Магазин на OpenCart редко ломается за один день. Сначала покупается тема, потом модуль доставки, потом фид для маркетплейса, дальше кто-то дописывает правку в корзину. Через несколько лет владелец уже не может сказать, что в его движке штатное, а что прикручено сверху. При обновлении OpenCart или модуля такие доработки приходится проверять и часто переписывать.
Эта статья для тех, кто уже на OpenCart или выбирает его. Здесь нет обзора того, что видно снаружи в 43 магазинах на трех платформах, — он есть отдельно в статье «Prom, Хорошоп или OpenCart». Здесь — проверка самого ядра: четыре места, где каталог чаще всего упирается в архитектуру, и как каждое из них проверить в своем магазине без разработчика.
Что OpenCart дает из коробки, и чего не нужно искать в модулях
Начнем с того, что часто покупают зря. Оптовые цены в простом виде в ядре уже есть: на вкладке Discount в карточке товара задается цена для группы клиентов, минимальное количество, приоритет и даты действия. В базе это отдельная таблица oc_product_discount с полями группы, количества, приоритета, цены и дат. Если ваш опт — это «дилер от 10 штук платит меньше», модуль для этого не нужен.
Точно так же штатно в карточке есть поля Model и SKU, количество на складе и переключатель Subtract Stock, то есть списывать ли остаток при заказе. У значений опций товара есть собственное количество и своя надбавка к цене.
Теперь о том, где штатного уже не хватает.
Когда шаблона и модулей OpenCart уже мало: четыре проверки
Дальше — четыре признака, каждый можно проверить в своей админке.
Несколько складов, а количество одно
Возьмите позицию, которая лежит в двух местах, и попробуйте из админки сказать, сколько ее на каждом. Поле Quantity в карточке одно, и это не ограничение интерфейса: и в ветке 3.0, и в 4.1 количество хранится одним целым числом в таблице товара, рядом с одной ценой. Таблицы складов в штатной схеме нет.
Если разбивка живет в таблице менеджера, вы уже на границе: все, что читает штатное поле количества, видит одно число. Почему одна цена ломается со вторым складом и разной закупкой, мы разобрали в статье «Несколько складов — одна цена товара не работает».
Опт, которому мало группы и количества
Штатная скидка знает две вещи: группу клиента и количество. Граница проходит там, где цена начинает зависеть от чего-то третьего. Чаще всего это склад, с которого отгружают, или персональная договоренность с конкретным покупателем на конкретную позицию. Еще одно типичное требование — минимальная сумма заказа для опта.
Попросите менеджера записать, как он на самом деле считает цену для самого сложного постоянного клиента. Уместилось в строку «группа плюс количество» — ядро справится. Появилось «но с этого склада» или «а этому клиенту на этот бренд отдельно» — такую логику приходится дописывать патчами в расчет цены, и они могут конфликтовать с другими модулями, которые правят то же место.
Остаток изменился, и никто не знает почему
Вчера в карточке было 12, сегодня 9. Кто и когда изменил число? В штатной схеме 3.0 есть таблицы истории для заказов, клиентов, купонов, сертификатов и возвратов. Таблицы движений остатка нет. Количество в карточке просто перезаписывается — заказом, импортом или рукой менеджера, и предыдущее значение нигде не остается.
Если без логов сервера и расспросов ответа не найти, складского учета у вас нет — есть только текущая цифра.
Для ветки 3.0 есть еще одна проверка. Откройте базу в phpMyAdmin и посмотрите колонку Engine в списке таблиц. Штатный установщик 3.0.5.1 создает 132 таблицы из 134 на MyISAM, а этот движок, по документации MySQL, транзакций не поддерживает. То есть несколько связанных записей одного заказа нельзя ни выполнить вместе, ни вместе откатить, если посередине что-то пошло не так. В ветке 4.1 установщик уже ставит InnoDB. Перевод таблиц на InnoDB обычно можно сделать без смены платформы, но его стоит проверить на копии базы; журнала движений он не добавит.
Поиск не находит артикул
Для магазинов запчастей, инструмента и любого опта это самый дорогой признак, потому что покупатель приходит с артикулом в буфере обмена.
Вот как ищет штатный OpenCart (мы читали код модели каталога в ветках 3.0 и 4.1). Название разбивается на слова, и каждое слово ищется вхождением. Модель и в 3.0, и в 4.1 сравнивается с запросом целиком, без учета регистра. SKU, EAN и другие коды в 3.0 тоже сравниваются целиком, а в 4.1 — по началу строки.
Так что если артикула AB-1234 нет в названии товара, запросы AB 1234, ab1234 или 1234 в поиске витрины в основном вернут пустую страницу — попробуйте на своем каталоге, это две минуты. Покупатель не знает, как именно у вас записан код, и уходит туда, где нашлось.
Что лечится, не меняя OpenCart
Типичные дыры, которые мы находили в замере рынка, лежат не в ядре. Медленный ответ сервера, устаревшая версия PHP, карта сайта с дублями, отсутствующий canonical — все это исправляется на том же движке, подробно — в замере технической базы рынка.
Оптовые уровни в рамках «группа плюс количество» закрываются вкладкой Discount. Таблицы переводятся на InnoDB. Новый шаблон меняет вид витрины. Если ваши боли здесь, менять платформу не нужно, и мы скажем это первым письмом. Поиск по артикулу — пограничный случай: его переделывают и на OpenCart, но это уже доработка ядра поиска, а не настройка.
Что не лечится патчами
Граница — не один признак, а их совпадение. Когда от склада зависит цена, а заказы приходится разбивать между складами и вести журнал движений остатка, это уже модель данных, и функцией ее не добавишь. Ее приходится встраивать в ядро чужого движка, и при обновлении OpenCart или модуля ее приходится проверять и часто переписывать.
Под этот случай мы делаем Stable Shop — собственный движок LIONEX на Laravel. В ядре там один артикул лежит на нескольких складах, и у каждого своя цена, остаток и срок доставки, а заказ разбивается автоматически. Группы клиентов имеют несколько уровней опта, персональные цены на позицию и минимальные суммы заказа. Каждое движение остатка записывается отдельной строкой с автором и временем, операции идут в транзакциях с блокировкой строки. Поиск работает на Meilisearch с лемматизацией украинского, и артикул находится с пробелами, дефисами и точками. Код и данные остаются на вашем сервере.
Чего там еще нет, говорим так же прямо: импорта из OpenCart пока нет, резервирования товара с таймером в корзине нет, Rozetka Delivery и Meest пока заглушки, а магазин расширений для сторонних разработчиков еще в разработке. Продукт сейчас на этапе подготовки запуска. Подробнее — на карточке Stable Shop и странице магазина на собственной платформе.
Когда OpenCart остается правильным выбором
Когда задача типовая: под нее уже есть готовый модуль, и его дешевле поставить, чем написать. Если склад один, а цены умещаются в группу и количество, опенкарт делает свою работу, и переписывание движка стоило бы больше, чем даст. Мы преимущественно работаем с OpenCart и разработку на нем продолжаем делать.
Если после четырех проверок у вас совпали два-три признака, пришлите адрес магазина и описание того, как считаются цены и остатки. Бесплатный разбор каталога покажет, что можно вылечить на текущем движке, а что упирается в ядро. Отвечаем в течение двух часов, а сумма, если дойдет до работы, фиксируется в договоре после разбора.