Разработка плагина доставки

Содержание...

Плагины доставки предназначены для расчета стоимости доставки отправлений в реальном времени в процессе оформления заказа. Плагин получает на вход данные об отправлении (состав, общий вес, стоимость и другие параметры) и возвращает стоимость доставки, рассчитывая ее на основе собственного алгоритма: например, в виде процентной доли общей стоимости заказа или выполнив предварительный запрос на сервер службы доставки через API этого сервиса — конкретная реализация является индивидуальной для каждого плагина и полностью определяется его разработчиком.

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

В качестве примера посмотрите исходный код плагина доставки «Почта России» (GitHub-репозиторий).

Плагины доставки реализованы на уровне ядра фреймворка, а не конкретного приложения. Это позволяет использовать функциональность таких плагинов любому установленному приложению (например, Shop-Script).

Исходный код плагинов доставки находится в директории wa-plugins/shipping/. Каждый плагин представляет собой отдельную поддиректорию с реализацией класса, унаследованного от базового класса waShipping. Наименование поддиректории с файлами плагина является его уникальным идентификатором, который используется в формировании правильного имени класса плагина. Ниже приведен пример таких наименований для некоторого плагина с идентификатором myshipping:

wa-plugins/shipping/myshipping/lib/myshippingShipping.class.php

<?php
 
class myshippingShipping extends waShipping 
{ 
    ... 
}

Помимо основного класса, производного от waShipping, для работы плагина также требуются конфигурационные файлы, которые, как в приложениях и плагинах, размещаются в поддиректории lib/config/. Подробное описание конфигурационных файлов см. ниже.

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

Методы

В методах основного класса плагина для получения значений полей настроек плагина, описанных в конфигурационном файле lib/config/settings.php, используйте доступ к приватному полю вида $this->field_name. Вместо field_name указывайте идентификатор поля настроек, значение которого необходимо получить.

Методы, реализация которых обязательна для любого плагина доставки

calculate()

Основной метод плагина доставки, который возвращает стоимость и приблизительное время доставки. Этот метод не принимает входных параметров. Метод calculate() должен вернуть массив, содержащий варианты доставки отправления:

array(
    'variant_id_1' => array(
        'name' => '', //название варианта доставки, например, “Наземный  транспорт”, “Авиа”, “Express Mail” и т. д.
        'description' => '', //необязательное описание варианта  доставки
        'est_delivery' => '', //произвольная строка, содержащая  информацию о примерном времени доставки
        'currency' => $this->currency, //ISO3-код валюты, в которой рассчитана  стоимость  доставки
        'rate_min' => $this->cost, //минимальная граница стоимости, если стоимость рассчитана приблизительно
        'rate_max' => $this->cost, //максимальная граница стоимости, если стоимость рассчитана приблизительно
        'rate' => $this->cost, //точная стоимость доставки
    ),
    'variant_id_2' => array(
        ...
    ),
    ...
),

Если стоимость рассчитать не удалось, то вместо массива метод calculate() может вернуть сообщение об ошибке. Например:

return 'Доставка по указанному адресу  невозможна';

calculate() — это основной метод любого плагина доставки. Разработка подавляющего большинства плагинов может быть сведена к реализации только этого метода.

allowedCurrency()

Возвращает строку или массив со списком ISO3-кодов валют, для которых плагин может рассчитывать стоимость доставки.

allowedWeightUnit()

Возвращает строковый идентификатор или массив идентификаторов поддерживаемых плагином единиц измерения веса отправления.

Методы, реализация которых необязательна и зависит от логики конкретного плагина

tracking($tracking_id = null)

Этот метод должен вернуть строку (допускается использование HTML-тегов), в которой может содержаться информация о текущем статусе отправления. Например, ссылку на страницу трассировки отправления на сайте службы доставки. Или же информацию о статусе отправления, если API службы доставки позволяет его получить.

Параметр $tracking_id — необязательный идентификатор отправления, полученный от пользователя. Результат, возвращаемый методом, предназначен для отображения покупателю на странице просмотра заказа.

getPrintForms(waOrder $order = null)

Возвращает список поддерживаемых печатных форм в виде ассоциативного массива следующего вида:

array(
    key1 => array(
        'name'        => '...',
        'description' => '...',
    ),
    key2 => array(
        'name'        => '...',
        'description' => '...',
    ),
    ...
)

key — произвольный уникальный (в рамках данного плагина) идентификатор печатной формы;
name — наименование печатной формы;
description — описание печатной формы.

displayPrintForm($id, waOrder $order, $params = array())

Печать формы по указанному идентификатору (в качестве идентификатора используется ключ ассоциативного массива, возвращаемого методом getPrintForms()). Содержание и внешний вид каждой формы реализуются с помощью отдельного шаблона, хранящегося в поддиректории плагина templates/. Метод должен вернуть HTML-код сформированной печатной формы.

allowedAddress()

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

array(
    array(
        'country' => ...,
        'region'  => ...,
    )
)

В качестве значения каждого из элементов может быть либо строка (единичное значение), либо массив строк (список идентификаторов разрешенных стран либо регионов). Если ограничивать доставку по отдельным регионам не нужно, то элемент 'region' можно не указывать.

requestedAddressFields()

Возвращает список полей адреса доставки, которые должны запрашиваться у покупателя при выборе способа доставки (когда срабатывает код плагина доставки). Метод дожен вернуть либо false (не запрашивать поля адреса доставки), либо array() (запрашивать все поля адреса), либо массив со структурой, пример которой показан ниже:

return array(
     'field_id_1' => ...,
     'field_id_2' => ...,
     ...
 );

Вместо ключей массива вида field_id_* нужно указать идентификаторы полей адреса: 'country', 'region', 'city', 'zip', 'street' или любого другого пользовательского поля (если есть). Для элементов массива допустимы следующие значения:

Конфигурационные файлы

plugin.php

Файл plugin.php является главным конфигурационным файлом плагина доставки и предназначен для хранения базовой информации о плагине: названия, описания, версии и т. д. Формат файла:

<?php
    
return array(
    'name'        => ...,
    'description' => ...,
    'icon'        => ...,
    'logo'        => ...,
    'vendor'      => ...,
    'version'     => ...,
    'external'     => true, //необязательный параметр
);

Описания полей

settings.php

Файл settings.php используется для автоматического формирования интерфейса настроек плагина доставки в бекенде приложения, которое использует такой плагин. См. подробное описание файла настроек плагина.

requirements.php

Файл requirements.php используется для указания дополнительных системных требований, специфичных для работы конкретного плагина (например, наличие дополнительных расширений или отдельных параметров конфигурации PHP, установленных приложений Webasyst). См. подробное описание правил оформления системных требований продукта.

Отображение дополнительных элементов управления во фронтенде

Плагин доставки может предлагать пользователю фронтенда дополнительные элементы управления, в том числе нестандартные. Для этого в классе плагина необходимо реализовать публичный метод customFields(). Этот метод должен вернуть массив элементов управления в виде подмассивов, содержащих параметры нужных элементов. Пример реализации этого метода:

public function customFields()
{
    return array(
        'field1' => array(
            'value'        => $default_field_value, //значение по умолчанию, если необходимо
            'title'        => _wp('First field name'),
            'control_type' => waHtmlControl::INPUT,
        ),
        'field2' => array(
            'value'        => $default_field_value, //значение по умолчанию, если необходимо
            'title'        => _wp('Second field name'),
            'control_type' => 'MyShippingPluginControl', //идентификатор пользовательского элемента управления
        ),
        //...
    );
}

В качестве значения параметра 'control_type' можно указать строковый идентификатор пользовательского элемента управления (который может представлять из себя любой фрагмент HTML- и JavaScript-кода).

Для реализации пользовательского элемента управления необходимо следующее:

  1. Добавьте в класс плагина публичный метод, возвращающий строку HTML-кода пользовательского элемента.
  2. В начале метода customFields() выполните вызов следующего вида:

    $this->registerControl('MyShippingPluginControl', array($this, 'myShippingPluginControl'));

    В этом примере 'MyShippingPluginControl' в качестве первого аргумента метода registerControl() является идентификатором пользовательского элемента управления, а 'myShippingPluginControl' — именем метода, в котором реализован этот элемент управления.

Идентификатор пользовательского элемента управления и метод для его реализации могут именованы произвольно.

Запрос желаемой даты и времени доставки

Для выбора запрашиваемых у клиента элементов времени/даты и настройки доступных интервалов времени доставки в конфигурационном файле настроек settings.php нужно использовать элемент управления с ключом desired_delivery и идентификатором элемента настроек DeliveryIntervalControl:

'desired_delivery' => array(
    'title'        => 'Preferred delivery time',
    'control_type' => 'DeliveryIntervalControl',
    'minutes'      => true,
),

Параметр 'minutes' обозначает необходимость указывать минуты в настройках интервалов времени доставки.

Для отображения полей выбора даты (с календарем) и времени (в виде выпадающего списка интервалов, добавленных в настройках способа доставки) в классе плагина нужно реализовать публичный метод customFields() по примеру, при необходимости адаптировав его под логику работы плагина:

public function customFields(waOrder $order)
{
    $fields = parent::customFields($order);

    $this->registerControl('CustomDeliveryIntervalControl');
    $setting = $this->getSettings('customer_interval');

    if (!empty($setting['interval']) || !empty($setting['date'])) {
        if (!strlen($this->delivery_time)) {
            $from = time();
        } else {
            $from = strtotime(preg_replace('@,.+$@', '', $this->delivery_time));
        }
        $offset = max(0, ceil(($from - time()) / (24 * 3600)));
        $fields['desired_delivery'] = array(
            'value'        => null,
            'title'        => $this->_w('Preferred delivery time'),
            'control_type' => 'CustomDeliveryIntervalControl',
            'params'       => array(
                'date'      => empty($setting['date']) ? null : ifempty($offset, 0),
                'interval'  => ifset($setting['interval']),
                'intervals' => ifset($setting['intervals']),
            ),
        );
    }
    return $fields;
}
Возможность запрашивать у клиента желаемую дату и время доставки должна поддерживаться приложением, с которым используется плагин. В случае с Shop-Script версия приложения должна быть не ниже 7.2.4.114.

Статус отправления

Плагин доставки оперирует отправлениями. Отправление — это экземпляр класса waOrder. Оно может находиться в одном из нескольких статусов, которые обозначаются константами класса waShipping:

Для изменения или получения статуса отправления используйте следующие методы класса waShipping.

setPackageState (waOrder $order, $state, $params = array())

Переводит отправление в указанный статус и возвращает результат в одном из следующих форматов:

getStateFields ($state, waOrder $order = null, $params = array())

Возвращает массив полей веб-формы, которые должен заполнить пользователь при переводе отправления в указанный статус $state.

Значения заполненных полей копируются в аргумент $params['shipping_data'] при вызове метода setPackageState().

getAdapter()->getAppProperties ($property_name = null)

Позволяет выяснить, насколько подробно приложение поддерживает возможности плагинов доставки.

Возвращает значения из параметра 'shipping_plugins', указанного в конфигурационном файле приложения app.php. Это может быть только булево значение либо ассоциативный массив обозначений возможностей, которые поддерживает приложение:

Советы

Базовый системный класс плагинов доставки waShipping предоставляет несколько полезных методов, которые можно использовать в основном классе плагина.

Полезные методы

getAddress ($field = null)

Возвращает либо полный массив информации об адресе получателя, либо только значение указанного поля адреса, например, 'country', 'region', 'city', 'zip', 'street' или любого другого пользовательского поля (если есть).

getItems()

Возвращает массив с информацией о заказанных товарах.

getTotalPrice()

Возвращает общую стоимость отправления.

getTotalWeight()

Возвращает общий вес отправления.