Загрузка данных


<?php

/*
 * Класс осуществляющий проверку есть ли задачи для отправку в КИС СЭД
 * и осуществляющий отправку.
 * */

use SL\NPF\V2\Service\Helper\ErrorNotifier;
use SL\NPF\V2\Service\Provider\UserProvider;

class KISQueue
{
    public $dbgMode = true;
    public $docName = [
        'FILE_PASSPORT' => 'Копия паспорта',
        'FILE_SNILS' => 'СНИЛС',
        'FILE_INN' => 'Свидетельство ИНН',
        'FILE_PU' => 'Пенсионное удостоверение / cправка о назначении пенсии',
        'FILE_ANKET' => 'Анкета физического лица (сведения)',
        'APPLICATION_FL' => 'Анкета физического лица (сведения)',
        'FILE_APPROVING_COMMUNICATION' => 'ЗАЯВЛЕНИЕ О СОГЛАСОВАНИИ СПОСОБА СВЯЗИ ФОНДА',
        'FILE_PDN' => 'Согласие на предоставление и обработку персональных данных',
        'CONSENT' => 'Согласие на предоставление и обработку персональных данных',
        'FILE_OTHERS' => 'Прочие документы',
        'PERSONAL_DOCS' => '',
        'CITIZEN_DOCS' => '',
        'MIGRATION_CARD_DOCS' => '',
        'STAY_DOCS' => '',
        'ADDRESS_DOCS' => '',
        'PRED_PERSONAL_DOCS' => '',
        'PRED_MIGRATION_CARD_DOCS' => '',
        'PRED_STAY_DOCS' => '',
        'BEN_PERSONAL_DOCS' => '',
        'BEN_MIGRATION_CARD_DOCS' => '',
        'BEN_O_PERSONAL_DOCS' => '',
        'BEN_O_MIGRATION_CARD_DOCS' => '',
        'BEN_O_STAY_DOCS' => '',
        'DOC_OTHERS' => 'Другие документы',
        'DOCUMENTS' => 'Документ',
        'FILE_DOC_TAX_START' => 'Копия свидетельства ИНН',
        'TAX_RESIDENT' => 'Опросный лист',
	    'FILE_BANK' => 'Банковские реквизиты (договор, сберкнижка)',
	    'ACCEPT_AUTH' => 'Подтверждение авторизации',
    ];

    public function __construct($dbgMode = true)
    {
        $this->dbgMode = $dbgMode;
    }

    /*
     * Метод запуска проверки. выбирает записи у которых флаг "UF_SIGNED" равен  true и флаг "UF_CANSEND" равен false
     * */
    public function run()
    {
		$errorNotifier = new ErrorNotifier();
        $rsRequest = GetRequestOfficialEntityTable::getList(['filter' => ['UF_SIGNED' => 1,
            'UF_KISSEDSEND' => 0, 'UF_GENERATED_FULL' => 1]])->fetchAll();

	    $userIds = [];
	    foreach ($rsRequest as $data)
	    {
		    $userIds[] = (int)$data['UF_USER_ID'];
	    }

	    $users = (new UserProvider())->getList(
		    [
			    'USER_ID' => $userIds
		    ],
	    );

        foreach ($rsRequest as $arItem)
		{
	        $user = $users[(int)$arItem['UF_USER_ID']];
	        if (
		        $user
		        && $user['UF_IS_SEND_DOCUMENTS_LIMITED']
	        )
	        {
		        continue;
	        }

            $path = FGeneratorEntityTable::getFullPath('GetRequestOfficialEntityTable', $arItem['ID']);

            $email = $this->getEmail($arItem['UF_USER_ID']);
            $sendRes = $this->safetySendEmail($path, $arItem['ID'], $email, $this->getSubject($arItem['UF_TYPE'], 'GetRequestOfficialEntityTable'), $this->getMessageText($arItem['UF_TYPE'], 'GetRequestOfficialEntityTable', $arItem), $arItem['UF_PDF'], unserialize($arItem['UF_FILES']),
                'GetRequestOfficialEntityTable');
            $updateFields = [];
            if ($arItem['UF_STATUS'] == 44) {
                $updateFields['STATUS'] = '45';
            }
            if (!$arItem['UF_CANSEND']) {
                $updateFields['CANSEND'] = 1;
            }
            if ($sendRes) {
                $updateFields['KISSEDSEND'] = 1;
            }
			else
			{
				$errorNotifier->notify(
					'Ошибка при отправке в КИС СЭД заявления из GetRequestOfficialEntityTable. Id = ' . $arItem['ID']
				);
			}
            if (!empty($updateFields)) {
                GetRequestOfficialEntityTable::update($arItem['ID'], $updateFields);
            }
        }

        $rsApplication = GetApplicationEntityTable::getList(['filter' => ['UF_SIGNED' => 1, 'UF_KISSEDSEND' => 0,
            'UF_GENERATED_FULL' => 1]])->fetchAll();

	    $userIds = [];
	    foreach ($rsApplication as $data)
	    {
		    $userIds[] = (int)$data['UF_USER_ID'];
	    }

	    $users = (new UserProvider())->getList(
		    [
			    'USER_ID' => $userIds
		    ],
	    );

        foreach ($rsApplication as $arItem){
	        $user = $users[(int)$arItem['UF_USER_ID']];
	        if (
		        $user
		        && $user['UF_IS_SEND_DOCUMENTS_LIMITED']
	        )
	        {
		        continue;
	        }

            $path = FGeneratorEntityTable::getFullPath('GetApplicationEntityTable', $arItem['ID']);
            $email = $this->getEmail($arItem['UF_USER_ID']);
            $sendRes = $this->safetySendEmail($path, $arItem['ID'], $email, $this->getSubject($arItem['UF_TYPE'], 'GetApplicationEntityTable'), $this->getMessageText($arItem['UF_TYPE'], 'GetApplicationEntityTable', $arItem), $arItem['UF_PDF'], unserialize($arItem['UF_FILES']),
                'GetApplicationEntityTable');

            $updateFields = [];
            if ($arItem['UF_STATUS'] == 50) {
                $updateFields['STATUS'] = '51';
            }
            if (!$arItem['UF_CANSEND']) {
                $updateFields['CANSEND'] = 1;
            }
            if ($sendRes) {
                $updateFields['KISSEDSEND'] = 1;
            }
			else
			{
				$errorNotifier->notify(
					'Ошибка при отправке в КИС СЭД заявления из GetApplicationEntityTable. Id = ' . $arItem['ID']
				);
			}
            if (!empty($updateFields)) {
                GetApplicationEntityTable::update($arItem['ID'], $updateFields);
            }
        }

        $rsAccNPO = CreateAccountsNPOEntityTable::getList(['filter' => ['UF_SIGNED' => 1, 'UF_KISSEDSEND' => 0,
            'UF_GENERATED_FULL' => 1, 'UF_STATUS' => 258]])->fetchAll();

	    $userIds = [];
	    foreach ($rsAccNPO as $data)
	    {
		    $userIds[] = (int)$data['UF_USER_ID'];
	    }

	    $users = (new UserProvider())->getList(
		    [
			    'USER_ID' => $userIds
		    ],
	    );

        foreach ($rsAccNPO as $arItem) {
	        $user = $users[(int)$arItem['UF_USER_ID']];
	        if (
		        $user
		        && $user['UF_IS_SEND_DOCUMENTS_LIMITED']
	        )
	        {
		        continue;
	        }

            $path = FGeneratorEntityTable::getFullPath('CreateAccountsNPOEntityTable', $arItem['ID']);
            $email = $this->getEmail($arItem['UF_USER_ID']);
            $sendRes = $this->safetySendEmail($path, $arItem['ID'], $email, $this->getSubject('npo', 'CreateAccountsNPOEntityTable'), $this->getMessageText('npo', 'CreateAccountsNPOEntityTable', $arItem), $arItem['UF_PDF'], unserialize($arItem['UF_FILES']),
                'CreateAccountsNPOEntityTable');

            $updateFields = [];
            if (!$arItem['UF_CANSEND']) {
                $updateFields['CANSEND'] = 1;
            }
            if ($sendRes) {
                $updateFields['KISSEDSEND'] = 1;
            }
            else
            {
	            $errorNotifier->notify(
		            'Ошибка при отправке в КИС СЭД заявления из CreateAccountsNPOEntityTable. Id = ' . $arItem['ID']
	            );
            }
            if (!empty($updateFields)) {
                CreateAccountsNPOEntityTable::update($arItem['ID'], $updateFields);
            }
        }

        $rsAccOPS = CreateAccountsOPSEntityTable::getList(['filter' => ['UF_SIGNED' => 1, 'UF_KISSEDSEND' => 0,
            'UF_GENERATED_FULL' => 1, 'UF_STATUS' => 261]])->fetchAll();

	    $userIds = [];
	    foreach ($rsAccOPS as $data)
	    {
		    $userIds[] = (int)$data['UF_USER_ID'];
	    }

	    $users = (new UserProvider())->getList(
		    [
			    'USER_ID' => $userIds
		    ],
	    );

        foreach ($rsAccOPS as $arItem) {
	        $user = $users[(int)$arItem['UF_USER_ID']];
	        if (
		        $user
		        && $user['UF_IS_SEND_DOCUMENTS_LIMITED']
	        )
	        {
		        continue;
	        }

	        $path = FGeneratorEntityTable::getFullPath('CreateAccountsOPSEntityTable', $arItem['ID']);
	        $email = $this->getEmail($arItem['UF_USER_ID']);
	        $sendRes = $this->safetySendEmail($path, $arItem['ID'], $email, $this->getSubject('ops', 'CreateAccountsOPSEntityTable'), $this->getMessageText('ops', 'CreateAccountsOPSEntityTable', $arItem), $arItem['UF_PDF'], unserialize($arItem['UF_FILES']),
		        'CreateAccountsOPSEntityTable');

            $updateFields = [];
            if (!$arItem['UF_CANSEND']) {
                $updateFields['CANSEND'] = 1;
            }
            if ($sendRes) {
                $updateFields['KISSEDSEND'] = 1;
            }
            else
            {
	            $errorNotifier->notify(
		            'Ошибка при отправке в КИС СЭД заявления из CreateAccountsOPSEntityTable. Id = ' . $arItem['ID']
	            );
            }
            if (!empty($updateFields)) {
                CreateAccountsOPSEntityTable::update($arItem['ID'], $updateFields);
            }
        }
    }

	private function updateDocumentsFiles(): void
	{
		$errorNotifier = new ErrorNotifier();

		$applications = GetApplicationEntityTable::getList(
			[
				'filter' => [
					'UF_NEED_UPDATE_FILES_IN_1C' => 1,
				]
			]);
		while ($application = $applications->fetch())
		{
			$path = FGeneratorEntityTable::getFullPath('GetApplicationEntityTable', $application['ID']);
			$email = $this->getEmail($application['UF_USER_ID']);
			$isEmailSent = (bool)$this->safetySendEmail(
				$path,
				$application['ID'],
				$email,
				$this->getSubject($application['UF_TYPE'], 'GetApplicationEntityTable'),
				$this->getMessageText($application['UF_TYPE'], 'UpdateDocumentsFiles', $application),
				$application['UF_PDF'],
				unserialize($application['UF_FILES'], ['allowed_classes' => false]),
				'GetApplicationEntityTable',
			);

			if (!$isEmailSent)
			{
				$errorNotifier->notify(
					'Ошибка при отправке в КИС СЭД обновления заявления из GetApplicationEntityTable. Id = ' . $application['ID']
				);
			}

			$updateFields = [
				'UF_NEED_UPDATE_FILES_IN_1C' => !$isEmailSent,
			];
			GetApplicationEntityTable::update($application['ID'], $updateFields);
		}
	}

    /*
        * Метод формирует текст письма, которое будет отправлено в КИС СЭД
        * */
    private function getMessageText($type, $class, $fields)
    {
        $fldName = '';
        $text = '';
        switch ($class) {
            case 'GetRequestOfficialEntityTable':
                $fldName = 'UF_DATA';
                $text = 'Новая задача по предоставлению документов';
                break;
	        case 'UpdateDocumentsFiles':
		        $fldName = 'UF_DATA';
		        $text = 'Обновление документов заявления';
		        break;
            case 'GetApplicationEntityTable':
                $fldName = 'UF_FIELDS';
                $text = 'Новое заявление';
                break;
            case 'CreateAccountsNPOEntityTable':
                $fldName = 'UF_DATA';
                $text = 'Заявление на заключение договора НПО';
                break;
            case 'CreateAccountsOPSEntityTable':
                $fldName = 'UF_DATA';
                $text = 'Заявление на заключение договора ОПС';
                break;
            case 'UpdatePersonalMetaEntityTable':
                $fldName = 'UF_DATA';
                $text = 'Запрос на изменение персональных данных';
                break;
        }
        if (empty($fldName)) return "";

        $arFld = unserialize($fields[$fldName]);
        $signString = "";
        if ($fields['UF_SIGNED'] == 1 && !empty($fields['UF_SIGNATURE'])) {
            $arSign = SignonEntityTable::getById($fields['UF_SIGNATURE'])->fetch();
            $signArray = str_split($arSign['UF_ESKEY'], 8);
            if (is_array($signArray)) {
                $signString = implode('-', $signArray);
            }
        }
        $arFld['SIGNON_STRING'] = $signString;
        $html = new HtmlGenerator(null, $type, $arFld);
        $textMessage = $html->getHtml();
        //pr($textMessage);
        //die();

        return $textMessage;
    }

    /*
     * Метод формирует тему письма, которое будет отправлено в КИС СЭД
     * */
    private function getSubject($type, $class)
    {
        $id = 0;
        switch ($class) {
            case 'GetRequestOfficialEntityTable':
                $id = 9;
                break;
            case 'GetApplicationEntityTable':
                $id = 12;
                break;
            case 'CreateAccountsNPOEntityTable':
                return 'Заявление на заключение договора НПО';
                break;
            case 'CreateAccountsOPSEntityTable':
                return 'Заявление на заключение договора ОПС';
                break;
            case 'UpdatePersonalMetaEntityTable':
                return 'Запрос на изменение персональных данных';
                break;
        }
        if ($id == 0)
            return $type;
        $rsData = CUserTypeEntity::GetList(array(), array('ENTITY_ID' => 'HLBLOCK_' . $id, 'FIELD_NAME' => 'UF_TYPE'));
        $element = $rsData->fetch();
        $obEnum = new CUserFieldEnum;
        $rsGender = $obEnum->GetList(array(), array(
            "USER_FIELD_ID" => $element['ID'],
        ));
        $retArr = [];
        while ($arGender = $rsGender->fetch())
            $retArr[$arGender['XML_ID']] = $arGender['VALUE'];
        return (isset($retArr[$type])) ? $retArr[$type] : $type;
    }

    /*
     *  Метод получения адреса почты пользователя
     * */
    private function getEmail($id)
    {
	    try
	    {
		    return Bitrix\Main\UserTable::getList(['select' => ['EMAIL'], 'filter' => ['ID' => $id]])->fetch()['EMAIL'];
	    }
        catch (Exception $e)
        {
			return '';
        }
    }

	private function safetySendEmail($pathFullFile, $id, $email, $subject, $message, $pdf_file, $arFiles, $entity)
	{
		$stringData = "Данные: ID: $id, Сущность: $entity";

		try
		{
			$response = $this->sendEmail($pathFullFile, $id, $email, $subject, $message, $pdf_file, $arFiles, $entity);
			if (!$response)
			{
				$errorNotifier = new ErrorNotifier();
				$errorNotifier->notify('Ошибка отправки в КИС СЭД (1)');
			}

			(new LogJ)->formMessage(
				"Успешная отправка в КИС СЭД 2. " . $stringData,
				[
					"FILE" => __FILE__,
					"LINE" => __LINE__,
				],
				'error',
				'KIS_SED_SEND'
			);

			return $response;
		}
		catch (Exception $e)
		{
			$errorNotifier = new ErrorNotifier();
			$errorNotifier->notify(
				'Ошибка отправки в КИС СЭД (2)',
				[
					'THROWABLE' => $e,
				],
			);

			(new LogJ)->formMessage(
				"Ошибка отправки в КИС СЭД 2. " . $e->getMessage() . $stringData,
				[
					"FILE" => __FILE__,
					"LINE" => __LINE__,
				],
				'error',
				'KIS_SED_SEND'
			);
		}

		return false;
	}

    /*
     * Метод отправки письма
     * var $email string адрес получателя
     * var $subject string тема сообщения
     * var $message string текст сообщения
     * var $pdf_file string основной файл заявления или запроса
     * var $arFiles array массив файлов, кприкрепленных пользователем.
     * */
    private function sendEmail($pathFullFile, $id, $email, $subject, $message, $pdf_file, $arFiles, $entity)
    {
        if ($this->dbgMode == true) {
            file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/logs/kissendtest.log", date("Y-m-d H:i:s", time()) . " \r\n", FILE_APPEND);
            file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/logs/kissendtest.log", "id " . var_export($id, true) . "\r\n", FILE_APPEND);
            file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/logs/kissendtest.log", "email " . var_export($email, true) . "\r\n", FILE_APPEND);
            file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/logs/kissendtest.log", "subject " . var_export($subject, true) . "\r\n", FILE_APPEND);
            file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/logs/kissendtest.log", "message " . var_export($message, true) . "\r\n", FILE_APPEND);
            file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/logs/kissendtest.log", "pdf_file " . var_export($pdf_file, true) . "\r\n", FILE_APPEND);
            file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/logs/kissendtest.log", "arFiles " . var_export($arFiles, true) . "\r\n", FILE_APPEND);
            file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/logs/kissendtest.log", "=============================================\r\n", FILE_APPEND);

            return true;
        }

        $mail = new PHPMailer\PHPMailer\PHPMailer(true);

        $stringData = "Данные: ID: $id, Сущность: $entity";
        try {
            $mail->SMTPDebug = 0;
            $mail->isSMTP();
            $mail->CharSet = "utf-8";
            $mail->Timeout = 15;
            $mail->Host = mail_hostname_smtp;
            $mail->SMTPAuth = smtp_auth;
            $mail->Username = mail_email;
            $mail->Password = mail_password;
			$mail->SMTPKeepAlive = true;
            $mail->Port = mail_port;
            $mail->SMTPSecure = true;
            $mail->SMTPAutoTLS = true;
            $mail->SMTPOptions = array(
                'ssl' => array(
                    'verify_peer'  => false,
                    'verify_peer_name'  => false,
                    'allow_self_signed' => true));
            $mail->setFrom(mail_email, 'Found');
            $mail->addAddress(sed_email, '');


            if (is_file($pdf_file . '.sig') && file_exists($pdf_file. '.sig')) {
                $mail->addAttachment($pdf_file. '.sig', "Основной файл.pdf.sig");
            }
            if (is_file($pdf_file) && file_exists($pdf_file)) {
                $mail->addAttachment($pdf_file, "Основной файл.pdf");
            }

            $filesForSign = [
                'APPLICATION_FL' => 'application_fl',
                'FILE_ANKET' => 'application_fl',
                'FILE_PDN' => 'consent',
                'CONSENT' => 'consent',
                'TAX_RESIDENT' => 'tax_resident_npo',
                'FAMILIARIZATION_SHEET' => 'familiarization_sheet',
                'KID' => 'kid',
            ];

            if (!empty($pathFullFile) && file_exists($pathFullFile)) {
                $pathFullFile = is_file($pathFullFile . '.sig') ? $pathFullFile . '.sig' : $pathFullFile;
                $mail->addAttachment($pathFullFile, "Объединенный файл.pdf.sig");
            }

			$files = [];
            foreach ($arFiles as $name => $path) {

                if (is_string($path)) {
                    $path_parts = pathinfo($path);
                    if (isset($filesForSign[$name])) {
                        if (is_file($path.'.sig')) {
                            $path = $path.'.sig';
                            $path_parts['extension'] = $path_parts['extension'].'.sig';
                        }
                    }
                    //$path = is_file($path.'.sig') ? $path.'.sig' : $path;
                    $mail->addAttachment($path, ((isset($this->docName[$name])) ? $this->docName[$name] : $name) . '.' . $path_parts['extension']);
					$files[] = $path;
                }
                if (is_array($path)) {
                    foreach ($path as $k => $alue) {
                        $path_parts = pathinfo($alue);
                        if (isset($filesForSign[$name])) {
                            if (is_file($alue.'.sig')) {
                                $alue = $alue.'.sig';
                                $path_parts['extension'] = $path_parts['extension'].'.sig';
                            }
                        }
                        //$alue = is_file($alue.'.sig') ? $alue.'.sig' : $alue;
                        $mail->addAttachment($alue, ((isset($this->docName[$name])) ? $this->docName[$name] : $name) . ' № ' . ($k + 1) . '.' . $path_parts['extension']);
	                    $files[] = $path;
                    }
                }
            }

			$filesString = implode(', ', $files);
			file_put_contents(
				$_SERVER['DOCUMENT_ROOT'] . "/logs/kissend.log",
				date("Y-m-d H:i:s", time()) . " отправка документов $filesString\r\n\r\n$id\r\n$entity\r\n",
				FILE_APPEND,
			);

            $mail->isHTML(true);
            $mail->Subject = $subject;
            $mail->Body = $message;
            if (!$mail->send()) {
                (new LogJ)->formMessage("Ошибка отправки в КИС СЭД. 
                   " . $stringData, [
                    "FILE" => __FILE__,
                    "LINE" => __LINE__,
                ], 'error', 'KIS_SED_SEND');
                return false;
            }
            (new LogJ)->formMessage("Успешная отправка в КИС СЭД. 
                   " . $stringData, [
                "FILE" => __FILE__,
                "LINE" => __LINE__,
            ], 'info', 'KIS_SED_SEND');
            return true;
        } catch (Exception $e) {
            (new LogJ)->formMessage("Ошибка отправки в КИС СЭД. 
                   " . $e->getMessage() . $stringData, [
                "FILE" => __FILE__,
                "LINE" => __LINE__,
            ], 'error', 'KIS_SED_SEND');
            return false;
        }
    }

    public function log($data)
    {
        file_put_contents($_SERVER['DOCUMENT_ROOT'] . "/logs/kissendtest.log", "message " . var_export($data, true) . "\r\n", FILE_APPEND);
    }

}