Инструкция по настройке уведомлений через Event Bus

Для того чтобы система уведомлений автоматически реагировала на события, необходимо связать модуль событий (erp208_events) с модулем уведомлений (erp217_notification_center). Эта инструкция предоставляет пошаговое руководство по конфигурации и отладке системы уведомлений.

1. Где вносить правки

Основная логика связки находится в файле:

/home/c/cs11853/test.promerp.ru/application/modules/erp208_events/classes/Service/Erp208/EventBus.php

Вам нужно модифицировать метод _proxy_to_notification_center.

2. Что конкретно написать

Найдите метод _proxy_to_notification_center и приведите его к следующему виду:

/**
 * Прокси-метод для автоматической отправки в Notification Center
 */
protected function _proxy_to_notification_center($payload, $event_name, $initiator_id)
{
    // 1. Определяем получателя.
    // Если в payload передан target_user_id, используем его, иначе инициатора.
    $user_id = isset($payload['target_user_id']) ? $payload['target_user_id'] : $initiator_id;

    if ($user_id) {
        // 2. Вызываем шину уведомлений для обработки события
        Service_Erp217_Bus::instance()->send($event_name, $user_id, $payload);
    }
}

3. Как это работает (алгоритм)

  1. Публикация события: Когда в коде вызывается Service_Erp208_EventBus::instance()->publish('order_created', $data, $user_id), событие попадает в шину.
  2. Загрузка подписчиков: При инициализации EventBus загружает из таблицы БД erp208_subscribers записи, где is_notification = 1.
  3. Слушатель: Для таких записей автоматически вешается слушатель на метод _proxy_to_notification_center.
  4. Передача в Bus: Метод прокси берет данные события и передает их в Service_Erp217_Bus::send().
  5. Отправка: Центр уведомлений проверяет, подписан ли конкретный $user_id на это событие, выбирает шаблон и ставит сообщение в очередь (erp217_queue).

4. Требования в БД

Чтобы уведомление сработало, убедитесь что:

  • В таблице erp208_subscribers есть запись с нужным event_name и установленным флагом is_notification = 1.
  • В таблице erp217_subscriptions есть запись для конкретного пользователя на это событие.
  • В таблице erp217_templates создан шаблон для этого события и выбранного канала (email/telegram).

5. Пример вызова из кода

Чтобы отправить уведомление, достаточно просто опубликовать событие:

Service_Erp208_EventBus::instance()->publish('new_task', [
    'task_name' => 'Подготовить отчет',
    'deadline'  => '2023-12-31',
    'target_user_id' => 45 // Кому придет уведомление
], Auth::instance()->get_user()->id);

Инструкция по отладке и настройке уведомлений (Event Bus)

Если сообщение не ушло, проблема может быть на одном из четырех этапов: Публикация → Подписка → Очередь → Отправка.

1. Упрощенная проверка (Ловим проблему)

Чтобы понять, где обрывается цепочка, модифицируйте метод _proxy_to_notification_center в файле EventBus.php, добавив временный лог:

protected function _proxy_to_notification_center($payload, $event_name, $initiator_id)
{
    $user_id = isset($payload['target_user_id']) ? $payload['target_user_id'] : $initiator_id;
    
    // ВРЕМЕННЫЙ ЛОГ ДЛЯ ТЕСТА
    Kohana_Log::instance()->add(Log::DEBUG, "EVENT_DEBUG: Event :name caught for user :user", [
        ':name' => $event_name,
        ':user' => $user_id
    ])->write();

    if ($user_id) {
        Service_Erp217_Bus::instance()->send($event_name, $user_id, $payload);
    }
}

Если в логах (application/logs/...) пусто после вызова события:

  • Проверьте таблицу erp_208_event_subscribers. Поле is_notification должно быть 1, а is_active — 1.
  • Проверьте, совпадает ли event_name в таблице с тем, что вы передаете в publish().

2. Чек-лист по базе данных (Самые частые причины)

Проверьте эти 3 таблицы по порядку:

  1. Таблица erp_208_event_subscribers:
    • Должна быть запись: event_name = 'ваше_событие', is_notification = 1.
    • Зачем: Без этого Event Bus не "перекинет" данные в модуль уведомлений.
  2. Таблица erp217_subscriptions:
    • Должна быть запись для конкретного user_id (получателя) и этого event_type.
    • Зачем: Система не отправляет спам. Пользователь должен быть "подписан" на этот тип уведомлений.
  3. Таблица erp217_templates:
    • Должен быть шаблон с event_alias, совпадающим с вашим событием, и нужным channel (email/telegram).
    • Зачем: Системе нужно знать, какой текст отправлять.

3. Проверка очереди

Если в БД всё настроено верно, загляните в таблицу erp217_queue:

  • Если там появилась запись со статусом pending — значит, связка сработала, но не запущен Cron.
  • Если запись в статусе failed — смотрите поле last_error.

4. Как принудительно протолкнуть очередь (для теста)

Если сообщения "зависли" в очереди, выполните этот код (например, в тестовом контроллере):

// Обработать 10 сообщений из очереди прямо сейчас
Service_Erp217_Bus::instance()->process_queue(10);

5. Модификация для надежности

В файле Service/Erp217/Bus.php в методе send есть пустой блок try-catch. Рекомендуется добавить туда логирование, чтобы видеть ошибки БД при создании очереди:

try {
    // ... код сохранения в очередь ...
} catch (Exception $e) {
    $db->rollback();
    Kohana_Log::instance()->add(Log::ERROR, 'NOTIFICATION_BUS_ERROR: ' . $e->getMessage());
}

Итог: Если сообщения не уходят, скорее всего, либо нет записи в erp_208_event_subscribers (событие не триггерит прокси), либо у пользователя в erp217_subscriptions не включен конкретный канал связи.