<?
include_once(_DIR_EXT.'/aspmo_server/c_services_server.php') ;
class c_services_poll_server extends c_services_server
{
    public $log_fname='kz_trace' ;

	function check_access(&$data)
	{
		ob_start();
		$terminal_id = $data['args']['id']['terminal'];
		$this->terminal_id = $terminal_id;
		$propusk_id = $data['args']['id']['user'];
		$result = array();
		$rec_member = array();
		$xmpp_message = array();
		$view_mo_in_monitor = 1; //  echo "LS_setting_monitor_view_only_success=".$GLOBALS['LS_setting_monitor_view_only_success'] ;
		// получаем инфу по терминалу
		$rec_terminal = ESMO()->get_terminal_by_id($terminal_id,array('check_reboot' => 1));
		$this->rec_terminal = $rec_terminal;
		if ($rec_terminal['pkey'])
		{
			$group_setting = unserialize(execSQL_value('select settings from obj_site_account where pkey="' . $rec_terminal['parent'] . '"'));
			$timezone = ($group_setting['timezone'])? $group_setting['timezone']:_DEFAULT_TIMEZONE;
			date_default_timezone_set($timezone);
		}
		$terminal_name = $rec_terminal['obj_name'];
		// проверяем, что пропуск активен - поулчаем ифнорамцию по работнику
		if ($propusk_id)
		{
			$options_whois = array('only_enabled' => 1,'dop_usl' => 'enabled=1');
			if (strpos($propusk_id,'#')!==false) $rec_member = PERSONAL()->whois_personal($propusk_id,$options_whois); // QR код будет сгенерирован на основе ВУ и номера авто
			else                                 $rec_member = PERSONAL()->get_personal(array('propusk' => $propusk_id,'tab_number' => $propusk_id),array('only_enabled' => 1,'set_rules' => 1,'set_QR_code' => $GLOBALS['LS_person_field_to_qrcode'],'dop_usl' => 'enabled=1'));
			$this->personal_id = $rec_member['pkey'];
		}
		$result['date'] = date('Y-m-d H:i:s');
		$result['args']['terminal_type'] = $rec_terminal['terminal_type'];
		$result['args']['id']['terminal'] = $terminal_id;
		$result['args']['id']['user'] = $rec_member['propusk'];
		$result['args']['data']['timeout'] = $GLOBALS['LS_setting_term_mess_view']*1000; // таймаут для выведенного сообщения в миллисекундах
		$result['args']['data']['hide_poll_on_tonometer'] = ($GLOBALS['LS_poll_view_on_tonometer'])? 0:1;
		$result['args']['data']['timeout_mo'] = $GLOBALS['LS_setting_mo_timeout'];
		//damp_array($rec_member,1,-1) ;
		$personal_id = $rec_member['pkey'];

		// дергаем событие check_access_success
		// но при МО это событие дергается через обрабочик
		// соответственно, все что связано с обработкой данных по POLL
		// должно происходить в обработчиках, независимо от  того, с какого терминала (МТ или КЗ) идет вызов POLL
        // событие успешного прохода check_access, отправляем массив
         $session_info=array('session_id'=>$this->session_id,
                             'terminal_id'=>$rec_terminal['id'],
                             'terminal_pkey'=>$rec_terminal['pkey'],
                             'terminal_type'=>$rec_terminal['terminal_type'],
                             'personal_id'=>$rec_member['pkey'],
                             'group_id'=>$rec_terminal['parent'],
                             'reader'=>$data['args']['id']['reader'],
                             'personal_demo_access'=>$rec_member['demo_access'],
                             'content_view'=>array('after_auth'=>'','during_systolic'=>'','before_sign'=>'')
                            ) ;

		//POLL()->on_event_check_access_success($session_info,$result) ;
        ENGINE()->on_event_by_pointer('server_check_access_success',$session_info,$result) ;
		$this->session_id=$result['args']['data']['poll'] ;
        //LOG_JSON('mo_session')->reg('session_id',$this->session_id);
		//LOG_JSON('mo_session')->reg('args_data_poll',$result['args']['data']['poll']);


		// сохранем фото на диск
		$img_info = POLL()->get_mo_img_dir_by_id($this->session_id,'','auth.jpg',array('check_directory'=>1,'no_check_exist_file' => 1));
		if ($data['args']['photo']['auth']) $this->save_send_photo($data['args']['photo']['auth'],$img_info['relative']);


		if ($rec_terminal['pkey'] and $personal_id and $result['args']['data']['poll'])
		{
			$result['args']['data']['user_name'] = ($GLOBALS['LS_hide_lastname_on_term'])? ENGINE()->hide_last_name($rec_member['obj_name']):$rec_member['obj_name'];
			// если сотрудник без фото - сохраняем фото в карточке персонала
			if (!$rec_member['_image_name'] and $data['args']['photo']['auth'] and file_exists($img_info['dir']))
			{  PERSONAL()->personal_upload_image($rec_member['pkey'],$img_info['dir'],array('fname'=>'img_auth_'.$rec_member['pkey'],'source_action'=>'Загрузка фото при авторизации')) ;
			}
			$rec_member['mo_info']['poll_id'] = $this->session_id;
			$rec_member['mo_info']['mo_reffer'] = $this->mo_reffer;
			$rec_member['mo_info']['terminal_id'] = $this->terminal_id;
			$rec_member['mo_info']['terminal_name'] = $rec_terminal['obj_name'];
			$rec_member['mo_info']['group_id'] = $rec_terminal['parent'];
			$rec_member['mo_info']['group_name'] = $rec_terminal['_group_name'];
			// проверяем допуск персонала
			//ESMO()->check_personal_access($rec_member,array('cur_mo_session_id' => $this->session_id)); // помещает информацию по допуску  в массив [__check]

			//LOG_JSON('mo_session')->reg('args_data_poll',$result['args']['data']['poll']);


			// проверяем, подлежит ли сотрудник контролю знаний
            //POLL()->on_event_check_access_success($rec_member,$result) ;
			//
			if ($result['args']['data']['poll']) // сотрудник подлежит
			{
				$result['args']['id']['medexam'] = $this->session_id;
				$result['args']['message'] = 'success';
				$result['args']['data']['user_name'] = $rec_member['obj_name'];
				$img_cont = (file_exists($rec_member['_image_dir']))? base64_encode(file_get_contents($rec_member['_image_dir'])):'';
				$result['args']['data']['photo'] = $img_cont;
				if ($GLOBALS['LS_send_qrcode_img_to_term'] and $rec_member['_qrcode_source']) $result['args']['data']['photo'] = $rec_member['_qrcode_source'];
				if ($GLOBALS['LS_send_photo_person_to_term'])
				{
					$result['args']['data']['authorized_photo'] = $img_cont;
					$result['args']['data']['authorized_photo_checksum'] = md5($img_cont);
				}
				$result['args']['data']['question'] = 0;  // задать ли вопрос о состоянии здоровья. Если параметр не указан, то значение задается по умолчанию 1
				$result['args']['data']['video'] = $GLOBALS['LS_setting_save_video'];  // вести ли видео запись. Если параметр не указан, то значение задается по умолчанию 1
				$result['args']['data']['select_exam_type'] = 0;

				// событие успешного прохода check_access, отправляем массив
                //ENGINE()->on_event_by_pointer('server_check_access_success',$rec_member,$result) ;


			}
			else // допуск к МО запрещен
			{
				$result['args']['message'] = 'failure';
				// формируем текст, который будет выводиться на дисплей терминала
				$denited_info = (_sizeof($rec_member['__check_comment']))? implode('<br>',$rec_member['__check_comment']):'';
				if (!$denited_info) $denited_info = $_SESSION['ARR_mo_failed_status'][$rec_member['__reason']];
				$result['args']['data']['reason'] = $denited_info; // свободный текст уведомления на дисплей
				// формируем текст уведомления на монитор дежурного врача
				$monitor_info = ($denited_info)? $denited_info:$_SESSION['ARR_mo_failed_status'][$rec_member['__reason']];
				$xmpp_message['notife'] = 'error';
				$xmpp_message['notife_text'] = $terminal_name . ', ' . $rec_member['obj_name'] . ':' . $monitor_info;
				// формируем поля записи по МО
				$mo_data = array();
				$mo_data['status'] = 4;
				$mo_data['comment'] = ($rec_member['__reason'])? '':$denited_info;
				$mo_data['reason'] = $rec_member['__reason'];
				$mo_data['message_terminal'] = 'failure';
				POLL()->update_poll_session($this->session_id,$mo_data);
				if ($rec_member['__go_doctor']) $result['args']['data']['reason'] = 'Для продолжения МО пройдите к врачу';
				elseif ($rec_member['__go_other_terminal']) $result['args']['data']['reason'] .= ' Для начала МО подойдите к другому терминалу';
				elseif ($rec_member['__check']['SeansDubl']) $result['args']['data']['reason'] .= ' ';
				elseif (isset($rec_member['__pause'])) $result['args']['data']['period'] = $rec_member['__pause'];   // количество минут, через которое следует подойти
				else                                          $result['args']['data']['period'] = $GLOBALS['LS_setting_auto_mo_interval'];   // количество минут, через которое следует подойти
				if ($result['args']['data']['period']) $result['args']['data']['reason'] .= ' Пожалуйста, подойдите через ' . $result['args']['data']['period'] . ' минут<br>';
				// сохраняем в логе
				ob_start();
				echo 'Авторизация - <span class=red>' . $denited_info . '</span>';
				?><h3>Флаги проверок</h3><?
				damp_array($rec_member['__check'],1,-1);
				?><h3>Комментарии проверок</h3><?
				damp_array($rec_member['__check_comment'],1,-1);
				$text = ob_get_clean();
				LOG_JSON('mo_session')->reg('check_access',$text);
				if ($GLOBALS['LS_setting_monitor_view_only_success']) $view_mo_in_monitor = 0;
			}
		}
		// пользватель не авторизован или нет доктора
		else
		{
			$reason = '';
			$log_text = '';
			$result['args']['message'] = 'failure';
			//$result['args']['data']['period']=$GLOBALS['LS_setting_auto_mo_interval']  ;   // количество минут, через которое следует подойти
			$result['args']['data']['period'] = 0;
			$result['args']['data']['user_name'] = 'Сотрудник';
			if (!$rec_terminal['pkey'])
			{  // сообщение для терминала
				$result['args']['data']['reason'] = 'Терминал не зарегистрирован ';   // свободный текст уведомления на дисплей
				// сообщение для лога
				$log_text = 'Обращение к серверу с незарегистрированного терминала';
				// описание ошибки для записи в сессию МО
				$reason = 'unknownTerminal';
			}
			else if (!$personal_id)
			{   // сообщение для терминала
				$result['args']['data']['reason'] = 'Идентификация не проведена, пожалуйста, обратитесь к врачу!';   // свободный текст уведомления на дисплей
				// сообщение для лога
				$log_text = 'Пропуск "' . $propusk_id . '" не найден или заблокирован';
				// описание ошибки для записи в сессию МО
				$reason = 'noAutorize';
				// сообщение для оператора
				$xmpp_message['notife'] = 'error';
				$xmpp_message['notife_text'] = 'Терминал ' . $terminal_name . ': Идентификация не проведена, сотрудник направлен к фельдшеру.';
			}
			else if (!$result['args']['data']['poll'])
			{

			}

			// сохраняем результат и ставим status 4 - осмотр не проводился
			$mo_data = array();
			$mo_data['status'] = 4;
			$mo_data['comment'] = $log_text;
			$mo_data['reason'] = $reason;
			$mo_data['message_terminal'] = 'failure';
			//POLL()->update_poll_session($this->session_id,$mo_data);
			// сохраняем в логе
			LOG_JSON('mo_session')->reg('check_access',$log_text);
			if ($GLOBALS['LS_setting_monitor_view_only_success']) $view_mo_in_monitor = 0;
		}
		// отправляем данные для уведомления и обновления таблицы
		// данные необходимо отправить всем АРМ текущей рабочей группы, кто имеет право получать уведомления
		//$xmpp_message['terminal_status'][$rec_terminal['id']] = 3; //ESMO()->prepare_terminal_status_to_xmpp($rec_terminal['parent']) ; //  подгатавливаем массив информации по всем терминалам текущей группы
		//$xmpp_message['time'] = date('d.m.y H:i:s'); //  подгатавливаем массив информации по всем терминалам текущей группы
		//$xmpp_message['from'] = 'c_server::check_access';
		//if ($view_mo_in_monitor) $xmpp_message['mo_tr_id'] = $this->session_id;;
		//if ($view_mo_in_monitor) $xmpp_message['mo_tr'] = ESMO()->get_mo_session_view_table_tr($this->session_id,["img_path_relative" => true]);
		//IO()->send_async_cmd('send_xmpp_mess',array('terminal_id'=>$terminal_id,'params'=>serialize($xmpp_message))) ;
		//if ($rec_terminal['pkey']) ESMO()->reg_monitor_mess($rec_terminal['parent'],$xmpp_message);
		$text = ob_get_clean();
		//if ($text) $result['args']['data']['reason'].=$text ;
		if ($text) $result['args']['data']['debug'] = $text;
		return ($result);
	}

	var $arr_mo_reason; // массив текстовые кодов ошибок с МО

	function examination_result(&$data)
	{   LOG_JSON('mo_session')->reg('examination_result','start');
	   	$result = array();
		$xmpp_message = array();
		ob_start();
		$terminal_type = $data['args']['terminal_type'];
		$terminal_id = $data['args']['id']['terminal'];
		$this->terminal_id = $terminal_id;
		$propusk_id = $data['args']['id']['user'];
        $this->session_id = $data['args']['id']['medexam']; // id сессии МО
		$rec_poll = POLL()->get_poll_by_id($this->session_id,array('no_public_info' => 1));

		// формируем ответ
		$result['date'] = date('Y-m-d H:i:s');
		$result['args']['terminal_type'] = 'mt';
		$result['args']['id']['terminal'] = $terminal_id;
		$result['args']['id']['user'] = $propusk_id;
		$result['args']['data']['timeout'] = $GLOBALS['LS_setting_term_mess_view']*1000; // таймаут для выведенного сообщения в миллисекундах
		$result['args']['data']['timeout_mo'] = $GLOBALS['LS_setting_mo_timeout'];
		$rec_terminal = ESMO()->get_terminal_by_id($terminal_id,array('check_reboot' => 1));
		set_time_point('get_terminal_by_id');
		$this->rec_terminal = $rec_terminal;
		if ($rec_terminal['pkey'])
		{
			$group_setting = unserialize(execSQL_value('select settings from obj_site_account where pkey="' . $rec_terminal['parent'] . '"'));
			$timezone = ($group_setting['timezone'])? $group_setting['timezone']:_DEFAULT_TIMEZONE;
			date_default_timezone_set($timezone);
		}
		// проверяем, что пропуск активен - поулчаем ифнорамцию по работнику.
		$rec_member = PERSONAL()->get_personal_by_id($rec_poll['personal_id']);   //set_time_point('get_personal_by_propusk') ;
		$this->personal_id = $rec_member['pkey'];
		$personal_id = $rec_member['pkey'];
		// новый вариант - через указатели
		ENGINE()->on_event_by_pointer('examination_result_data_read',$data,$rec_member,$rec_poll);

		// сохраняем данные измерений в запись МО
		$data_mo = array('e_data' => time(),
                         'reason' => $data['args']['data']['reason'],
                         'equipment' => $data['args']['data']['equipment'],
                         'video' => $data['args']['photo']['video']
                        );
		if ($data['args']['data']['reason']) $this->arr_mo_reason[] = $data['args']['data']['reason'];
		POLL()->update_poll_session($this->session_id,$data_mo);
		set_time_point('update_mo_session');
		// сохраняем фото начала МО
		//$img_dir = ESMO()->get_mo_img_dir_by_id($this->session_id,'relative','alco.jpg',array('check_directory' => 1,'no_check_exist_file' => 1));
		//if ($data['args']['photo']['alco']) $this->save_send_photo($data['args']['photo']['alco'],'/public/mo_photo/'.$this->session_id.'_alco.jpg') ;
		//if ($data['args']['photo']['alco']) $this->save_send_photo($data['args']['photo']['alco'],$img_dir);
		if ($personal_id)
		{  // независимо от reason присланного терминалом, надо оценить результаты измерений
			$arr_result = array();
			// внимание!!! в $arr_result будут собраны результаты только тех измерений, которые поддерживает терминал
			// это важно, так как в ESMO()->get_mo_result_to_personal не будут оцениваться те измерения,
			// которые хотя и есть в правиле МО но нет в результатах от терминала
			//$rules_info = ESMO_RULES()->get_mo_rules_to_personal($rec_member,array('terminal_id' => $terminal_id,'esmo_group' => $rec_terminal['parent']));
			//$mo_result = ESMO_RULES()->get_mo_result_to_personal($rules_info['_rules'],$arr_result,array('tk' => $rec_poll['tk']));

			// если осмотр был успешный
			if ($data['args']['message']=='success')
			{   $mo_result['status']=2 ;
				$access = ($mo_result['status']==2)? 1:0; // 2 = МО пройден, 3 - МО не пройден
				$comment = $mo_result['comment'];
				// сохраняем данные измерений в запись МО
				POLL()->update_poll_session($this->session_id,$mo_result); // id записи по проведению МО
				set_time_point('update_mo_session');
				// $data['args']['data']['intrusion']=1 если не удалось распознать лицо
				// допуск автоматом в этом случае не дается
				if ($access)
				{	$result['args']['message'] = 'success';
					$result['args']['data']['reason'] = 'Опрос пройден';
					// сохраняем в логе
					LOG_JSON('mo_session')->reg('Окончание сеанса контроля знаний','Пройден');
					// отправляем событие МО пройден успешно
                    // mo_passed_success используется только в модуле WO, временно отключаем
					//ENGINE()->on_event('mo_passed_success',array('poll_id' => $this->session_id,'this' => $this));

                    // событие успешного прихода examination_result, отправляем массив
                    $session_info=array('session_id'=>$this->session_id,
                                        'terminal_type'=>$rec_terminal['terminal_type'],
                                        'personal_id'=>$rec_member['pkey'],
		                                'personal_name'=>$rec_member['obj_name'],
                                        ) ;
                    ENGINE()->on_event_by_pointer('server_examination_result_success',$session_info,$data);
					//
					if ($this->reason) $result['args']['data']['reason'] = $this->reason;


				}
				else
				{   $mo_result['status']=3 ;
					$result['args']['message'] = 'failure';
					if ($GLOBALS['LS_setting_mo_failed_mess_detailed']) $result['args']['data']['reason'] = $comment;
					else                                                 $result['args']['data']['reason'] = 'Опрос не пройден';
					LOG_JSON('mo_session')->reg('Окончание опроса','Не пройден');
					set_time_point('reg_log');
				}
			}
			// failure – выход по таймауту
			else if ($data['args']['data']['reason']=='cancelTimeout')
			{
				$comment = 'Превышено время отведенное на проведение опроса';
				$mo_result['error'] = 4;
				$mo_result['status'] = 3;
				POLL()->update_poll_session($this->session_id,$mo_result); // id записи по проведению МО
				// сообщение для оператора
				$xmpp_message['notife'] = 'error';
				$xmpp_message['notife_text'] = 'Терминал ' . $terminal_id . ', ' . $rec_member['obj_name'] . ': ' . $comment;
				// сохраняем в логе
				LOG_JSON('mo_session')->reg('Окончание МО по таймауту',$comment,array('terminal_id' => $terminal_id,'member_id' => $rec_member['pkey'],'poll_id' => $this->session_id));
				$result['args']['message'] = 'failure';
				$result['args']['data']['reason'] = $comment;
			}
			else //failure – МО окончен, отказ в доступе(причина указывается в параметре args.data.reason)
			{ // ключевые поля для разспознования ощибки
				// args.data.reason
				// args.data.equipment
				// сохраняем данные измерений в запись МО
				$reason = $data['args']['data']['reason'];
				$device = $data['args']['data']['equipment'];
				$status = 3;
				$comment = $_SESSION['ARR_mo_failed_status'][$reason];
				if ($device) $comment .= ', ' . $_SESSION['ARR_mo_failed_dev'][$device];
				$reason_text = $comment; // $reason - текст для вывода на экране терминала
				// не удалось провести измерение
				if ($reason=='equipmentError')  // неисправность устройства => сообщение клиенту занять другой терминал, терминал в перезагрузку, check_status, режим неисправности
				{
					$reason_text .= (ESMO()->get_allow_view_button_hand_check_in_mo_tr($rec_poll))? ' Пожалуйста, обратитесь врачу для проведения проверки':' Подойдите для повторного МО через ' . $GLOBALS['LS_setting_auto_mo_interval'] . ' минут.';
				}
				// неисправность устройства
				if ($reason=='equipmentFailure')  // неисправность устройства => сообщение клиенту занять другой терминал, терминал в перезагрузку, check_status, режим неисправности
				{
					$reason_text = 'Оборудование неисправно (' . $_SESSION['ARR_mo_failed_dev'][$device] . '). Пройдите проверку на другом терминале.';
					// оправлем терминалу команду проверить статус, асинхронно
					if ($GLOBALS['LS_term_send_reboot_by_dev_error']) DEVICE()->device_send_async_cmd($this->rec_terminal['pkey'],'reboot',array('pause' => 5));
					$status = 4;
				}
				// обновляем статус сессии - МО пройден с ошибкой
				//$mo_result['error']=4 ;
				$mo_result['status'] = $status;
				POLL()->update_poll_session($this->session_id,$mo_result);
				$result['args']['message'] = 'failure';
				$result['args']['data']['reason'] = $reason_text;
				// сообщение для оператора
				$xmpp_message['notife'] = 'error';
				$xmpp_message['notife_text'] = 'Терминал ' . $terminal_id . ', ' . $rec_member['obj_name'] . ':  опрос не пройден: ' . $comment;
				// сохраняем в логе
				LOG_JSON('mo_session')->reg('Окончание опрос','Не пройден');
			}

			if ($data['args']['data']['intrusion']==1)
			{
				$this->arr_mo_reason[] = 'intrusion';
				$xmpp_message['notife'] = 'error';
				$xmpp_message['notife_text'] = 'Терминал ' . $terminal_id . ', ' . $rec_member['obj_name'] . ': требуется подтверждение личности';
				$result['args']['data']['reason'] = 'Вам необходимо обратиться к врачу для подтверждения личности';
			}

            if (_sizeof($this->arr_mo_reason))
			{
				POLL()->update_poll_session($this->session_id,array('reason' => implode(' ',$this->arr_mo_reason)));
				LOG_JSON('mo_session')->reg('update_mo_session','',array('data' => $this->arr_mo_reason));
			}
			// отправляем данные для уведомления и обновления таблицы
			// данные необходимо отправить либо владельцу терминала, либо всем сотрудникам АСПМО, кто имеет право получать уведомления
			//$xmpp_message['mo_tr_id'] = $this->session_id;;
			//$xmpp_message['mo_tr'] = ESMO()->get_mo_session_view_table_tr($this->session_id,["img_path_relative" => true,'show_button_dopusk' => 1]);
			//$xmpp_message['terminal_status'][$rec_terminal['id']] = 2; // статус терминала 2 - готов к работе
			//$xmpp_message['time'] = date('d.m.y H:i:s'); //  подгатавливаем массив информации по всем терминалам текущей группы
			//$xmpp_message['from'] = 'c_server::examination_result';
			//ESMO()->reg_monitor_mess($rec_terminal['parent'],$xmpp_message);
		}
		//damp_array($xmpp_message,1,-1) ;
		$text = ob_get_clean();
		set_time_point('ob_get_clean');
		$result['args']['data']['debug'] = $text;
		//$result['args']['data']['DTW_res'] = $DTW_res['cost'];
		//$result['args']['data']['PP_count'] = $pp_count;
		//$result['args']['data']['MinMOToAutoSetNorma'] = $GLOBALS['LS_pp_MinMOToAutoSetNorma'];
		//$result['args']['data']['has_pp_norm'] = $has_pp_norm;
		// инициируем событие
		ENGINE()->on_event('examination_result',array('poll_id' => $this->session_id));
		return ($result);
	}

}

?>
