OpenCart — точки самовывоза. Часть 1

Добрый день, уважаемый читатель!

На работе мне поставили задачу сделать точки самовывоза для OpenCart. Захотелось мне немного схалявить и найти готовый модуль. Но, к сожалению, поиск не увенчался успехом, что меня немного удивило — ведь модулей для OpenCart много, а в добавок еще и множество предпринимателей имеет не одну точку (магазин), а несколько. Но все, что я нашел — это был модуль «Расширенный самовывоз«, который мне не подошел.

Пришлось все-таки лезть в дебри кода и в конце концов я сделал это. И хочу поделиться с Вами…

PS: специально для тех, кому не хочется осиливать много букаф, я в конце выложу файлы для скачивания

Задача

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

Точки самовывоза в неактивном состоянии
Точки самовывоза в неактивном состоянии
Точки самовывоза в активном состоянии
Точки самовывоза в активном состоянии

При этом, список магазинов можно редактировать из админ-панели

Первое, что нам предстоит сделать — это клонировать модуль самовывоза в админке.

Итак, приступим.

1) Делаем копии файлов:

/admin/controller/shipping/pickup.php

/admin/language/russian/shipping/pickup.php

/admin/view/template/shipping/pickup.php

/catalog/model/shipping/pickup.php

/catalog/language/russian/shipping/pickup.php

Я назвал новые файлы pickup_point.php

2) Теперь нужно пройтись по всем файлам и изменить названия классов и имена некоторых переменных.

Заходим в файл /admin/controller/shipping/pickup_point.php и меняем имя класса с

ControllerShippingPickup

на

ControllerShippingPickupPoint

Модель с

ModelShippingPickup

на

ModelShippingPickupPoint

Вся модель данного способа доставки выглядит так:


<?php
class ModelShippingPickupPoint extends Model {
 function getQuote($address) {
 $this->load->language('shipping/pickup_point');

 $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "zone_to_geo_zone WHERE geo_zone_id = '" . (int)$this->config->get('pickup_point_geo_zone_id') . "' AND country_id = '" . (int)$address['country_id'] . "' AND (zone_id = '" . (int)$address['zone_id'] . "' OR zone_id = '0')");

 if (!$this->config->get('pickup_point_geo_zone_id')) {
 $status = true;
 } elseif ($query->num_rows) {
 $status = true;
 } else {
 $status = false;
 }

 $method_data = array();

 if ($status) {
 $quote_data = array();

 $quote_data['pickup_point'] = array(
 'code' => 'pickup_point.pickup_point',
 'title' => $this->language->get('text_description'),
 'cost' => $this->config->get('pickup_point_cost'),
 'tax_class_id' => 0,
 'text' => $this->currency->format(0.00)
 );

$method_data = array(
 'code' => 'pickup_point',
 'title' => $this->language->get('text_title'),
 'quote' => $quote_data,
 'sort_order' => $this->config->get('pickup_point_sort_order'),
 'error' => false
 );
 }

 return $method_data;
 }
}
?>

Языковой файл /catalog/language/russian/shipping/pickup_point.php:

<?php
// Text
$_['text_title'] = 'Самовывоз из ближайшего магазина';
$_['text_description'] = 'Самовывоз из магазина';
?>

Далее очень просто: через функцию текстового редактора «Найти и заменить» пишем в «Найти»: pickup, «Заменить»: pickup_point

Заходим в /admin/language/russian/shipping/pickup_point.php

нам понадобятся поля, которых нет в стандартном модуле «Самовывоз», поэтому нам нужно добавить несколько языковых переменных (я приведу весь код языкового файла):

// Heading
$_['heading_title'] = 'Точки самовывоза';

// Text
$_['text_shipping'] = 'Доставка';
$_['text_success'] = 'Настройки модуля обновлены!';

// Entry
$_['entry_geo_zone'] = 'Географическая зона:';
$_['entry_status'] = 'Статус:';
$_['entry_sort_order'] = 'Порядок сортировки:';
$_['entry_cost'] = 'Стоимость';
$_['entry_shop_number'] = 'Номер магазина';
$_['entry_shop_address'] = 'Название магазина';
$_['entry_status'] = 'Статус';

$_['button_add'] = 'Добавить';
$_['button_remove'] = 'Удалить';

// Error
$_['error_permission'] = 'У Вас нет прав для управления этим модулем!';

И соответственно добавляем эти переменные в контроллер (/admin/controller/shipping/pickup_point) — также отрезок кода, который отвечает за загрузку переменных из языкового файла в отображение:

$this->data['heading_title'] = $this->language->get('heading_title');
$this->data['text_enabled'] = $this->language->get('text_enabled');
$this->data['text_disabled'] = $this->language->get('text_disabled');
$this->data['text_all_zones'] = $this->language->get('text_all_zones');
$this->data['text_none'] = $this->language->get('text_none');

$this->data['entry_cost'] = $this->language->get('entry_cost');
$this->data['entry_shop_number'] = $this->language->get('entry_shop_number');
$this->data['entry_shop_address'] = $this->language->get('entry_shop_address');
$this->data['entry_geo_zone'] = $this->language->get('entry_geo_zone');
$this->data['entry_status'] = $this->language->get('entry_status');
$this->data['entry_sort_order'] = $this->language->get('entry_sort_order');

$this->data['button_save'] = $this->language->get('button_save');
$this->data['button_cancel'] = $this->language->get('button_cancel');
$this->data['button_add'] = $this->language->get('button_add');
$this->data['button_remove'] = $this->language->get('button_remove');

Ниже в коде, где-то под хлебными крошками, ищем

if (isset($this->request->post['pickup_point_geo_zone_id'])) {
    $this->data['pickup_point_geo_zone_id'] = $this->request->post['pickup_point_geo_zone_id'];
} else {
    $this->data['pickup_point_geo_zone_id'] = $this->config->get('pickup_point_geo_zone_id');
}

if (isset($this->request->post['pickup_point_status'])) {
    $this->data['pickup_point_status'] = $this->request->post['pickup_point_status'];
} else {
    $this->data['pickup_point_status'] = $this->config->get('pickup_point_status');
}

if (isset($this->request->post['pickup_point_sort_order'])) {
    $this->data['pickup_point_sort_order'] = $this->request->post['pickup_point_sort_order'];
} else {
    $this->data['pickup_point_sort_order'] = $this->config->get('pickup_point_sort_order');
}

и добавляем:


if (isset($this->request->post['pickup_point_cost'])) {

$this->data['pickup_point_cost'] = $this->request->post['pickup_point_cost'];

} else {
$this->data['pickup_point_cost'] = $this->config->get('pickup_point_cost');
 }

// информация о магазине (№ магазина, название магазина или его адрес, статус (вкл/выкл))


$this->data['shops'] = array();

if (isset($this->request->post['pickup_point_shops'])) {
    $this->data['shops'] = $this->request->post['pickup_point_shops'];
} elseif ($this->config->get('pickup_point_shops')) {
    $this->data['shops'] = $this->config->get('pickup_point_shops');
}

На этом подготовка программной части админ-панели почти заканчивается, остается только сделать отображение.

Открываем /admin/view/template/shipping/pickup_point.tpl

Тут я вас мучать не буду и просто дам файл для скачивания: pickup_point_view.zip

Заменяете все содержимое и в итоге, в админ-панели, должно появиться нечто похожее на

Точки самовывоза - админ-панель
Точки самовывоза — админ-панель

На этом мы сегодня закончим, ждите продолжения, но с учетом того, что ждать нужно не долго!

28 комментариев

  1. Очень полезное дополнение. Но у меня возникает ошибка. Не могли бы вы помочь?
    Когда доходит до выбора (шаг 4 )

    Notice: Error: Could not load model shipping/pickup_point! in /var/www/u7486161/data/www/мой домен/system/engine/loader.php on line 48

  2. Добрый день! поправил запись: нужно сделать еще копию в /catalog/model/shipping/pickup.php -> pickup_point и переименовать модель в ModelShippingPickupPoint.

    Спасибо за обращение!

    1. Добрый день! Проделала первую часть, в Доставке появляется название Точки самовывоза, нажимаю установить и открывается пустое окно. Работаю на OcStore 1.5.5.1.2.
      Если можно, скиньте пожалуйста сам модуль.

  3. Добавил копию в /catalog/model/shipping/pickup.php -> pickup_point.
    Теперь ошибки нет, и пункт появился, но, магазины не добавляются. В админке, все есть, и все добавляется. А при заказе, просто одно поле — Самовывоз из ближайшего магазина. И все, больше ничего нет. Выпадающего списка как на втором скрине не появилось.

  4. А вы бы не могли выложить все эти файлы:

    /admin/controller/shipping/pickup.php
    /admin/language/russian/shipping/pickup.php
    /admin/view/template/shipping/pickup.php
    /catalog/model/shipping/pickup.php
    /catalog/language/russian/shipping/pickup.php

    но уже с изменением. то я все делаю по инструкции, а в админке потом протос белый экран при выборе данного модуля

    1. Добрый день! Роман, а можете посмотреть в логах ошибок — там должно быть написано, почему только белый экран.
      Настройки — журнал ошибок. И пришлите, пожалуйста, ошибку через форму обратной связи и я скажу что нужно поправить

  5. Доброго времени суток! После первой части (перепроверял файлы несколько раз).
    Появляется ошибка в админке при установке.изменении модуля /controller/extension/shipping.php on line 127
    Прошу помощи

  6. Ошибка на самом деле появляется следующая:
    Notice: Error: Could not load template /home/virtwww/site/http/admin/view/template/shipping/pickup.tpl! in /home/virtwww/site/http/vqmod/vqcache/vq2-system_engine_controller.php on line 117

      1. У Вас просто так написано:

        Заходим в файл /admin/controller/shipping/pickup_point.php и меняем имя класса с

        ControllerShippingPickup
        на

        ControllerShippingPickupPoint
        Модель с

        ModelShippingPickup
        на

        ModelShippingPickupPoint

        Вот я и думал что это всё в одном файле.

  7. У меня при входе в модуль в админке:

    Parse error: syntax error, unexpected ‘$this’ (T_VARIABLE) in /var/www/xxxx/xxxxx.com/admin/controller/shipping/pickup_point.php on line 101

    а на главной:

    Warning: fopen(/var/www/xxxx/xxxxx.com/image/test): failed to open stream: Permission denied in /var/www/xxxx/xxxxx.com/admin/controller/common/home.php on line 334Warning: fwrite() expects parameter 1 to be resource, boolean given in /var/www/xxxx/xxxxx.com/admin/controller/common/home.php on line 336Warning: fclose() expects parameter 1 to be resource, boolean given in /var/www/xxxx/xxxxx.com/admin/controller/common/home.php on line 338

          1. да, я всё сделал что описано в 3-х частях. буду признателен если скинете. почта верная. Спасибо!

  8. Здравствуйте.
    Делаю все по вашему рецепту, все появляется в админке, но при попытке сохранить модуль возникает ошибка:

    Warning: Cannot modify header information — headers already sent by (output started at /var/www/xxxxxxxx.ru/admin/language/russian/shipping/pickup_point.php:1) in /var/www/xxxxxxx.ru/vqmod/vqcache/vq2-system_engine_controller.php on line 28Warning: Cannot modify header information — headers already sent by (output started at /var/www/xxxxxxxx.ru/admin/language/russian/shipping/pickup_point.php:1) in /var/www/xxxxxxx.ru/vqmod/vqcache/vq2-system_engine_controller.php on line 29

    Я так понимаю, тут говорится о том, что заголовки уже отправлены.
    М.б. это связано с версией OpenCart?
    У меня v.1.5.3.1

  9. Здравствуйте!
    Ошибка 2016-07-12 19:57:04 — PHP Notice: Undefined variable: shop_id in C:\inetpub\vhosts\u0152510.plsk.regruhosting.ru\httpdocs\masik-toys.ru\catalog\view\theme\OPC030062\template\checkout\simplecheckout_shipping.tpl on line 63

    В файле 63 строка
    <option value="»selected=»selected»>

Leave a Reply