Статус заказа "T"

Где возникла проблема: 4.19.1.SP1 ULTIMATE RU

Суть проблемы:
При построении отчёта по товарам (использующего таблицы cscart_order_details и cscart_orders) при фильтрации по статусу заказа с кодом T формируется логически противоречивое условие в секции WHERE SQL-запроса:

AND a.status IN ('T')
AND a.status != 'T'

В результате:

  • заказы со статусом T физически есть в базе (cscart_orders.status = 'T');
  • статус T можно назначать заказам, и он корректно отображается в списке заказов;
  • отчёт всегда возвращает пустой результат по статусу T, так как условие IN ('T') и != 'T' одновременно не может быть истинным ни для одной строки.

При этом в интерфейсе настроек отчёта/модуля нет явных ограничений или исключений для статуса T — он не отмечен как “исключаемый”, но в запрос всё равно попадает a.status != 'T'.


Как воспроизвести проблему:

  1. Чистая установка CS-Cart 4.19.1.SP1 ULTIMATE RU, без сторонних модулей и тем.
  2. В админке создать новый статус заказа:
    • Тип: O (заказ);
    • Код: T (латинская буква T, CHAR(1));
    • Название: любое, например «Выполнен Бери-5».
  3. Создать тестовый заказ и перевести его в статус T. Убедиться, что:
    • в таблице cscart_orders есть запись с status = 'T' и нужным order_id;
    • в списке заказов в админке этот заказ отображается со статусом T и заданным названием.
  4. Включить режим отладки (DEBUG_MODE) в config.local.php, очистить кэш.
  5. Открыть стандартный отчёт по продажам по товарам, использующий cscart_order_details и cscart_orders (например, Администрирование → Отчёты → Отчёты по продажам, тип отчёта «Товары»).
  6. В настройках отчёта/фильтра:
    • выбрать период, в который попадает тестовый заказ;
    • в списке включаемых статусов указать только статус с кодом T;
    • при этом не указывать T ни в каких списках “исключаемых” статусов.
  7. Построить отчёт.

Фактический результат:
Отчёт не выводит ни одной строки по статусу T, хотя в базе есть заказы с этим статусом.

Если открыть панель отладки и посмотреть SQL-запрос, то он выглядит примерно так (фрагмент):

SELECT b.product_id,
       SUM(b.price * b.amount) AS product_amount,
       c.product
FROM cscart_order_details AS b
LEFT JOIN cscart_orders AS a ON b.order_id = a.order_id
LEFT JOIN cscart_product_descriptions AS c
       ON b.product_id = c.product_id
      AND c.lang_code = 'ru'
WHERE a.timestamp >= 1735678800
  AND a.timestamp <= 1767214799
  AND a.status IN ('T')
  AND a.status != 'T'
  AND a.is_parent_order != 'Y'
GROUP BY b.product_id
ORDER BY product_amount DESC, product_id
LIMIT 5, 1;

Критичный фрагмент:

AND a.status IN ('T')
AND a.status != 'T'

Он делает выборку по статусу T логически невозможной.


Ожидаемое поведение:
При выборе статуса T (и любых других кастомных статусов) в настройках отчёта в запрос должно попадать только положительное условие по выбранным статусам, например:

AND a.status IN ('T')

или

AND a.status IN ('T', 'P', 'C')

Условие a.status != 'T' не должно добавляться одновременно с a.status IN ('T'), если статус T явно не указан в списке исключаемых статусов в интерфейсе.


Дополнительная информация (окружение):

  • CS-Cart 4.19.1.SP1 ULTIMATE RU
  • Браузер: Chrome на Windows 10 x64
  • PHP: 8.1

При необходимости могу предоставить:

  • выборку строк из cscart_statuses и cscart_orders с примером заказа со статусом T;
  • полный SQL-лог или скрин панели отладки с приведённым выше запросом.