понеділок, 26 грудня 2016 р.

Обновляем цены в интернет-магазине на Okay-CMS



Встроенный функционал Okay-CMS позволяет импортировать товары из файла, но совсем не заточен под простое обновление цен. Бывают ситуации, когда из прайс-листа нужно обновить только те цены, которые уже есть на сайте и пропустить все остальные. Стандартный же функционал заставляет нас заполнять поле с названием товара, и постарается его создать, если не найдет такой в базе данных по артикулу или названию товара.

Кроме того, меня лично не устраивает что на обновление каждого товара система делает как минимум 2 запроса - SELECT его из базы, а потом UPDATE. Все шаред-хостинги, которые я видел (да-да, меня жаба давит на VPS а шареда вполне хватает) имели ограничение на количество запросов к бд что-то в пределах 3-4 тыс. операций в час. То есть в час мы можем обновить максимум 2000 товаров.

Попробуем решить все эти проблемы сразу, создав отдельный модуль обновления цен товаров.

Сразу замечу, что функционал я делал "под себя", поэтому опустил например проверку доступа менеджера к модулю импорта цен, а так же забил на проверку валюты (у меня все цены на сайте в одной валюте). Все это можно сделать и довольно просто, но такая задача не стояла.
Создадим шаблон страницы импорта цен. За основу я взял шаблон
/backend/design/html/import.tpl
и немного поправил. Скачать его можно по ссылке import_cost.tpl

Чтобы к новому модулю был доступ с любой страницы раздела "Импорт/Экспорт", добавим строчку в файлы import.tpl и export.tpl:
{* /backend/design/html/import.tpl *}
{capture name=tabs}
  <li class="active"><a href="index.php?module=ImportAdmin">Импорт</a></li>
  {if in_array('export', $manager->permissions)}<li><a href="index.php?module=ExportAdmin">Экспорт</a></li>{/if}
  {* вставляем вот эту строчку: *}
  <li><a href="index.php?module=UpdateAdmin">Обновление цен</a></li>
{/capture}

{* /backend/design/html/export.tpl *}
{capture name=tabs}
  {if in_array('import', $manager->permissions)}<li><a href="index.php?module=ImportAdmin">Импорт</a></li>{/if}
  <li class="active"><a href="index.php?module=ExportAdmin">Экспорт</a></li>
  {* вставляем вот эту строчку: *}
  <li><a href="index.php?module=UpdateAdmin">Обновление цен</a></li>
{/capture}
Контроллер этого модуля, который показывает страницу загрузки файла и позволяет загрузить сам файл для импорта, качаем по ссылке UpdateAdmin.php и поместим в папку под именем
/backend/UpdateAdmin.php
Теперь вновь созданный модуль нужно прописать в админке в файле IndexAdmin.php:
/* /backend/IndexAdmin.php */
private $left_menu = array(
  ...
  'UpdateAdmin' => 'auto',
  ...
);
private $modules_permissions = array(
  ...
  'UpdateAdmin' => 'update',
  ...
);
А так же добавить его в список прав доступа:
/* /api/Managers.php */
public $permissions_list = array(
  ...
  'update',
  ...   
);
И последнее, нужно создать сам ajax-контроллер, который будет парсить прайс и обновлять цены.
В двух словах, что конкретно он делает:
  • Перебирает импортированный файл порциями по 500 строк, запоминает артикулы.
  • Ищет в базе данных варианты товаров, совпадающие по артикулам с найденными в файле
    SELECT sku, name, product_id, price FROM s_variants WHERE sku IN (список_артикулов)
  • Обновляет одним запросом все найденные в этой порции артикулы
    UPDATE s_variants SET price = CASE WHEN sku=артикул_1 THEN цена_1 ... ELSE price END WHERE sku IN (список_артикулов)
    Следовательно, для обновления 50 000 цен будет всего лишь 200 запросов. Но можно увеличить порцию и до 1000 артикулов за раз, и даже больше. Требования к памяти у этого скрипта минимальные.
Скачать контроллер по ссылке: update.php и положить его в папку под именем:
/backend/ajax/update.php
Теперь на странице "Импорт/Экспорт" появилась новая закладка, открываем её, загружаем заранее подготовленный файл с двумя столбцами: ["Артикул", "Цена"] и ждём результата.
Я еще для красоты немного подковырял стили CSS но не буду раздувать статью по мелочам.

Немає коментарів :

Дописати коментар