<?php
include_once(_DIR_EXT.'/aspmo_server/c_services_server.php') ;
class c_page_server extends c_services_server
{ public $terminal_id ;
  public $personal_id ;
  public $mo_id ;
  public $seans_id ;
  public $mo_reffer ;
  public $rec_terminal ;
  public $is_log_request=1 ;
  public $JSON_source='' ;
  public $result_stream='output' ;
  public $data_in=array() ;
  public $data_out=array() ;
  public $operation=array() ;
  public $reason='' ;
  public $request_UID='' ;
  public $log_fname='mo_trace' ;
  public $autonom_mo = 0;

  function check_access(&$data)
  {  $group_setting=array() ;
    ob_start() ;
    $terminal_id=$data['args']['id']['terminal'] ;  $this->terminal_id=$terminal_id ;   $doctor_id=0 ;
    $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_groups'=>1,'set_QR_code'=>$GLOBALS['LS_person_field_to_qrcode'],'dop_usl'=>'enabled=1')) ;
      $this->personal_id=$rec_member['pkey'] ;
    }
    // проверяем активность врача - в группе должен быть один текущий врач
    if ($rec_terminal['pkey']) $doctor_id=ESMO()->check_doctor($rec_terminal['parent']) ; // помещает информацию по допуску  в массив [__check]

    $result['date'] = date('Y-m-d H:i:s');
    $result['args']['terminal_type']='mt' ;
    $result['args']['id']['terminal']=$terminal_id ;
    $result['args']['id']['user']=$rec_member['propusk'] ;
    // если не было whois - возвращаем текст приветствия
    if ($GLOBALS['LS_hello_enabled'] and $data['args']['id']['reader']!='number') $result['args']['data']['greetings']=ESMO()->get_greetings_for_terminal($rec_member) ;
    $result['args']['data']['timeout']=$GLOBALS['LS_setting_term_mess_view']*1000  ; // таймаут для выведенного сообщения в миллисекундах
    $result['args']['data']['hide_quiz_on_tonometer'] = ($GLOBALS['LS_quiz_view_on_tonometer'])? 0:1;
    $result['args']['data']['timeout_mo']=$GLOBALS['LS_setting_mo_timeout'] ;
    //damp_array($rec_member,1,-1) ;
    $member_id=$rec_member['pkey'] ;

    // получаем правила МО, соответствующие текущему пользователю. В пользователе уже есть запись [_rules]
    $rules_info=ESMO_RULES()->get_mo_rules_to_personal($rec_member,array('terminal_id'=>$terminal_id,'esmo_group'=>$rec_terminal['parent'])) ;
    $rules=_sizeof($rules_info['_rules'])? $rules_info['_rules']:array() ;

    // формируем запист по сесси МО с учетом реального оборудования, которые подключено к терминалу
      $res_session=array( 'terminal_id' =>$terminal_id,
                          'terminal_pkey' =>$rec_terminal['pkey'],
                          'member_id'   =>$member_id,
                          'group_id'   =>$rec_terminal['parent'],
                          'tonometer'    =>(($rules['s'] or $rules['d']) and $rec_terminal['_profil']['tonometer'])? 1:0,
                          'pulsometer'   =>($rules['p'] and $rec_terminal['_profil']['tonometer'])? 1:0, // давление и пульс измеряются одним прибором
                          'thermometer'  =>($rules['t'] and $rec_terminal['_profil']['thermometer'])? 1:0,
                          'alcotester'   =>($rules['a'] and $rec_terminal['_profil']['alcotester'])? 1:0,
                          'pupilometer'  =>($rules['n'] and $rec_terminal['_profil']['pupilometer'])? 1:0,
                          'message_terminal'=>'success',
                          //'reader'=>$data['args']['id']['reader'],
                          'vcheck'       =>($rules['v'])? 1:0
                         );

      if (!$GLOBALS['LS_mo_no_use_def_doctor']) $res_session['doctor_id']=$doctor_id ;
      // если для группы имеется настройка по нужному типу МО - проставляем его сразу
      if ($group_setting['mo_type']) $res_session['tk']=$group_setting['mo_type']-1 ;

      $this->session_id=ESMO()->open_mo_session($res_session) ; // id записи по проведению МО ;
      $this->mo_reffer=$this->session_id.'.'._DOT('obj_site_mo_session')->pkey ;

      // сохранем фото на диск
	  $img_info=ESMO()->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'],'/public/mo_photo/'.$this->session_id.'_auth.jpg') ;
      if ($data['args']['photo']['auth']) $this->save_send_photo($data['args']['photo']['auth'],$img_info['relative']) ;

    // для начала МО нужен доктор
    if ($rec_terminal['pkey'] and $member_id and ($doctor_id or $rec_member['demo_access']))
    {   $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'])
         { if (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']['mo_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]

        // проверяем, соответствует ли набор оборудования терминала правилам прохождения МО. Возможно, надо будет мерять температуру, а термометр на терминале не работает
        if ($rec_member['__check']['result'])
        {  if (!$rec_member['demo_access']) ESMO()->check_terminal_to_used($rec_member,$rules,$rec_terminal) ; // помещает информацию по допуску  в массив [__check], комментарии в '__check_comment'
           else $rec_member['__check']['access_terminal']=1 ; // демо-сотрудников допускаем к любому терминалу, даже если он не обеспечивает всех необходимых проверко
        }

        ESMO()->update_mo_session($this->session_id,array('message_terminal'=>'success',
                                                     'terminal_comment'=>mb_substr($rec_member['__terminal_comment'],0,240))) ;

       // если сотрудник допущен к МО
       if ($rec_member['__check']['result'] /* or $rec_terminal['virt']*/)
       {
         $result['args']['id']['medexam']=(string) $this->session_id ; // числовой тип medexam не работает со старыми версиями терминала (6.12.3 и более ранние): при измерении ПП фатал еррор при сохранении файла
         $result['args']['message']='success' ;
         $result['args']['comment']=$rec_member['__terminal_comment'] ;
         $result['args']['data']['user_name']=$rec_member['obj_name'] ;

         if ($rec_member['_image_dir'])
         { $img_cont=(file_exists($rec_member['_image_dir']))? base64_encode(file_get_contents($rec_member['_image_dir'])):'' ;
           $result['args']['data']['photo']=($GLOBALS['LS_send_qrcode_img_to_term'] and $rec_member['_qrcode_source'])? $rec_member['_qrcode_source']:$img_cont ;
         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']=1 ;  // задать ли вопрос о состоянии здоровья. Если параметр не указан, то значение задается по умолчанию 1
         $result['args']['data']['video']=$GLOBALS['LS_setting_save_video'] ;  // вести ли видео запись. Если параметр не указан, то значение задается по умолчанию 1
         $result['args']['data']['tonometer']=$res_session['tonometer'] ; ;  // будем ли мерить давление. Если параметр не указан, то значение задается по умолчанию 0
         $result['args']['data']['pulse']=$res_session['pulsometer'] ;  // будем ли замерять пульс. Если параметр не указан, то значение задается по умолчанию 0
         $result['args']['data']['thermometer']=$res_session['thermometer'] ;   // будем ли мерить температуру. Если параметр не указан, то значение задается по умолчанию 1
         $result['args']['data']['alcotester']=$res_session['alcotester'] ;   // будем ли замерять уровень алкогольных паров. Если параметр не указан, то значение задается по умолчанию 1
         $result['args']['data']['pupilometer']=$res_session['pupilometer'] ;   // Будем ли производить измерение реакции зрачков на свет. Если параметр не указан, то значение задается по умолчанию 1
         if ($res_session['pupilometer'])
         {  $result['args']['data']['pupilometer_args']['delay_time']=$rules['pupilometer_delay_time'] ; // Время задержки включения светодиода, мс
            $result['args']['data']['pupilometer_args']['work_time']=$rules['pupilometer_work_time'] ; // Время работы светодиода, мс
            $result['args']['data']['pupilometer_args']['recovery_time']=$rules['pupilometer_recovery_time'] ; // Время для восстановления зрачка, мс
            $result['args']['data']['pupilometer_args']['min_detected_percent']=$rules['pupilometer_min_detected_percent'] ; // Минимальный процент правильно распознанных кадров от общего числа
            $result['args']['data']['pupilometer_args']['hidden_mode']=$rules['pupilometer_hidden_mode'] ; // Режим измерений. 1-параллельно с алкотестом.
         }
         if ($res_session['tonometer'])
         {  $result['args']['data']['tonometer_args']['systolic_min']=$rules['s_min'] ; // минимальное Систолическое АД (если не указано – проверка пропускается)
            $result['args']['data']['tonometer_args']['systolic_max']=$rules['s_max'] ; // максимальное Систолическое АД (если не указано – проверка пропускается)
            $result['args']['data']['tonometer_args']['diastolic_min']=$rules['d_min'] ; // минимальное Диастолическое АД (если не указано – проверка пропускается)
            $result['args']['data']['tonometer_args']['diastolic_max']=$rules['d_max'] ; // максимальное Диастолическое АД (если не указано – проверка пропускается)
         }
         if ($res_session['thermometer'])
         {  $result['args']['data']['thermometer_args']['min_temperature']=$rules['t_min']; // минимальная температура (если не указано – проверка пропускается)
            $result['args']['data']['thermometer_args']['max_temperature']=$rules['t_max'] ; // максимальная температура (если не указано – проверка пропускается)
         }
         if ($res_session['pulsometer'])
         {  $result['args']['data']['pulse_args']['min_pulse']=$rules['p_min'] ; // минимальный пульс(если не указано – проверка пропускается)
            $result['args']['data']['pulse_args']['max_pulse']=$rules['p_max'] ; // максимальный пульс (если не указано – проверка пропускается)
         }
         // экран типа осмотра на терминале
         // если оно 0 или не пришло, экран не показывается,
         // 1 - показывает только кнопки предсменный/послесменный
         // 2 - показывает предсменный/межсменный/послесменный
         // добавлена проверка настройки группы на тип осмотра

           $terminal_version=explode('.',$rec_terminal['vers']) ;
           if ($GLOBALS['LS_select_exam_type'] and !$group_setting['mo_type'] and (int)$terminal_version[0]>=10)   $result['args']['data']['select_exam_type']=(int)$GLOBALS['LS_select_exam_type'] ;

         if ($res_session['vcheck'])
         {  $v_settings=$rules['v_settings'] ;
            $result['args']['data']['schulte']=1 ;    // - 0 не проводить тест, 1 - проводить тест (задается в критериях)
            $result['args']['data']['schulte_type']=(int)$v_settings['table'] ;  //  - 0 тест Шульте, 1 - тест Горбова-Шульте
            $result['args']['data']['schulte_size']=(int)$v_settings['size'] ;   //  размер таблицы, может принимать значение от 3 до 7, как выставлено в критериях
            $result['args']['data']['schulte_red_order']=(int)$v_settings['red'] ;  // порядок проверки для красных значений (0 - по возрастанию, 1 - по убыванию). Используется только для теста Горбова-Шульте. Для Шульте передавать значение 0
            $result['args']['data']['schulte_black_order']=(int)$v_settings['black'] ; // порядок проверки для черных значений (0 - по возрастанию, 1 - по убыванию)
            $result['args']['data']['schulte_max_errors']=(int)10 ; //$v_settings['max_errors'] ; // максимальное допустимое количество ошибок, целое число, задается в критериях
            $result['args']['data']['schulte_timeout']=(int)60 ; //$v_settings['timeout'] ; // время прохождения теста в секундах, целое число, задается в критериях
         }

         // событие успешного прохода 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'=>'')
                            ) ;
         ENGINE()->on_event_by_pointer('server_check_access_success',$session_info,$result) ;


         // сохраняем в логе
         ob_start() ;
         echo 'Авторизация - проверка разрешена' ;
         damp_array($rules,1,-1) ;
         $text=ob_get_clean() ;
	     LOG_JSON('mo_session')->reg('check_access',$text) ;
       }
       else // допуск к МО запрещен
       { $result['args']['message']='failure' ;

         if ($GLOBALS['LS_mo_success_send_ticket_to_term_DD'] and $rec_member['__check']['dopiskAllowExist']) $this->send_ticket_to_term($rec_member['__check']['id_prev_mo'],$result) ;
         //$result['args']['comment']=$rec_member['__terminal_comment'] ;


         // формируем текст, который будет выводиться на дисплей терминала
         $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' ;
         ESMO()->update_mo_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>' ;
         damp_array($rules,1,-1) ;
         ?><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 (!$member_id)
        {   // сообщение для терминала
            $result['args']['data']['reason']='Идентификация не проведена, пожалуйста, обратитесь к врачу!'  ;   // свободный текст уведомления на дисплей
            // сообщение для лога
            $log_text='Пропуск "'.$propusk_id.'" не найден или заблокирован' ;
            // описание ошибки для записи в сессию МО
            $reason='noAutorize' ;
            // сообщение для оператора
            $xmpp_message['notife']='error' ;
            $xmpp_message['notife_text']='Терминал '.$terminal_name.': Идентификация не проведена, сотрудник направлен к фельдшеру.' ;
        }
        else if (!$doctor_id and !$this->autonom_mo)
        {  // сообщение для терминала
           $result['args']['data']['reason']='Дождитесь начала смены врача'  ;   // свободный текст уведомления на дисплей
           // сообщение для лога
           $log_text='Не найдено ни одного активного доктора, переводим терминал в сон.' ;
           // оправлем терминалу команду спать через 5 секунд
	        DEVICE()->device_send_async_cmd($this->rec_terminal['pkey'],'set_sleep',array('pause'=>5)) ;
           // описание ошибки для записи в сессию МО
           $reason='noDoctor' ;
        }

        // сохраняем результат и ставим status 4 - осмотр не проводился
        $mo_data=array() ;
        $mo_data['status']=4 ;
        $mo_data['comment']=$log_text ;
        $mo_data['reason']=$reason ;
        $mo_data['message_terminal']='failure' ;
        ESMO()->update_mo_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)
    {   // временный костыль
        $reboot_termial=0 ;
        /*if ($data['args']['data']['equipment']=='pupilometer' and $data['args']['data']['reason']=='equipmentFailure' and $data['args']['message']=='failure')
        {  $data['args']['data']['equipment']='' ;
           $data['args']['data']['reason']='' ;
           $data['args']['message']='success' ;
           $reboot_termial=1 ;
        }*/

        $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_mo=ESMO()->get_mo_by_id_now($this->session_id,array('no_public_info'=>1)) ; $this->session_id=$rec_mo['pkey'] ;


        // формируем ответ
        $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_mo['member_id']) ;   //set_time_point('get_personal_by_propusk') ;
        $this->personal_id=$rec_member['pkey'] ;
        $member_id=$rec_member['pkey'] ;


        // новый вариант - через указатели
        // далее совместить события examination_result_data_read и server_examination_result_success
        ENGINE()->on_event_by_pointer('examination_result_data_read',$data,$rec_member,$rec_mo) ;

        /* все операции по PP вынесены в m_pp.php и вызываются по событию examination_result_data_read
           данные возвращаются через массив data['esmo_out']

        // сохраняем данные по Пупиллометрия в отдельную таблицу
        // вызываем функцию для обработки
        // она выдаст результа нарко теста
        $pp_code=0 ;
        if (function_exists('PP') and ($data['args']['data']['pupilometer_left'] or $data['args']['data']['pupilometer_right']))
        {
            $pp_id=PP()->create_pp_rec($this->session_id,$member_id,$data['args']['data']['pupilometer_left'],$data['args']['data']['pupilometer_right'],$data['args']['data']['pupilometer_lux'],$data['args']['data']['pupilometer_args']['left_detected_percent'],$data['args']['data']['pupilometer_args']['right_detected_percent']) ;

            PP()->increase_pp_cnt($member_id); //увеличение кол-ва ПП сотрудника

            // Считаем норму сотрудника автоматически, если пройдено нужное количество медосмотров
            $pp_count = PP()->getPPTestsCountByMemberId($member_id);
            $has_pp_norm = PP()->hasNormByMemberId($member_id);

            if ($GLOBALS['LS_pp_MinMOToAutoSetNorma'] <= $pp_count && $has_pp_norm == 0) {
                PP()->calculate_norm_auto($member_id);
            }
            // провести ЦНС, только если есть норма для сотрудника
            list($result_check_narko,$pp_code)=PP()->check_narko($pp_id,array('no_check_outer_norm'=>1)) ; // возвращает текстовое сообщение по результату расшифровки данных. Если все в порядке, вернуть пустую строку
            // только для виртуального терминала - подменяем результат  ПП на требуемый по проверке
            //if ($data['args']['data']['pupilometer_left']) $pp_code=$data['args']['data']['pupilometer_result'] ;
            // временно, пока не будет починена ПП
            //$result_check_narko='' ;
            // $pp_code='1' ;

            // сохраняем данные измерений в запись МО
            ESMO()->update_mo_session($this->session_id,array('narko'=>$result_check_narko,'res_n'=>$pp_code)) ;
        }
        else
        {
            $result_check_narko = '';
            ESMO()->update_mo_session($this->session_id,array('narko'=>$result_check_narko,'res_n'=>$pp_code)) ;
        }*/

        /* все операции по DTW вынесены в i_signature и вызываются по событию examination_result_data_read
        // распознование экранной подписи
        // более не генерим подпись на основании оцифровки
        // показываем подпись сотрудника из изходной картинки
        // на странице МО будет показана подпись другим способом
        if ($data['args']['data']['signature']['image'])
        {   //  почему до сих пор сохраняется в директорию mo_photo???
	        $img_dir=ESMO()->get_mo_img_dir_by_id($this->session_id,'relative','DTW.png',array('check_directory'=>1,'no_check_exist_file'=>1)) ;
            //$this->save_send_photo($data['args']['data']['signature']['image'],'/public/mo_photo/'.$this->session_id.'_DTW.png') ;
            $this->save_send_photo($data['args']['data']['signature']['image'],$img_dir) ;

        }

        if ($data['args']['data']['signature']['data'])
        {  $sign_id=signature()->mo_session_save_DTW($this->session_id,$data['args']['data']['signature']['data']);
           $DTW_res = signature()->check_sign($this->personal_id, $data['args']['data']['signature']['data']) ;
        }
        */

        // если задано значение минимальной температуры и производиться замер температуры и значение замера меньше чем минимальное - ставим минимальное значение
        if ($rec_mo['thermometer'] and $GLOBALS['LS_esmo_check_thermometr_error'])
        {  $arr_logs=array() ;
           $value_term=(float)$data['args']['data']['thermometer'] ;
           $rec_crit=reset(_IL('IL_dg')->recs) ;
           if ($GLOBALS['LS_min_termometr_value'])
           { $value_min=(float)$GLOBALS['LS_min_termometr_value'] ;
             if ($value_term<=$value_min)
             { $arr_logs['LS_min_termometr_value']=$GLOBALS['LS_min_termometr_value'] ;
               $arr_logs['args_data_thermometer_before']=$data['args']['data']['thermometer'] ;
               $arr_logs['krit']=$rec_crit['t_min'].' ... '.$rec_crit['t_max'] ;
               $data['args']['data']['thermometer']=rand($rec_crit['t_min']*10,$rec_crit['t_max']*10)/10 ;
               $arr_logs['args_data_thermometer_after']=$data['args']['data']['thermometer'] ;
             }
           }
           if ($GLOBALS['LS_max_termometr_value'])
           { $value_max=(float)$GLOBALS['LS_max_termometr_value'] ;
             if ($value_term>=$value_max)
             {  $arr_logs['LS_max_termometr_value']=$GLOBALS['LS_max_termometr_value'] ;
                $arr_logs['args_data_thermometer_before']=$data['args']['data']['thermometer'] ;
                $arr_logs['krit']=$rec_crit['t_min'].' ... '.$rec_crit['t_max'] ;
                $data['args']['data']['thermometer']=rand($rec_crit['t_min']*10,$rec_crit['t_max']*10)/10 ;
                $arr_logs['args_data_thermometer_after']=$data['args']['data']['thermometer'] ;
             }
           }
           if (_sizeof($arr_logs)) LOG_JSON('mo_session')->reg('check_therm_value','',array('data'=>$arr_logs,'mo_id'=>$this->session_id)) ;
        }

        //При получении любого значения в alcotester_value>0 выставляем флаг alcotester=1 в результатах терминала
        if (isset($data['args']['data']['alcotester_value']) and (float)$data['args']['data']['alcotester_value']>0) $data['args']['data']['alcotester']=1 ;

        // сохраняем данные измерений в запись МО
        $data_mo=array(   'e_data'=>time(),
                          'systolic'=>($data['args']['data']['tonometer_systolic'])? $data['args']['data']['tonometer_systolic']:0,
                          'diastolic'=>($data['args']['data']['tonometer_diastolic'])? $data['args']['data']['tonometer_diastolic']:0,
                          'temperature'=>($data['args']['data']['thermometer'])? $data['args']['data']['thermometer']:0,
                          'pulse'=>($data['args']['data']['pulse'])? $data['args']['data']['pulse']:0,
                          'alko'=>($data['args']['data']['alcotester'])? $data['args']['data']['alcotester']:0,
                          'question'=>($data['args']['data']['question'])? $data['args']['data']['question']:0,
                           // все операции по PP вынесены в m_pp.php и вызываются по событию examination_result_data_read
                          //'narko'=>$result_check_narko,
                          // все операции по DTW вынесены в i_signature и вызываются по событию examination_result_data_read
                          //'DTW_sign_result' => (isset($DTW_res) && isset($DTW_res['cost'])) ? $DTW_res['cost'] : 100,
                          //'DTW_res' => (isset($DTW_res) && $DTW_res['valid']) ? "1" : "0",
                          //'signature_DTW_mp_Cost' => (isset($DTW_res['signature_DTW_mp_Cost'])) ? $DTW_res['signature_DTW_mp_Cost'] : "0",
                          //'signature_DTW_mp_Sum' => (isset($DTW_res['signature_DTW_mp_Sum'])) ? $DTW_res['signature_DTW_mp_Sum'] : "0",
                          //'signature_DTW_mp_Transform' => (isset($DTW_res['signature_DTW_mp_Transform'])) ? $DTW_res['signature_DTW_mp_Transform'] : "0",
                          //'signature_DTW_mp_StepCount' => (isset($DTW_res['signature_DTW_mp_StepCount'])) ? $DTW_res['signature_DTW_mp_StepCount'] :  "0",
                          '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'] ;

        if (isset($data['args']['data']['alcotester_value'])) $data_mo['alko_value']=$data['args']['data']['alcotester_value'] ;
        if (isset($data['args']['data']['thermometer']) and $rec_mo['pupilometer']) $data_mo['thermometer']=1 ;  // если пришла температура и есть путилометр, выставляем флаг, что было измерение температуры
        // 1 - предсменный
        // 2 - послесменный
        // 3 - межсменны
        if (isset($data['args']['exam_type']) and $data['args']['exam_type']<=3) { $data_mo['tk']=$data['args']['exam_type']-1 ; $rec_mo['tk']=$data_mo['tk'] ; }
        if (isset($data['args']['exam_type']) and $data['args']['exam_type']>3) { $data_mo['tk']=$data['args']['exam_type']-4 ; $rec_mo['tk']=$data_mo['tk'] ; }
        if (isset($data['args']['data']['schulte_time']) and $rec_mo['vcheck'])   $data_mo['v_time']=$data['args']['data']['schulte_time'] ;
        if (isset($data['args']['data']['schulte_errors']) and $rec_mo['vcheck']) $data_mo['v_errors']=$data['args']['data']['schulte_errors'] ;

        ESMO()->update_mo_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 ($member_id)
        {  // независимо от reason присланного терминалом, надо оценить результаты измерений
           $arr_result=array() ;
           if ($rec_terminal['tonometer'])   $arr_result['s']=$data['args']['data']['tonometer_systolic'] ;
           if ($rec_terminal['tonometer'])   $arr_result['d']=$data['args']['data']['tonometer_diastolic'] ;
           if ($rec_terminal['tonometer'])   $arr_result['p']=$data['args']['data']['pulse'] ;
           if ($rec_terminal['thermometer']) $arr_result['t']=$data['args']['data']['thermometer'] ;
           if ($rec_terminal['alcotester'])  $arr_result['a']=$data['args']['data']['alcotester'] ;
           if ($rec_terminal['pupilometer']) $arr_result['t']=$data['args']['data']['thermometer'] ;  // температура, измерененная пурилометром   ??? перекрывает температуту, измеренную термометром????
           if ($rec_terminal['pupilometer']) { $arr_result['n']=$data['esmo_out']['pp_code'] ;
                                               $arr_result['n_text']=$data['esmo_out']['result_check_narko'] ;
                                             }
                                             $arr_result['q']=$data['args']['data']['question'] ;
           if ($rec_mo['vcheck'])            $arr_result['v']=array('time'=>$data['args']['data']['schulte_time'],
                                                                    'errors'=>$data['args']['data']['schulte_errors'],
                                                                    );

           // внимание!!! в $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'])) ;
           if ($this->autonom_mo) { $mo_result['status'] = 2; }
           else { $mo_result=ESMO_RULES()->get_mo_result_to_personal($rules_info['_rules'],$arr_result,array('tk'=>$rec_mo['tk']))  ; }
           $check_max_DD_check_after_setting_model=0 ;
           // если осмотр был успешный
           if ($data['args']['message']=='success'
               or ($data['args']['message']=='failure' and $data['args']['data']['question']==1 and $data['args']['data']['reason']=='negativeResponse')
               // при включенном контроле ошибок термометра игнорируем неисправность термометра
               or ($data['args']['message']=='failure' and $GLOBALS['LS_esmo_check_thermometr_error'] and $data['args']['data']['reason']=='equipmentFailure' and $data['args']['data']['equipment']=='thermometer')
              )
           {
               $access=($mo_result['status']==2)? 1:0 ; // 2 = МО пройден, 3 - МО не пройден
               if ($data['args']['data']['question']==1 and $data['args']['data']['reason']=='negativeResponse')
               { $access=0 ;
                 $mo_result['status']=3 ;
               }
               $comment=$mo_result['comment'] ;
               set_time_point('get_mo_result_to_personal') ;
               // сохраняем данные измерений в запись МО
               ESMO()->update_mo_session($this->session_id,$mo_result) ; // id записи по проведению МО

               set_time_point('update_mo_session') ;

	           // допуск автоматом в этом случае не дается
               $check_by_face=1 ; // по умолчнию проверка по лицу выключена = пройдена
               if ($GLOBALS['LS_mo_auth_by_photo'] and $data['args']['data']['intrusion']) $check_by_face=0 ; // $data['args']['data']['intrusion']=1 если не удалось распознать лицо
               if ($GLOBALS['LS_setting_auto_dopuck']==1 and $access and $check_by_face)
               { ESMO()->update_mo_session($this->session_id,array('dopusk'=>1,'dopusk_time'=>time(),'dopusk_time_end'=>time()+$rec_member['_dopusk_time_S'])) ;
                  set_time_point('update_mo_session[auto_dopusk]') ;
                  LOG_JSON('mo_session')->reg('Автодопуск сотрудника') ;
                  set_time_point('reg_log') ;
               }

               if ($GLOBALS['LS_setting_auto_nedopusk']==1 and !$access and $mo_result['res_a']!=2  and $rec_mo['mo1_id'])
               {  $dopusk_time=time();
                  $dopusk_time_end=time()+$rec_member['_nedopusk_time_S'] ;
                  ESMO()->update_mo_session($this->session_id,array('dopusk'=>2,'dopusk_time'=>$dopusk_time,'dopusk_time_end'=>$dopusk_time_end)) ;
                  set_time_point('update_mo_session[auto_nedopusk]') ;
                  LOG_JSON('mo_session')->reg('Автонедопуск сотрудника') ;
                  set_time_point('reg_log') ;

                   $check_max_DD_check_after_setting_model=1 ;


               }

               if ($access) { $result['args']['message']='success' ;
                              $result['args']['data']['reason']='МО пройден' ;

                              if ($GLOBALS['LS_hello_enabled'])
                              { $arr=explode(' ',$rec_member['obj_name']) ;
                                $io=$arr[1].' '.$arr[2] ; // имя отчество
                                if ($rec_mo['tk']==0 or $rec_mo['tk']==2) $result['args']['data']['reason'].='<br>'.$GLOBALS['LS_goodbye_text1'].', '.$io ;
                                else                                      $result['args']['data']['reason'].='<br>'.$GLOBALS['LS_goodbye_text2'].', '.$io ;
                              }

                              // сообщение для оператора
                              //$xmpp_message['notife']='info' ;
                              //$xmpp_message['notife_text']='Терминал '.$terminal_id.', '.$rec_member['obj_name'].':  медосмотр пройден' ;
                              // сохраняем в логе
                              LOG_JSON('mo_session')->reg('Окончание медосмотра','Пройден') ;
                              set_time_point('reg_log') ;

                              // отправляем событие МО пройден успешно
                              // mo_passed_success используется только в модуле WO, временно отключаем
	                          //ENGINE()->on_event('mo_passed_success',array('mo_id'=>$this->session_id,'this'=>$this)) ;
	                          //
	                          if ($this->reason) $result['args']['data']['reason']=$this->reason ;

                              if ($GLOBALS['LS_mo_success_send_ticket_to_term']) $this->send_ticket_to_term($this->session_id,$result) ;
                            }
               else         { $result['args']['message']='failure' ;
                              if ($GLOBALS['LS_setting_mo_failed_mess_detailed']) $result['args']['data']['reason']=$comment ;
                              else                                                 $result['args']['data']['reason']='Медосмотр не пройден' ;
                              //  в случае первого МО и не алкоголь или ПП - приглашение пройти МО позже
                              if ($mo_result['res_a']<=1 and $mo_result['res_s']<=1 and $mo_result['res_d']<=1 and $mo_result['res_p']<=1 and $mo_result['res_t']<=1 and $mo_result['res_n']>=2) // все параметры в норм кроме ПП
                              //if ($mo_result['res_n']>=2) // все параметры в норм кроме ПП
                                  $result['args']['data']['reason'].='. Подойдите к врачу для прохожения МО' ;
                              elseif ($rec_mo['mo_type']==1 and $mo_result['res_a']!=2 and $mo_result['res_n']!=2 and !$data['args']['data']['question'])
                                     $result['args']['data']['reason'].='. Подойдите для повторного МО через '.$GLOBALS['LS_setting_auto_mo_interval'].' минут.' ;
                              else   $result['args']['data']['reason'].='. Подойдите к врачу для прохожения МО' ;

                              // сообщение для оператора
                              $xmpp_message['notife']='error' ;
                              $xmpp_message['notife_text']='Терминал '.$terminal_id.', '.$rec_member['obj_name'].':  медосмотр не пройден' ;
                              // сохраняем в логе
                              LOG_JSON('mo_session')->reg('Окончание медосмотра','Не пройден') ;
                              set_time_point('reg_log') ;
                            }


               // событие успешного прихода 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) ;

           }
           // failure – выход по таймауту
           else if ($data['args']['data']['reason']=='cancelTimeout')
           {  $comment='Превышено время отведенное на проведение МО' ;
              $mo_result['error']=4 ;
              $mo_result['status']=3 ;
              ESMO()->update_mo_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'],'mo_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_mo))? ' Пожалуйста, обратитесь врачу для проведения проверки':' Подойдите для повторного МО через '.$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 ;

             ESMO()->update_mo_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' ;
              if ($GLOBALS['LS_mo_auth_by_photo'])
              { $xmpp_message['notife']='error' ;
              $xmpp_message['notife_text']='Терминал '.$terminal_id.', '.$rec_member['obj_name'].': требуется подтверждение личности' ;
	          $result['args']['data']['reason']='Вам необходимо обратиться к врачу для подтверждения личности' ;
            }
            }


           // вычисляем и сохраняем модель  прохождения МО
           ESMO()->set_model_to_session_mo($this->session_id) ;
           set_time_point('set_model_to_session_mo') ;

           if ($check_max_DD_check_after_setting_model and $GLOBALS['LS_setting_max_DD_check'])  ESMO()->check_count_DD_to_personal($rec_member['pkey']) ;


	        if (_sizeof($this->arr_mo_reason))
            { ESMO()->update_mo_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' ;

            //IO()->send_async_cmd('send_xmpp_mess',array('terminal_id'=>$terminal_id,'params'=>serialize($xmpp_message))) ;
            ESMO()->reg_monitor_mess($rec_terminal['parent'],$xmpp_message) ;


            // перегружаем терминал если был ошибка пупилометра
            //if ($reboot_termial) DEVICE()->terminal_send_async_cmd($terminal_id,'reboot',array('pause'=>5)) ;

            //set_time_point('send_async_cmd') ;
        }
        //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('mo_id'=>$this->session_id)) ;

       return($result) ;
    }



}
?>
