if (!CModule::IncludeModule('o2k.betapro')) {
die('Модуль не установлен!');
}
$stack = new O2k\Betapro\Services\Stack();
$manager = new O2k\Betapro\Manager();
$result = $stack->getStackList();
echo '
В очереди на отправку: ' . count($result) . ' заказ(ов)
';
echo ''; print_r($result); echo '
';
echo "Обработка очереди завершена
";
………………………………………………………………………………………………………………………………………………………………………………………………………………………………………..
////////////////////////////////////////////////////////////////////////////////////////
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php');
define('NOT_CHECK_PERMISSIONS', true);
define('NO_AGENT_CHECK', true);
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');
if (!\Bitrix\Main\Loader::includeModule('o2k.betapro')) {
die('Модуль o2k.betapro не установлен');
}
use Bitrix\Main\Loader;
use O2k\Betapro\Manager;
use O2k\Betapro\Services\Stack;
use Bitrix\Sale;
Loader::includeModule('o2k.betapro');
// -- инициализация ------------------------------------------------------------
$stack = new Stack();
$manager = new O2k\Betapro\Manager(); // пригодится, если захотите тестово вызывать sendAddedOrder()
$stackList = $stack->getStackList(); // вернёт массив, где ключ – ID записи, значения см. в доке :contentReference[oaicite:0]{index=0}:contentReference[oaicite:1]{index=1}
echo 'В очереди найдено: '.count($stackList).' записей
';
echo '';
echo '
# Stack |
ORDER_ID (во внутренней таблице модуля) |
BX_ORDER_ID (ID заказа в Sale) |
BX_ACCOUNT_NUMBER |
STATUS |
Проблема |
';
$problemCount = 0;
foreach ($stackList as $stackId => $row) {
$problem = [];
// 1. BX_ORDER_ID отсутствует или null
if (empty($row['BX_ORDER_ID'])) {
$problem[] = 'BX_ORDER_ID пуст';
}
// 2. BX_ORDER_ID не число
if (!empty($row['BX_ORDER_ID']) && !ctype_digit((string)$row['BX_ORDER_ID'])) {
$problem[] = 'BX_ORDER_ID не число';
}
// 3. заказ физически не существует в sale
if (!empty($row['BX_ORDER_ID']) && Sale\Order::load($row['BX_ORDER_ID']) === null) {
$problem[] = 'Заказ с таким ID не найден в sale';
}
// 4. отсутствие ACCOUNT_NUMBER (тоже вызывает падение cancelSendedOrder / checkSendedOrder)
if (empty($row['BX_ACCOUNT_NUMBER'])) {
$problem[] = 'BX_ACCOUNT_NUMBER пуст';
}
// 5. можно проверить, что STATUS=ADDED и одновременно BX_ORDER_ID пуст
if ($row['STATUS'] == Stack::STATUS_ADDED && empty($row['BX_ORDER_ID'])) {
$problem[] = 'STATUS_ADDED, но BX_ORDER_ID пуст — 100% падает в sendAddedOrder()';
}
// вывод строки
echo '';
echo ''.$stackId.' | ';
echo ''.$row['ORDER_ID'].' | ';
echo ''.($row['BX_ORDER_ID'] ?: 'NULL').' | ';
echo ''.($row['BX_ACCOUNT_NUMBER'] ?: 'NULL').' | ';
echo ''.$row['STATUS'].' | ';
echo ''.($problem ? implode('; ', $problem) : ' ').' | ';
echo '
';
if ($problem) {
$problemCount++;
}
}
echo '
';
echo 'Найдено проблемных записей: '.$problemCount.'
';
if ($problemCount && isset($_GET['debug'])) {
echo '
';
echo "Ниже пример, как можно вручную вызвать sendAddedOrder() в try/catch\n\n";
foreach ($stackList as $id => $row) {
if ($row['STATUS'] == Stack::STATUS_ADDED) {
try {
$manager->sendAddedOrder((int)$row['BX_ORDER_ID']); // может упасть
echo "OK: stack #$id, order ".$row['BX_ORDER_ID']."\n";
} catch (Throwable $e) {
echo "FAIL: stack #$id, order ".$row['BX_ORDER_ID']." — ".$e->getMessage()."\n";
}
}
}
echo '
';
}
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/footer.php');
?>
……………………………….////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////
['ID','ORDER_ID','STATUS'],
'filter' => ['SEND'=>'N', 'STATUS'=>Stack::STATUS_ADDED],
'order' => ['ID'=>'DESC'],
'limit' => 15,
])->fetchAll();
/** шаг 2. отмечаем, что мы хотим их обработать (ничего не меняем – просто вывод) */
echo "Готовим к отправке ".count($rows)." записей\n";
foreach ($rows as $r){
echo "#{$r['ID']} (ORDER_ID={$r['ORDER_ID']})\n";
}
echo "
";
/** шаг 3. пускаем штатный механизм менеджера */
$manager = new Manager();
$manager->checkQueue(); // здесь вызовется protected sendAddedOrder()
echo "
Готово, обновите страницу для проверки.";
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Удаление всех товаров из очереди
truncateTable(StackRequestTable::getTableName());
/**
* 2. (опционально) сбрасываем признак «уже добавлен в очередь»,
* чтобы нужные заказы могли попасть в неё повторно на следующем запуске exchange.
*
* Закомментируй, если нужно просто опустошить очередь «навсегда».
*/
//$conn->query("UPDATE o2k_betapro_order SET ADDED_TO_STACK = 'N' WHERE ADDED_TO_STACK = 'Y'");
echo "✓ Очередь Betapro очищена\n";
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
итоговый код
define('NOT_CHECK_PERMISSIONS', true);
define('NO_AGENT_CHECK', true);
$_SERVER['DOCUMENT_ROOT'] = '/var/www/jogdog/jogdog.ru';
require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
use Bitrix\Main\Application;
use Bitrix\Main\Type\DateTime;
use Bitrix\Main\Loader;
use Bitrix\Sale\Order;
use O2k\Betapro\Orm\OrderTable;
use O2k\Betapro\Orm\StackRequestTable;
use O2k\Betapro\Services\Stack;
use O2k\Betapro\Manager;
/* ---------------- Настройки ---------------- */
class Config
{
public static function getQueueLookbackDays(): int
{
return 3;
}
public static function getSendDelayMinutes(): int
{
return 5;
}
public static function getTestNameMask(): string
{
return 'test';
}
}
if (!Loader::includeModule('o2k.betapro')) {
echo 'Модуль o2k.betapro не установлен';
exit(1);
}
/* --------------- Инициализация ------------- */
$stack = new Stack();
$manager = new Manager();
$conn = Application::getConnection();
$now = new DateTime();
$delaySec = Config::getSendDelayMinutes() * 60;
/* 1. Добавляем свежие заказы в очередь */
$fromDate = (clone $now)->add('-' . Config::getQueueLookbackDays() . ' days');
$rsOrders = OrderTable::getList([
'select' => [
'ID',
'ORDER_ID',
'DATE_INSERT' => 'BX_ORDER.DATE_INSERT',
],
'runtime' => [
'BX_ORDER' => [
'data_type' => Order::class,
'reference' => ['=this.ORDER_ID' => 'ref.ID'],
'join_type' => 'LEFT',
],
],
'filter' => [
'>=BX_ORDER.DATE_INSERT' => $fromDate,
'ADDED_TO_STACK' => 'N',
'BX_ORDER.CANCELED' => 'N',
],
'order' => ['ID' => 'ASC'],
]);
while ($order = $rsOrders->fetch()) {
$internalId = (int)$order['ID'];
$bxOrderId = (int)$order['ORDER_ID'];
// --- Фильтрация тестовых заказов по свойству NAME ---
$saleOrder = Order::load($bxOrderId);
if ($saleOrder) {
$props = $saleOrder->getPropertyCollection();
$nameProp = $props->getItemByOrderPropertyCode('NAME');
$custName = $nameProp
? mb_strtolower($nameProp->getValue())
: '';
if (mb_stripos($custName, mb_strtolower(Config::getTestNameMask())) !== false) {
// если в имени встречается «test» — пропускаем
continue;
}
}
/* чистим старые хвосты */
$rs = StackRequestTable::getList([
'select' => ['ID'],
'filter' => ['=ORDER_ID' => $internalId],
]);
while ($row = $rs->fetch()) {
StackRequestTable::delete($row['ID']);
}
/* добавляем в очередь */
$stack->addToStack($internalId, Stack::STATUS_ADDED, 'N');
/* и помечаем в o2k_betapro_order */
$stack->markSendedOrder($bxOrderId);
echo "Добавлен: внутренний={$internalId}, BX={$bxOrderId}\n";
}
/* 2. Собираем, что реально уйдёт */
$stackList = $stack->getStackList();
$willSend = [];
foreach ($stackList as $stackId => $row) {
if ($row['STATUS'] != Stack::STATUS_ADDED) {
continue;
}
$order = Order::load($row['BX_ORDER_ID']);
$created = $order ? $order->getDateInsert() : null;
if ($created instanceof DateTime &&
$now->getTimestamp() - $created->getTimestamp() < $delaySec) {
continue; // ещё рано
}
$willSend[$stackId] = $row;
}
if (php_sapi_name() !== 'cli') {
echo 'Будут отправлены в BetaPro: ' . count($willSend) . '
';
if ($willSend) {
echo '
#Stack | ORDER_ID | BX_ORDER_ID |
ACCOUNT_NUMBER | Дата создания |
';
foreach ($willSend as $sid => $row) {
$order = Order::load($row['BX_ORDER_ID']);
$date = $order ? $order->getDateInsert()->toString() : '—';
echo '' . htmlspecialchars($sid) . ' |
' . htmlspecialchars($row['ORDER_ID']) . ' |
' . htmlspecialchars($row['BX_ORDER_ID']) . ' |
' . htmlspecialchars($row['BX_ACCOUNT_NUMBER']) . ' |
' . htmlspecialchars($date) . ' |
';
}
echo '
';
}
}
/* 3. Отправляем и удаляем */
foreach ($willSend as $stackId => $row) {
$bxId = (int)$row['BX_ORDER_ID'];
try {
if ($manager->sendAddedOrder($bxId)) {
StackRequestTable::delete($stackId);
echo "Отправлен и удалён: stack={$stackId}, BX={$bxId}\n";
} else {
echo "sendAddedOrder вернул false: stack={$stackId}\n";
}
} catch (\Throwable $e) {
echo "Ошибка: stack={$stackId} — " . $e->getMessage() . "\n";
}
}
echo "=== DONE ===\n";
require $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php';
?>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
query("
DELETE FROM ". StackRequestTable::getTableName() ."
WHERE SEND = 'Y'
");
// =======================================================================
// 1) Добавляем свежие заказы в очередь (как обычно)
// =======================================================================
$stack = new Stack();
$now = new DateTime();
// Берём заказы за последние 3 дня и которые ещё не добавлялись
$fromDate = (clone $now)->add('-3 days');
$rsNew = OrderTable::getList([
'select' => ['ID','ORDER_ID'],
'runtime' => [
'BX_ORDER' => [
'data_type' => Order::class,
'reference' => ['=this.ORDER_ID'=>'ref.ID'],
'join_type' => 'LEFT',
],
],
'filter' => [
'>=BX_ORDER.DATE_INSERT' => $fromDate,
'ADDED_TO_STACK' => 'N',
'BX_ORDER.CANCELED' => 'N',
],
'order' => ['ID'=>'ASC'],
]);
echo "Добавляем в очередь новых заказов:\n";
while ($row = $rsNew->fetch()) {
$intId = (int)$row['ID'];
$bxId = (int)$row['ORDER_ID'];
// на всякий случай удаляем старые хвосты очереди
$rsOld = StackRequestTable::getList([
'select'=>['ID'],
'filter'=>['=ORDER_ID'=>$intId],
]);
while ($old = $rsOld->fetch()) {
StackRequestTable::delete($old['ID']);
}
$stack->addToStack($intId, Stack::STATUS_ADDED, 'N');
$stack->markSendedOrder($bxId);
echo " → internal={$intId}, bx={$bxId}\n";
}
// =======================================================================
// 2) Запускаем штатный менеджер, который отправит всё, что осталось
// в o2k_betapro_stack_request (STATUS_ADDED & SEND=N) и удалит записи
// =======================================================================
echo "\nЗапускаем отправку — Manager::checkQueue()\n";
$manager = new Manager();
$manager->checkQueue();
// ==== новый блок очистки очереди ====
echo "\nУдаляем все остатки из o2k_betapro_stack_request…\n";
$conn = Application::getConnection();
$conn->query("
DELETE FROM ". StackRequestTable::getTableName() ."
WHERE SEND = 'Y' OR STATUS != ".Stack::STATUS_ADDED."
");
echo "Готово — очередь пуста.\n";
echo "=== DONE ===\n";
require $_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/main/include/epilog_after.php';