Как вставить комментарии из Битрикса в письмо?
У меня есть класс который я использую в системе
<?php
use Bitrix\Main\EventManager;
use Bitrix\Crm\DealTable;
use Bitrix\Main\Mail\Event;
class UnifiedWindowQualityRating {
const UNIFIED_WINDOW_CATEGORY_ID = 16;
const STAGE_SUCCESS = 'C16:EXECUTING';
const FIELD_CODE_RATING = 'UF_CRM_QUALITY_RATING';
const FIELD_CODE_RATED = 'UF_CRM_QUALITY_RATED';
public static function init() {
$event_manager = EventManager::getInstance();
$event_manager->addEventHandler('crm', 'OnAfterCrmDealUpdate', [self::class, 'on_deal_update']);
$event_manager->addEventHandler('crm', 'OnBeforeCrmDealUpdate', [self::class, 'on_before_deal_update']);
}
public static function on_before_deal_update(&$ar_fields) {
if (!empty($ar_fields['ID']) && isset($ar_fields['STAGE_ID'])) {
$deal_id = $ar_fields['ID'];
$current_stage = self::get_current_stage($deal_id);
if ($current_stage) {
$GLOBALS['QUALITY_RATING_OLD_STAGE_' . $deal_id] = $current_stage;
}
}
}
public static function on_deal_update($ar_fields) {
if (empty($ar_fields['ID'])) {
return;
}
$deal_id = $ar_fields['ID'];
$old_stage = self::get_old_stage($deal_id, $ar_fields);
$new_stage = $ar_fields['STAGE_ID'] ?? self::get_current_stage($deal_id);
if ($old_stage && $new_stage && $old_stage !== self::STAGE_SUCCESS && $new_stage === self::STAGE_SUCCESS) {
self::process_deal($deal_id);
}
}
private static function get_old_stage($deal_id, $ar_fields) {
if (isset($GLOBALS['QUALITY_RATING_OLD_STAGE_' . $deal_id])) {
$old_stage = $GLOBALS['QUALITY_RATING_OLD_STAGE_' . $deal_id];
unset($GLOBALS['QUALITY_RATING_OLD_STAGE_' . $deal_id]);
return $old_stage;
}
if (isset($ar_fields['STAGE_ID_OLD'])) {
return $ar_fields['STAGE_ID_OLD'];
}
return self::get_current_stage($deal_id);
}
private static function get_current_stage($deal_id) {
try {
$deal_data = DealTable::getById($deal_id)->fetch();
return $deal_data['STAGE_ID'] ?? '';
} catch (Exception $e) {
return '';
}
}
private static function process_deal($deal_id) {
if (!self::acquire_lock($deal_id)) {
return;
}
try {
sleep(1);
$deal_data = DealTable::getById($deal_id)->fetch();
if (!$deal_data) {
return;
}
if (!self::check_conditions($deal_data)) {
return;
}
self::send_email($deal_data);
} catch (Exception $e) {
} finally {
self::release_lock($deal_id);
}
}
private static function acquire_lock($deal_id) {
$lock_file = $_SERVER['DOCUMENT_ROOT'] . "/upload/tmp/quality_lock_{$deal_id}";
$lock_dir = dirname($lock_file);
if (!is_dir($lock_dir)) {
mkdir($lock_dir, 0755, true);
}
$fp = @fopen($lock_file, 'x');
if ($fp) {
fclose($fp);
return true;
}
return false;
}
private static function release_lock($deal_id) {
$lock_file = $_SERVER['DOCUMENT_ROOT'] . "/upload/tmp/quality_lock_{$deal_id}";
if (file_exists($lock_file)) {
unlink($lock_file);
}
}
private static function check_conditions($deal_data) {
if (!self::is_unified_window_deal($deal_data)) {
return false;
}
if (!self::is_correct_stage($deal_data)) {
return false;
}
if (!self::is_not_sent($deal_data)) {
return false;
}
if (!self::has_email($deal_data)) {
return false;
}
return true;
}
public static function is_unified_window_deal($deal_data) {
return isset($deal_data['CATEGORY_ID']) && $deal_data['CATEGORY_ID'] == self::UNIFIED_WINDOW_CATEGORY_ID;
}
private static function is_correct_stage($deal_data) {
return isset($deal_data['STAGE_ID']) && $deal_data['STAGE_ID'] === self::STAGE_SUCCESS;
}
private static function is_not_sent($deal_data) {
return empty($deal_data[self::FIELD_CODE_RATED]);
}
private static function has_email($deal_data) {
return !empty(self::get_initiator_email($deal_data));
}
private static function get_last_comment($deal_id, $limit=5){
$comments = [];
$activityResult = CCrmActivity::GetList(
['CREATED' => 'DESC'],
[
'BINDING_ENTITY_TYPE_ID' => CCrmOwnerType::Deal,
'BINDING_ENTITY_ID' => $deal_id,
'TYPE_ID' => CCrmActivityType::Provider,
'PROVIDER_ID' => 'CRM_COMMENT'
],
false,
false,
['ID', 'DESCRIPTION']
);
$count = 0;
while ($activity = $activityResult->Fetch()) {
if (!empty($activity['DESCRIPTION']) && $count < $limit) {
$comments[] = $activity['DESCRIPTION'];
$count++;
}
}
return $comments;
}
public static function send_email($deal_data) {
$deal_id = $deal_data['ID'];
$email = self::get_initiator_email($deal_data);
if (empty($email)) {
return false;
}
$deal_url = self::get_deal_url($deal_id);
$rating_token = self::generate_rating_token($deal_id);
$excellent_url = self::get_rating_url_excellent($deal_id, $rating_token);
$poor_url = self::get_rating_url_poor($deal_id, $rating_token);
$comments = self::get_last_comment($deal_id);
$last_comments_html = '';
foreach ($comments as $comment) {
$last_comments_html .= "<p><em>" . htmlspecialchars($comment) . "</em></p>";
}
$subject = 'Оценка качества выполненной работы';
$html_message = "
<p>Ваша заявка \"<strong>{$deal_id} - {$deal_data['TITLE']}</strong>\" выполнена, оцените качество работы.</p>
<p>Последние комментарии: </p>
{$last_comments_html}
<p>Ссылка на заявку: <a href='{$deal_url}'>{$deal_url}</a></p>
<div style='margin: 20px 0;'>
<a href='{$excellent_url}' target='_blank' style='background-color: #4CAF50; color: white; padding: 10px 20px; text-decoration: none; margin-right: 10px; border-radius: 4px;'>Отлично</a>
<a href='{$poor_url}' target='_blank' style='background-color: #f44336; color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px;'>Неудовлетворительно</a>
</div>
<p style='color: #666; font-size: 12px;'>Оценку можно поставить только один раз</p>
";
$html_message = mb_convert_encoding($html_message, 'UTF-8', 'auto');
$email_fields = [
"EVENT_NAME" => "CRM_QUALITY_RATING",
"LID" => "s1",
"C_FIELDS" => [
"EMAIL_TO" => $email,
"SUBJECT" => $subject,
"BODY" => $html_message,
],
];
$send_result = Event::send($email_fields);
if ($send_result) {
$update_fields = [
self::FIELD_CODE_RATED => 1
];
$deal_object = new CCrmDeal(false);
$update_result = $deal_object->update($deal_id, $update_fields);
if ($update_result) {
// self::add_timeline_comment($deal_id, "Отправлено письмо с запросом оценки качества на email: {$email}");
return true;
}
}
return false;
}
public static function get_initiator_email($deal_data) {
$email_fields = ['UF_CRM_EMAIL_FROM_REQUEST', 'UF_CRM_EMAIL', 'UF_CRM_CONTACT_EMAIL', 'EMAIL'];
foreach ($email_fields as $field) {
if (!empty($deal_data[$field])) {
return $deal_data[$field];
}
}
if (!empty($deal_data['CONTACT_ID'])) {
$multi_fields = CCrmFieldMulti::GetList(
['ID' => 'asc'],
['ENTITY_ID' => 'CONTACT', 'ELEMENT_ID' => $deal_data['CONTACT_ID']]
);
while ($field = $multi_fields->Fetch()) {
if ($field['TYPE_ID'] === 'EMAIL' && !empty($field['VALUE'])) {
return $field['VALUE'];
}
}
}
return '';
}
private static function get_deal_url($deal_id) {
return \Bitrix\Main\Config\Option::get('main', 'site_addr', '') . "/crm/deal/details/{$deal_id}/";
}
private static function generate_rating_token($deal_id) {
$salt = \Bitrix\Main\Config\Option::get('main', 'server_uniq_id', '');
return md5($deal_id . $salt . date('Y-m-d'));
}
private static function get_rating_url_excellent($deal_id, $rating_token) {
$base_url = \Bitrix\Main\Config\Option::get('main', 'site_addr', '');
return $base_url . "/local/integrat/quality_assesment/excellent.php?deal_id={$deal_id}&token={$rating_token}";
}
private static function get_rating_url_poor($deal_id, $rating_token) {
$base_url = \Bitrix\Main\Config\Option::get('main', 'site_addr', '');
return $base_url . "/local/integrat/quality_assesment/poor.php?deal_id={$deal_id}&token={$rating_token}";
}
public static function save_rating_direct($rating_value, $deal_id, $token) {
try {
if (self::verify_rating_token($deal_id, $token)) {
$deal_data = DealTable::getById($deal_id)->fetch();
if ($deal_data && self::is_unified_window_deal($deal_data) && empty($deal_data[self::FIELD_CODE_RATED])) {
$rating_enum_id = self::get_rating_enum_id($rating_value);
if ($rating_enum_id) {
$deal_object = new CCrmDeal(false);
$update_fields = [
self::FIELD_CODE_RATING => $rating_enum_id,
self::FIELD_CODE_RATED => 1
];
$deal_object->Update($deal_id, $update_fields);
$rating_text = ($rating_value === 'excellent') ? 'Отлично' : 'Неудовлетворительно';
self::add_timeline_comment($deal_id, "Оценка качества: {$rating_text}");
}
}
}
} catch (Exception $e) {
}
}
private static function get_rating_enum_id($rating_value) {
$rating_text = ($rating_value === 'excellent') ? 'Отлично' : 'Неудовлетворительно';
$user_field = CUserTypeEntity::GetList([], [
'ENTITY_ID' => 'CRM_DEAL',
'FIELD_NAME' => self::FIELD_CODE_RATING
])->Fetch();
if (!$user_field) {
return false;
}
$enum_values = [];
$enum_res = CUserFieldEnum::GetList([], [
'USER_FIELD_ID' => $user_field['ID']
]);
while ($enum = $enum_res->Fetch()) {
$enum_values[$enum['VALUE']] = $enum['ID'];
}
return $enum_values[$rating_text] ?? false;
}
private static function verify_rating_token($deal_id, $rating_token) {
$salt_value = \Bitrix\Main\Config\Option::get('main', 'server_uniq_id', '');
$expected_token = md5($deal_id . $salt_value . date('Y-m-d'));
$yesterday_token = md5($deal_id . $salt_value . date('Y-m-d', strtotime('-1 day')));
return $rating_token === $expected_token || $rating_token === $yesterday_token;
}
private static function add_timeline_rating($deal_id){
if(isset($ar_fields['FIELDS'][self::FIELD_CODE_RATING])) {
$deal_id = $ar_fields['ID'];
$rating = $ar_fields['FIELDS'][self::FIELD_CODE_RATING];
self::add_timeline_comment($deal_id, "Оценка качества была поставлена: {$rating}");
}
}
// private static function add_timeline_comment($deal_id, $comment_text) {
// $arFields = [
// 'ENTITY_TYPE' => 'DEAL',
// 'ENTITY_ID' => $deal_id,
// 'COMMENT' => $comment_text,
// 'AUTHOR_ID' => 1,
// ];
//
//
// $comment_id = CCrmTimelineComment::Add($arFields);
//
//
// if ($comment_id) {
// return true;
// }
//
// return false;
// }
}
UnifiedWindowQualityRating::init();
Конкретно у меня вопросы к части кода
private static function get_last_comment($deal_id, $limit=5){
$comments = [];
$activityResult = CCrmActivity::GetList(
['CREATED' => 'DESC'],
[
'BINDING_ENTITY_TYPE_ID' => CCrmOwnerType::Deal,
'BINDING_ENTITY_ID' => $deal_id,
'TYPE_ID' => CCrmActivityType::Provider,
'PROVIDER_ID' => 'CRM_COMMENT'
],
false,
false,
['ID', 'DESCRIPTION']
);
$count = 0;
while ($activity = $activityResult->Fetch()) {
if (!empty($activity['DESCRIPTION']) && $count < $limit) {
$comments[] = $activity['DESCRIPTION'];
$count++;
}
}
return $comments;
}
public static function send_email($deal_data) {
$deal_id = $deal_data['ID'];
$email = self::get_initiator_email($deal_data);
if (empty($email)) {
return false;
}
$deal_url = self::get_deal_url($deal_id);
$rating_token = self::generate_rating_token($deal_id);
$excellent_url = self::get_rating_url_excellent($deal_id, $rating_token);
$poor_url = self::get_rating_url_poor($deal_id, $rating_token);
$comments = self::get_last_comment($deal_id);
$last_comments_html = '';
foreach ($comments as $comment) {
$last_comments_html .= "<p><em>" . htmlspecialchars($comment) . "</em></p>";
}
$subject = 'Оценка качества выполненной работы';
$html_message = "
<p>Ваша заявка \"<strong>{$deal_id} - {$deal_data['TITLE']}</strong>\" выполнена, оцените качество работы.</p>
<p>Последние комментарии: </p>
{$last_comments_html}
<p>Ссылка на заявку: <a href='{$deal_url}'>{$deal_url}</a></p>
<div style='margin: 20px 0;'>
<a href='{$excellent_url}' target='_blank' style='background-color: #4CAF50; color: white; padding: 10px 20px; text-decoration: none; margin-right: 10px; border-radius: 4px;'>Отлично</a>
<a href='{$poor_url}' target='_blank' style='background-color: #f44336; color: white; padding: 10px 20px; text-decoration: none; border-radius: 4px;'>Неудовлетворительно</a>
</div>
<p style='color: #666; font-size: 12px;'>Оценку можно поставить только один раз</p>
";
$html_message = mb_convert_encoding($html_message, 'UTF-8', 'auto');
$email_fields = [
"EVENT_NAME" => "CRM_QUALITY_RATING",
"LID" => "s1",
"C_FIELDS" => [
"EMAIL_TO" => $email,
"SUBJECT" => $subject,
"BODY" => $html_message,
],
];
$send_result = Event::send($email_fields);
if ($send_result) {
$update_fields = [
self::FIELD_CODE_RATED => 1
];
$deal_object = new CCrmDeal(false);
$update_result = $deal_object->update($deal_id, $update_fields);
if ($update_result) {
// self::add_timeline_comment($deal_id, "Отправлено письмо с запросом оценки качества на email: {$email}");
return true;
}
}
return false;
}
Письмо приходит на почту но последние комментарии в нем не отображаются пробовал использовать разные классы не помогает