function DeleteMessage($ID, $checkRights = "Y")
 {
     $err_mess = CTicket::err_mess() . "<br>Function: DeleteMessage<br>Line: ";
     global $DB;
     $ID = intval($ID);
     if ($ID <= 0) {
         return;
     }
     $bAdmin = "N";
     if ($checkRights == "Y") {
         $bAdmin = CTicket::IsAdmin() ? "Y" : "N";
     } else {
         $bAdmin = "Y";
     }
     if ($bAdmin == "Y") {
         $strSql = "\n\t\t\t\tSELECT\n\t\t\t\t\tF.ID FILE_ID,\n\t\t\t\t\tM.TICKET_ID\n\t\t\t\tFROM\n\t\t\t\t\tb_ticket_message M\n\t\t\t\tLEFT JOIN b_ticket_message_2_file MF ON (MF.MESSAGE_ID = M.ID)\n\t\t\t\tLEFT JOIN b_file F ON (F.ID = MF.FILE_ID)\n\t\t\t\tWHERE\n\t\t\t\t\tM.ID='{$ID}'\n\t\t\t\t";
         $z = $DB->Query($strSql, false, $err_mess . __LINE__);
         while ($zr = $z->Fetch()) {
             $ticketID = $zr["TICKET_ID"];
             if (intval($zr["FILE_ID"]) > 0) {
                 CFile::Delete($zr["FILE_ID"]);
             }
         }
         $DB->Query("DELETE FROM b_ticket_search WHERE MESSAGE_ID = '{$ID}'", false, $err_mess . __LINE__);
         $z = $DB->Query("DELETE FROM b_ticket_message WHERE ID='{$ID}'", false, $err_mess . __LINE__);
         if (intval($z->AffectedRowsCount()) > 0) {
             CTicket::UpdateLastParams($ticketID);
             CTicket::UpdateLastParams2($ticketID, CTicket::DELETE);
         }
     }
 }
 function Set($arFields, &$MID, $id = "", $checkRights = "Y", $sendEmailToAuthor = "Y", $sendEmailToTechsupport = "Y")
 {
     global $DB, $APPLICATION, $USER;
     $err_mess = CAllTicket::err_mess() . "<br>Function: Set<br>Line: ";
     $v0 = self::Set_InitVar($arFields, $id, $checkRights, $sendEmailToAuthor, $sendEmailToTechsupport);
     if (!is_array($v0)) {
         return $v0;
     }
     $v = $v0["v"];
     /* isNew, CHECK_RIGHTS, SEND_EMAIL_TO_AUTHOR, SEND_EMAIL_TO_TECHSUPPORT, bAdmin, bSupportTeam, bSupportClient, bDemo, bOwner, uid, bActiveCoupon, IsSpam */
     $f = $v0["f"];
     /* ID, SITE_ID, MODIFIED_GUEST_ID, OWNER_USER_ID, OWNER_SID, HOLD_ON, IS_SPAM */
     // если модифицируем обращение то
     if (!$v->isNew) {
         unset($arFields['COUPON']);
         $arFields['ID'] = $f->ID;
         $arFields = CTicket::ExecuteEvents('OnBeforeTicketUpdate', $arFields, false);
         $v->closeDate = isset($arFields["CLOSE"]) && $arFields["CLOSE"] == "Y";
         //$close
         // запоминаем предыдущие важные значения
         $v->arrOldFields = array();
         $arr = array("RESPONSIBLE_USER_ID", "SLA_ID", "CATEGORY_ID", "CRITICALITY_ID", "STATUS_ID", "MARK_ID", "DIFFICULTY_ID", "DATE_CLOSE", "HOLD_ON");
         $str = "ID";
         foreach ($arr as $s) {
             $str .= "," . $s;
         }
         $strSql = "SELECT " . $str . ", SITE_ID FROM b_ticket WHERE ID='" . $f->ID . "'";
         $z = $DB->Query($strSql, false, $err_mess . __LINE__);
         if ($zr = $z->Fetch()) {
             $f->SITE_ID = $zr["SITE_ID"];
             if (intval($v->uid) == $zr["RESPONSIBLE_USER_ID"]) {
                 $v->bSupportTeam = "Y";
             }
             foreach ($arr as $key) {
                 $v->arrOldFields[$key] = $zr[$key];
             }
         }
         $f->FromArray($arFields, "SITE_ID,MODIFIED_MODULE_NAME,SUPPORT_COMMENTS,SLA_ID,SOURCE_ID", array(CSupportTableFields::MORE0, CSupportTableFields::NOT_EMTY_STR));
         $f->FromArray($arFields, "CATEGORY_ID,RESPONSIBLE_USER_ID,STATUS_ID,DIFFICULTY_ID,CRITICALITY_ID");
         $f->set("MODIFIED_USER_ID", $v->uid, array(CSupportTableFields::MORE0));
         $f->setCurrentTime("TIMESTAMP_X");
         if ($v->closeDate) {
             $f->setCurrentTime("DATE_CLOSE");
         }
         // ?remake? {
         $v->IS_GROUP_USER = '******';
         if ($v->bAdmin) {
             $IS_GROUP_USER = '******';
         } elseif ($v->CHECK_RIGHTS == 'Y' && ($v->bSupportClient || $v->bSupportTeam)) {
             if ($v->bSupportTeam) {
                 $join_query = '(T.RESPONSIBLE_USER_ID IS NOT NULL AND T.RESPONSIBLE_USER_ID=O.USER_ID)';
             } else {
                 $join_query = '(T.OWNER_USER_ID IS NOT NULL AND T.OWNER_USER_ID=O.USER_ID)';
             }
             $strSql = "SELECT 'x'\n\t\t\t\tFROM b_ticket T\n\t\t\t\tINNER JOIN b_ticket_user_ugroup O ON {$join_query}\n\t\t\t\tINNER JOIN b_ticket_user_ugroup C ON (O.GROUP_ID=C.GROUP_ID)\n\t\t\t\tINNER JOIN b_ticket_ugroups G ON (O.GROUP_ID=G.ID)\n\t\t\t\tWHERE T.ID='" . $f->ID . "' AND C.USER_ID='" . $v->uid . "' AND C.CAN_VIEW_GROUP_MESSAGES='Y' AND G.IS_TEAM_GROUP='" . ($v->bSupportTeam ? "Y" : "N") . "'";
             $z = $DB->Query($strSql);
             if ($zr = $z->Fetch()) {
                 $v->IS_GROUP_USER = '******';
             }
         }
         // }
         if (isset($arFields["AUTO_CLOSE_DAYS"]) && intval($arFields["AUTO_CLOSE_DAYS"]) > 0 && strlen($arFields["MESSAGE"]) > 0 && $arFields["HIDDEN"] != "Y" && $arFields["NOT_CHANGE_STATUS"] != "Y") {
             $f->AUTO_CLOSE_DAYS = $arFields["AUTO_CLOSE_DAYS"];
         }
         if (is_array($v->arrOldFields) && is_array($arFields) && $arFields["CLOSE"] == "N" && strlen($v->arrOldFields["DATE_CLOSE"]) > 0) {
             $f->DATE_CLOSE = null;
             $f->REOPEN = "Y";
         }
         // Если есть что и мы Аднины или из группы ТП, запишем в базу
         $v->FirstUpdateRes = false;
         if ($v->bSupportTeam || $v->bAdmin) {
             $arFields_i = $f->ToArray(CSupportTableFields::ALL, array(CSupportTableFields::ONLY_CHANGED), true);
             if (count($arFields_i) > 0) {
                 $v->SupportTeamUpdateRes = $DB->Update("b_ticket", $arFields_i, "WHERE ID='" . $f->ID . "'", $err_mess . __LINE__);
                 //$rows1
                 $GLOBALS["USER_FIELD_MANAGER"]->Update("SUPPORT", $f->ID, $arFields);
                 // если указана отметка о спаме то установим отметку о спаме
                 if (strlen($f->IS_SPAM) > 0) {
                     CTicket::MarkAsSpam($f->ID, $f->IS_SPAM, $v->CHECK_RIGHTS);
                 }
                 $v->newSLA = isset($arFields_i["SLA_ID"]) && $v->arrOldFields["SLA_ID"] != $arFields_i["SLA_ID"];
             }
         } elseif ($v->bOwner || $v->bSupportClient) {
             $arFields_i = $f->ToArray("TIMESTAMP_X,DATE_CLOSE,CRITICALITY_ID,MODIFIED_USER_ID,MODIFIED_GUEST_ID,MODIFIED_MODULE_NAME,REOPEN", array(CSupportTableFields::ONLY_CHANGED), true);
             $arFields_i["MARK_ID"] = intval($arFields["MARK_ID"]);
             if (count($arFields_i) > 0) {
                 $v->SupportClientUpdateRes = $DB->Update("b_ticket", $arFields_i, "WHERE ID='" . $f->ID . "' AND (OWNER_USER_ID='" . $v->uid . "' OR CREATED_USER_ID='" . $v->uid . "' OR '" . $v->CHECK_RIGHTS . "'='N' OR '" . $v->IS_GROUP_USER . "'='Y')", $err_mess . __LINE__);
                 $GLOBALS["USER_FIELD_MANAGER"]->Update("SUPPORT", $f->ID, $arFields);
             }
         }
         // поля для записи лога
         /*$arFields_log = array(
         			"LOG"							=> "Y",
         			"MESSAGE_CREATED_USER_ID"		=> $MODIFIED_USER_ID,
         			"MESSAGE_CREATED_MODULE_NAME"	=> $MODIFIED_MODULE_NAME,
         			"MESSAGE_CREATED_GUEST_ID"		=> $MODIFIED_GUEST_ID,
         			"MESSAGE_SOURCE_ID"				=> intval($arFields["SOURCE_ID"])
         		);*/
         // если необходимо соблюдать права то
         if ($v->CHECK_RIGHTS == "Y") {
             // если update техподдержки не прошел то
             if (intval($v->SupportTeamUpdateRes) <= 0) {
                 // убираем из массива исходных значений то что может менять только техподдержка
                 unset($v->arrOldFields["RESPONSIBLE_USER_ID"]);
                 unset($v->arrOldFields["SLA_ID"]);
                 unset($v->arrOldFields["CATEGORY_ID"]);
                 unset($v->arrOldFields["DIFFICULTY_ID"]);
                 unset($v->arrOldFields["STATUS_ID"]);
             }
             // если update автора не прошел то
             if (intval($v->SupportClientUpdateRes) <= 0) {
                 // убираем из массива исходных значений то что может менять только автор
                 unset($v->arrOldFields["MARK_ID"]);
             }
         }
         // если состоялся один из updat'ов то
         if (intval($v->SupportTeamUpdateRes) > 0 || intval($v->SupportClientUpdateRes) > 0) {
             // добавляем сообщение
             $arFields["MESSAGE_CREATED_MODULE_NAME"] = $arFields["MODIFIED_MODULE_NAME"];
             if (is_set($arFields, "IMAGE")) {
                 $arFields["FILES"][] = $arFields["IMAGE"];
             }
             $MID = CTicket::AddMessage($f->ID, $arFields, $arFiles, $v->CHECK_RIGHTS);
             $MID = intval($MID);
             $dateType = CTicket::ADD;
             if ($v->newSLA || $f->REOPEN == "Y") {
                 $dateType = CTicket::CURRENT_DATE;
             }
             CTicket::UpdateLastParams2($f->ID, $dateType);
             /*// если обращение закрывали то
             		if($v->closeDate)
             		{
             			// удалим агентов-напоминальщиков и обновим параметры обращения
             			CTicketReminder::Remove($f->ID);
             		}*/
             if (is_array($v->arrOldFields) && is_array($arFields)) {
                 // определяем что изменилось
                 $v->arChange = array();
                 if ($MID > 0) {
                     if ($arFields["HIDDEN"] != "Y") {
                         $v->arChange["MESSAGE"] = "Y";
                     } else {
                         $v->arChange["HIDDEN_MESSAGE"] = "Y";
                     }
                 }
                 if ($arFields["CLOSE"] == "Y" && strlen($v->arrOldFields["DATE_CLOSE"]) <= 0) {
                     $v->arChange["CLOSE"] = "Y";
                 } elseif ($arFields["CLOSE"] == "N" && strlen($v->arrOldFields["DATE_CLOSE"]) > 0) {
                     $v->arChange["OPEN"] = "Y";
                 }
                 if (array_key_exists("HOLD_ON", $arFields)) {
                     if ($v->arrOldFields["HOLD_ON"] == null) {
                         $v->arrOldFields["HOLD_ON"] = 'N';
                     }
                     if ($arFields["HOLD_ON"] == null) {
                         $arFields["HOLD_ON"] = 'N';
                     }
                     if ($v->arrOldFields["HOLD_ON"] != $arFields["HOLD_ON"]) {
                         if ($arFields["HOLD_ON"] == "Y") {
                             $v->arChange["HOLD_ON_ON"] = "Y";
                         } else {
                             $v->arChange["HOLD_ON_OFF"] = "Y";
                         }
                     }
                     unset($v->arrOldFields["HOLD_ON"]);
                 }
                 foreach ($v->arrOldFields as $key => $value) {
                     if (isset($arFields[$key]) && intval($value) != intval($arFields[$key])) {
                         $v->arChange[$key] = "Y";
                     }
                 }
                 // получим текущие значения обращения
                 CTimeZone::Disable();
                 $z = CTicket::GetByID($f->ID, $f->SITE_ID, "N");
                 CTimeZone::Enable();
                 if ($zr = $z->Fetch()) {
                     $nf = (object) $zr;
                     $rsSite = CSite::GetByID($nf->SITE_ID);
                     $v->arrSite = $rsSite->Fetch();
                     self::Set_sendMails($nf, $v, $arFields);
                     //if ($v->arChange['SLA_ID'] == 'Y' || $v->arChange['OPEN'] == 'Y') CTicketReminder::Update($nf->ID, true);
                 }
             }
             CTicket::ExecuteEvents('OnAfterTicketUpdate', $arFields, false);
         }
     } else {
         $arFields = CTicket::ExecuteEvents('OnBeforeTicketAdd', $arFields, false);
         if (!$arFields) {
             return false;
         }
         if (!((strlen(trim($arFields["OWNER_SID"])) > 0 || intval($arFields["OWNER_USER_ID"]) > 0) && ($v->bSupportTeam || $v->bAdmin))) {
             $f->OWNER_USER_ID = $v->uid > 0 ? $v->uid : null;
             $f->OWNER_SID = null;
             $f->OWNER_GUEST_ID = intval($_SESSION["SESS_GUEST_ID"]) > 0 ? intval($_SESSION["SESS_GUEST_ID"]) : null;
         }
         $f->FromArray($arFields, "CREATED_MODULE_NAME,CATEGORY_ID,STATUS_ID,DIFFICULTY_ID,CRITICALITY_ID,SOURCE_ID,TITLE", array(CSupportTableFields::MORE0, CSupportTableFields::NOT_EMTY_STR));
         $f->set("CREATED_USER_ID", $v->uid, array(CSupportTableFields::MORE0));
         $f->setCurrentTime("LAST_MESSAGE_DATE,DAY_CREATE,TIMESTAMP_X");
         $f->DATE_CREATE = time() + CTimeZone::GetOffset();
         // если обращение создается сотрудником техподдержки, администратором или демо пользователем
         if ($v->bSupportTeam || $v->bAdmin || $bv->Demo) {
             $f->FromArray($arFields, "SUPPORT_COMMENTS", array(CSupportTableFields::NOT_EMTY_STR));
         }
         if (!self::Set_getCOUPONandSLA($v, $f, $arFields)) {
             return false;
         }
         // $f +SLA_ID $v +V_COUPON +bActiveCoupon
         if ($v->bActiveCoupon) {
             $f->COUPON = $v->V_COUPON;
         }
         self::Set_getResponsibleUser($v, $f, $arFields);
         // $f +RESPONSIBLE_USER_ID  $v +T_EVENT1 +T_EVENT2 +T_EVENT3
         // поля для записи лога
         $v->arFields_log = array("LOG" => "Y", "MESSAGE_CREATED_USER_ID" => $f->CREATED_USER_ID, "MESSAGE_CREATED_MODULE_NAME" => $f->CREATED_MODULE_NAME, "MESSAGE_CREATED_GUEST_ID" => $f->MODIFIED_GUEST_ID, "MESSAGE_SOURCE_ID" => $f->SOURCE_ID);
         $acd0 = intval(COption::GetOptionString("support", "DEFAULT_AUTO_CLOSE_DAYS"));
         $f->AUTO_CLOSE_DAYS = $acd0 <= 0 ? 7 : $acd0;
         $arFields["AUTO_CLOSE_DAYS"] = $f->AUTO_CLOSE_DAYS;
         $arFields_i = $f->ToArray(CSupportTableFields::ALL, array(CSupportTableFields::NOT_NULL, CSupportTableFields::NOT_DEFAULT), true);
         $id = $DB->Insert("b_ticket", $arFields_i, $err_mess . __LINE__);
         if (!($id > 0)) {
             return $id;
         }
         $f->ID = $id;
         $GLOBALS["USER_FIELD_MANAGER"]->Update("SUPPORT", $f->ID, $arFields);
         $arFields["MESSAGE_AUTHOR_SID"] = $f->OWNER_SID;
         $arFields["MESSAGE_AUTHOR_USER_ID"] = $f->OWNER_USER_ID;
         $arFields["MESSAGE_CREATED_MODULE_NAME"] = $f->CREATED_MODULE_NAME;
         $arFields["MESSAGE_SOURCE_ID"] = $f->SOURCE_ID;
         $arFields["HIDDEN"] = "N";
         $arFields["LOG"] = "N";
         $arFields["IS_LOG"] = "N";
         if (is_set($arFields, "IMAGE")) {
             $arFields["FILES"][] = $arFields["IMAGE"];
         }
         $arFiles = null;
         $MID = CTicket::AddMessage($f->ID, $arFields, $arFiles, $v->CHECK_RIGHTS);
         $v->arrFILES = $arFiles;
         $MID = intval($MID);
         if (intval($MID) > 0) {
             CTicket::UpdateLastParams2($f->ID, CTicket::ADD);
             // если указана отметка о спаме то установим отметку о спаме
             if (strlen($f->IS_SPAM) > 0) {
                 CTicket::MarkAsSpam($f->ID, $f->IS_SPAM, $v->CHECK_RIGHTS);
             }
             /********************************************
             				$nf - Заново прочитанные из базы поля
             			********************************************/
             CTimeZone::Disable();
             $z = CTicket::GetByID($f->ID, $f->SITE_ID, "N");
             CTimeZone::Enable();
             if ($zr = $z->Fetch()) {
                 $nf = (object) $zr;
                 $rsSite = CSite::GetByID($nf->SITE_ID);
                 $v->arrSite = $rsSite->Fetch();
                 self::Set_sendMails($nf, $v, $arFields);
                 // создаем событие в модуле статистики
                 if (CModule::IncludeModule("statistic")) {
                     if (!$v->category_set) {
                         $v->T_EVENT1 = "ticket";
                         $v->T_EVENT2 = "";
                         $v->T_EVENT3 = "";
                     }
                     if (strlen($v->T_EVENT3) <= 0) {
                         $v->T_EVENT3 = "http://" . $_SERVER["HTTP_HOST"] . "/bitrix/admin/ticket_edit.php?ID=" . $f->ID . "&lang=" . $v->arrSite["LANGUAGE_ID"];
                     }
                     CStatEvent::AddCurrent($v->T_EVENT1, $v->T_EVENT2, $v->T_EVENT3);
                 }
             }
         }
         // !!! ПРОВЕРИТЬ $arFields ТОЧНО ЛИ ВСЕ $arFields[..] = .. ТАКИЕ ЖЕ КАК В ОРИГИНАЛЕ !!!
         $arFields['ID'] = $f->ID;
         $arFields['MID'] = $MID;
         CTicket::ExecuteEvents('OnAfterTicketAdd', $arFields, true);
     }
     return $f->ID;
 }