<?php
$__functions['init'][]='_aspmo_site_vars' ;
$__functions['boot_site'][]='_aspmo_site_boot' ;

include_once('i_esmo_rules.php') ;
function ESMO_RULES(){ $esmo_rules=new esmo_rules();return($esmo_rules);}
function ESMO() {
  if (isset($_SESSION['aspmo_system'])){
    return($_SESSION['aspmo_system']);
  } else {
    $_SESSION['aspmo_system']=new c_aspmo_system();
    return($_SESSION['aspmo_system']);
  }
}

function _aspmo_site_vars()
{
   // ВНИМАНИЕ! При добавлении новых статусов откр
   $_SESSION['ARR_status_sess']=array(0=>'',
                                      1=>'Осмотр начат',
                                      2=>'Осмотр окончен, полож.',
                                      3=>'Осмотр окончен, отриц.',
                                      4=>'Осмотр прерван'
                                      ) ;

   $_SESSION['ARR_model_osmotr']=array(1=>'МО1+',
                                        2=> 'МО1-',
                                        3=> 'МО1-МО2+',
                                        4=> 'МО1-МО2-',
                                        5=> 'МО1-МО2-РМВ+',
                                        6=> 'МО1-МО2-РМВ-',
                                        7=> 'МО1-РМВ+',
                                        8=> 'МО1-РМВ-',
                                        9=> 'РМВ+',
                                        10=>'РМВ-'
                                       ) ;

   $_SESSION['ARR_mo_type']=array      (1=>'МО1',   // первый подход
                                        2=>'МО2',   // второй подход
                                        3=>'РМВ'    // проверка на РМВ
                                       ) ;

   $_SESSION['ARR_mo_tk_type']=array   (0=>'предсменный',
                                        1=>'послесменный',
                                        2=>'межсменный'
                                       ) ;

   $_SESSION['ARR_doc_napravlenie_type']=array   (0=>'Стандартный',
                                                  1=>'Казахстан'
                                                  ) ;

   $_SESSION['ARR_doc_napravlenie_title']=array     (0=>'Направление по АГ', //для стандартного типа
                                                    1=>'Направление' //для казахстана
                                                    ) ;

   $_SESSION['ARR_doc_spravka_type']=array   (0=>'Стандартный',
                                                   1=>'Казахстан'
                                                   ) ;

   $_SESSION['ARR_doc_napravlenie_narko_type']=array   (0=>'Стандартный',
                                                   1=>'Казахстан'
                                                   ) ;

    $_SESSION['ARR_doc_protokol_trezvosti_type']=array   (0=>'Стандартный',
                                                          3=>'Стандартный с измененным заключением',
                                                          1=>'Расширенный',
                                                          2=>'307/у-05'
                                                          ) ;

   $_SESSION['ARR_mo_failed_status']=array() ;
   $_SESSION['ARR_mo_failed_status'][0]='Неизвестная ошибка' ;
   $_SESSION['ARR_mo_failed_status']['negativeResponse']='Отрицательный ответ на вопрос о состоянии здоровья' ;
   $_SESSION['ARR_mo_failed_status']['equipmentError']='Не удалось провести измерение' ;
   $_SESSION['ARR_mo_failed_status']['equipmentFailure']='Неисправность устройства' ;
   $_SESSION['ARR_mo_failed_status']['negativeResult']='Негативный результат устройства' ;
   $_SESSION['ARR_mo_failed_status']['cancelButton']='Отмена измерения' ;
   $_SESSION['ARR_mo_failed_status']['cancelTimeout']='Превышено время отведенное на проведение МО' ;
   $_SESSION['ARR_mo_failed_status']['work_order_not_found']='Отсутствует наряд на работы' ;
   $_SESSION['ARR_mo_failed_status']['workOrderNotFound']='Отсутствует наряд на работы' ;
   $_SESSION['ARR_mo_failed_status']['intrusion']='Требуется подтверждение личности' ;
   // собственные коды ошибок
   $_SESSION['ARR_mo_failed_status']['noDoctor']='Нет дежурного врача' ;
   $_SESSION['ARR_mo_failed_status']['noAutorize']='Ошибка авторизации' ;
   $_SESSION['ARR_mo_failed_status']['alcoExist']='Был алкоголь в прошлых проверках' ;
   $_SESSION['ARR_mo_failed_status']['EEexist']='Более двух неудачных попыток пройти МО' ;
   $_SESSION['ARR_mo_failed_status']['failedMO']='Более двух неудачных попыток пройти МО' ;
   $_SESSION['ARR_mo_failed_status']['dopiskSessionDenited']='Более двух неудачных сессий МО' ;
   $_SESSION['ARR_mo_failed_status']['minIntAfterCheck']='Не выдержан минимальный интервал между проверками' ;
   $_SESSION['ARR_mo_failed_status']['minIntAfterDopusk']='Допуск уже получен' ;
   $_SESSION['ARR_mo_failed_status']['dopiskAllowExist']='Допуск уже получен' ;
   $_SESSION['ARR_mo_failed_status']['dopiskDenitedExist']='Допуск уже запрещен' ;
   $_SESSION['ARR_mo_failed_status']['negativeResponseExist']='Ранее жалоба на здоровье' ;
   $_SESSION['ARR_mo_failed_status']['denitedExist']='Допуск был аннулирован ранее' ;
   $_SESSION['ARR_mo_failed_status']['nonRule']='Не удалось определить критерии оценки' ;
   $_SESSION['ARR_mo_failed_status']['unknownTerminal']='Терминал не зарегистрирован в системе' ;
   $_SESSION['ARR_mo_failed_status']['SeansDubl']='Сеанс МО начат на другом терминале' ;


    $_SESSION['ARR_mo_failed_dev']=array() ;
    $_SESSION['ARR_mo_failed_dev']['tonometer']='тонометр при замере давления' ;
    $_SESSION['ARR_mo_failed_dev']['thermometer']='термометр' ;
    $_SESSION['ARR_mo_failed_dev']['pulse']='тонометр при замере пульса' ;
    $_SESSION['ARR_mo_failed_dev']['alcotester']='алкотестер' ;
    $_SESSION['ARR_mo_failed_dev']['pupilometer']='пупиллометр' ;

   $_SESSION['ARR_status_dopusk']=array(
                                      1=>'Разрешен',
                                      2=>'Запрещен',
                                      3=>'Уклонился'
                                      ) ;

   $_SESSION['ARR_status_uklonist']=array(
                                      2=>'Запрещен',
                                      3=>'Уклонился'
                                      ) ;

   $_SESSION['ARR_terminal_status']=array(0=>'Выключен',
                                          1=>'Сон',
                                          2=>'Готов к работе',
                                          3=>'Идут измерения',
                                          4=>'check_status',
                                          5=>'reboot',
                                          6=>'требуется дезинфекция',
                                          8=>'Нет связи',
                                          9=>'Неисправен'
                                      ) ;
   $_SESSION['ARR_terminal_status_color']=array(0=>'Выключен',
                                          1=>'Сон',
                                          2=>'<span class=green>Готов к работе</span>',
                                          3=>'<span class=yellow>Идут измерения</span>',
                                          4=>'check_status',
                                          5=>'reboot',
                                          6=>'<span class=red_label>требуется дезинфекция</span>',
                                          8=>'<span class=red>Нет связи</span>',
                                          9=>'<span class=red>Неисправен</span>'
                                      ) ;
   $_SESSION['ARR_MO_error']=array(0=>'МО прошел успешно',
                                   1=>'',
                                   2=>'Идентификация не проведена',
                                   3=>'Нет дежурного врача',
                                   4=>'Превышено время отведенное на проведение МО',
                                   5=>''
                                   ) ;

    $_SESSION['ARR_mo_push_format']=array(1=>'JSON',
                                         2=>'XML',
                                       ) ;



    $_SESSION['ARR_terminal_tk_select']=array(0=>'Нет выбора',
                                              1=>'предсменный/послесменный',
                                              2=>'предсменный/межсменный/послесменный',
                                              6=>'Предрейсовый/Послерейсовый',
                                            ) ;

    $_SESSION['arr_terminal_printer_type']=array(0=>'POS',
                                                 1=>'Наклейка');

    $_SESSION['ARR_mo_hand_check_by_mo']=array(0=>'Не показывать',
                                            1=>'МО1',
                                            2=>'МО2',
    ) ;


}

function _aspmo_site_boot($options)
{
  create_system_modul_obj('aspmo',$options) ;
}


class c_aspmo_system  extends c_system
{
   public $list_device ;
   public $cancel_message ;
   public $id_section_device ;

   public $host ;
   public $list_operator_id ;

   public $table_account ;
   public $table_mo_sessions ;
   public $table_mo_sessions_now ;
   public $view_mo_session ;
   public $view_mo_session_now ;
   public $smena_time ;
   public $smena_by_hour ;
   public $smena_interval ;

    public $ARR_mo_tk_type=array(0=>'предсменный',
                                    1=>'послесменный',
                                    2=>'межсменный',
                                    3=>'предрейсовый',
                                    4=>'послерейсовый',
                                    5=>'межрейсовый',
                                    ) ;

     public $ARR_mo_tk_type_term=array(1=>'предрейсовый', //'предсменный',
                                2=>'послерейсовый', //'послесменный',
                                3=>'межрейсовый', //'межсменный',
                                4=>'предрейсовый',
                                5=>'послерейсовый',
                                6=>'межрейсовый',
                                ) ;

    public $arr_terminal_printer_type=array(0=>'POS',
                                            1=>'Наклейка');


   function __construct($create_options=array())
   { $this->table_name ='obj_'.SITE_CODE.'_mo_session' ;
     parent::__construct($create_options) ;
     //$this->pages_info=array() ;

     $_SESSION['TM_account']='obj_site_account' ; $GLOBALS['TM_account']=$_SESSION['TM_account'] ;

     $this->table_account='obj_site_account' ;
     $this->table_mo_sessions='obj_site_mo_session' ;
     $this->table_mo_sessions_now=($GLOBALS['LS_mo_now_enabled'])? 'obj_site_mo_session_now':'obj_site_mo_session' ;
     $this->view_mo_session ='view_mo_session' ;
     $this->view_mo_session_now =($GLOBALS['LS_mo_now_enabled'])? 'view_mo_session_now':'view_mo_session' ;

     $this->smena_time = array('1'=>array('from'=>6,'to'=>14),
                               '2'=>array('from'=>14,'to'=>22),
                               '3'=>array('from'=>22,'to'=>6)
                              ) ;


       $this->smena_by_hour=$this->get_smena_by_hour($this->smena_time) ; // составляем список смен по часам
     $this->smena_interval=$this->get_smena_interval($this->smena_time) ; // составляем длительность смен

     //регистрируем отчеты
     $this->system_title ='Медицинские осмотры';

     ENGINE()->reg_ext('aspmo','ЭСМО') ;
     ENGINE()->reg_ext('aspmo_mo','МО') ;
     ENGINE()->reg_ext('aspmo_rmv','РМВ') ;

     ENGINE()->reg_ext('esmo_setting','Настройки ЭСМО') ;
     ENGINE()->reg_ext('aspmo_monitor','Монитор МО') ;

     //временно тут, пока reg_ext не будет перенесено в инсталятор
       ENGINE()->reg_ext('esmo_master','РМР') ;
       ENGINE()->reg_ext('esmo_gateway','Шлюз интеграции') ;

     set_time_point('Создание объекта <strong>aspmo_system</strong>') ;
     //parent::c_system($create_options) ;
     //unset($this->pages_info) ;

   }


    //С терминала приходят значения 1,2,3,4,5,6
    //    В БД храниться в виде двух значений
    //- tk:   0,1,2
    //- tkm:  0,1

   // id - значение c терминала [1,2,3,4,5,6]
   // tk - id типа МО для БД [0,1,2]
   // tkm - id признака водителя для БД [0,1]
   function convert_id_to_tk_tkm($id)
   {   $tk=0  ; $tkm=0 ;
       switch($id)
         { case 1: $tk=0 ; $tkm=0 ; break ;
           case 2: $tk=1 ; $tkm=0 ; break ;
           case 3: $tk=2 ; $tkm=0 ; break ;
           case 4: $tk=0 ; $tkm=1 ; break ;
           case 5: $tk=1 ; $tkm=1 ; break ;
           case 6: $tk=2 ; $tkm=1 ; break ;
        }
       return([$tk,$tkm]) ;
   }

   // tk - id типа МО для БД [0,1,2]
   // tkm - id признака водителя для БД [0,1]
  // возвращает значение от 1..6
  // id - значение c терминала [1,2,3,4,5,6]
   function convert_tk_tkm_to_id($tk,$tkm=0)
   { $id=($tk+$tkm*3)+1 ;
     return($id) ;
   }

   // функция возращается название типа МО для записи по МО в БД
   // $tk - [0,1,2] - тип МО
   // $tkm - [0,1] - признак водителя
   // если стоит признак $tkm, по МО должны иметь типы 0=>'предрейсовый',1=>'послерейсовый',2=>'межрейсовый'
   // если $tkm=0, то МО должны иметь типы   0=>'предсменный', 1=>'послесменный' 2=>'межсменный',
	function get_mo_tk_type($tk,$tkm=0)
    {   $id=$this->convert_tk_tkm_to_id($tk,$tkm) ; // id=[1....6]
        $value=$this->ARR_mo_tk_type_term[$id] ;
        return($value) ;
        // проверка сотрудника на вьювер водителя более не нужна, так как данные поступают из МО, а в нем уже в поле tkm зафиксирован признак "водитель"
        /*
        if ($GLOBALS['LS_personal_use_drivers_group_for_tk_name'] and $GLOBALS['LS_drivers_viewer_name'] and $personal_id)
        {
          $in_group_drivers=execSQL_value('select pkey from '.$GLOBALS['LS_drivers_viewer_name'].' where pkey='.$personal_id) ;
          if ($in_group_drivers) $value=$this->ARR_mo_tk_type_for_driver[$tk] ;
        }
        */

    }

    // функция возвращает название типа МО для фильтра в отчете
    function get_filter_tk_type($id)
    {
      $value=$this->ARR_mo_tk_type_term[$id] ;
      return($value) ;
    }

    function declare_menu_items_1($page)
        {
            $page->menu['/cab/rmv/[cur_smena]/']=array('title'=>'РМВ',
                                               'allow_access_to_rol'=>2,
                                               'class'=>'fa fa-user-md',
                                               'items'=>array('/cab/rmv/[cur_smena]/'=>'Рабочее место врача',
                                                              '/cab/rmv/mo/'=>'Провести вручную',
                                                              '/cab/rmv/terminals/'=>array('title'=>'Терминалы','class'=>'fa fa-users',
                                                                                     /* 'items'=>array('/'=>array('title'=>'Усыпить все терминалы','cmd'=>'aspmo/all_term_sleep'),
                                                                                                     '//'=>array('title'=>'Разбудить все терминалы','cmd'=>'aspmo/all_term_start')
                                                                                      ) */

                                                              ),
                                                              '/cab/rmv/report_mo/[cur_smena]/'=>'Журнал МО'
                                               )
                                              ) ;
        }

        function declare_menu_items_4($page)
        {   $page->menu['/cab/setting/']['items']['/cab/esmo_setting/mo/']['title']='Медицинские осмотры' ;
            $page->menu['/cab/setting/']['items']['/cab/esmo_setting/mo/']['items']['/cab/esmo_setting/mo/']='Проведение МО' ;
            $page->menu['/cab/setting/']['items']['/cab/esmo_setting/mo/']['items']['/cab/esmo_setting/groups/']='Группы сотрудников' ;
            $page->menu['/cab/setting/']['items']['/cab/esmo_setting/mo/']['items']['/cab/esmo_setting/groups_of_disease/']='Группы по болезни' ;
            $page->menu['/cab/setting/']['items']['/cab/esmo_setting/mo/']['items']['/cab/esmo_setting/rules/']='Критерии осмотра' ;
            $page->menu['/cab/setting/']['items']['/cab/esmo_setting/mo/']['items']['/cab/esmo_setting/diagnoz/']='Признаки ЗиПР' ;
            $page->menu['/cab/setting/']['items']['/cab/esmo_setting/mo/']['items']['/cab/esmo_setting/arhive/']='Архив данных' ;
            $page->menu['/cab/setting/']['items']['/cab/setting/members/']['items']['/cab/esmo_setting/terminal/']='Терминалы' ;
            $page->menu['/cab/setting/']['items']['/cab/setting/members/']['items']['/cab/esmo_setting/terminal/profile/']='Профили терминалов' ;
            $page->menu['/cab/setting/']['items']['/cab/setting/members/']['items']['/cab/setting/devices/']='Устройства' ;
            $page->menu['/cab/setting/']['items']['/cab/setting/members/']['items']['/cab/esmo_setting/ssl_check/']='Проверка SSL' ;
            $page->menu['/cab/setting/']['items']['/cab/setting/members/']['items']['/cab/esmo_setting/trassir/']='Trassir' ;
            $page->menu['/cab/setting/']['items']['/cab/medical_organizations/']['title']='Справочник мед.организаций' ;

        }


        function declare_menu_items_5($page)
        {
            //$page->menu['/cab/esmo_master/stats/[org_ids=(7106)]/']=array('title'=>'Статистика','class'=>'fa _fa-desktop') ;
            //$page->menu['/cab/esmo_master/master/']=array('title'=>'Мастер','class'=>'fa _fa-desktop') ;
            $page->menu['/cab/monitor/']=array('title'=>'МОНИТОРИНГ','class'=>'fa fa-desktop','id'=>'show_window_monitor','window_title'=>'MO_MONITOR') ;
        }


  //==========================================================================================================================================================================
  // ТЕРМИНАЛЫ
  //==========================================================================================================================================================================

   function terminal_save($terminal_pkey,$rec,$options=array())
    {  DEVICE()->terminal_save($terminal_pkey,$rec,$options) ;
    }

    function terminal_create($form_data)
      { //if (!isset($form_data['rol']))  return(array('error'=>'rol_not_set')) ;
        //if (!$form_data['login'])  $form_data['login']=safe_text_to_url($form_data['name']) ;
        //if ($form_data['rol']==6) $data['parent']=_CLIENT_GROUP_ID ; // клиентов в отдельную папку
        //if (!$form_data['parent'])  $form_data['parent']=MEMBER()->cur_group_id ;

        $id_exist=execSQL_value('select pkey from obj_site_account where id="'.$form_data['id'].'" and clss=203') ;
        if ($id_exist)  return(array('error'=>'Терминал с данным ID уже зарегистрирован в системе')) ;

        $id_exist=execSQL_value('select pkey from obj_site_account where ip="'.$form_data['ip'].'" and clss=203') ;
        if ($id_exist)  return(array('error'=>'Терминал с данным IP уже зарегистрирован в системе')) ;

        $data=array() ;
        $data['clss']=203 ;
        $data['parent']=$form_data['group_id'] ;
        $data['obj_name']=$form_data['name'] ;
        $data['id']=$form_data['id'] ;
        $data['ip']=$form_data['ip'] ;
        $data['profil']=$form_data['profil'] ;
        $data['enabled']=isset($form_data['enabled'])? $form_data['enabled']:1;
        $data['terminal_type']=isset($form_data['terminal_type'])? $form_data['terminal_type']:'mt';

        $id=adding_rec_to_table('obj_site_account',$data,array('debug'=>0)) ;
        $result['info']='Терминал успешно добавлен, ID='.$id ;
        $result['pkey']=$id ;
        $result['id']=$data['id'] ;
        $result['reffer']=$id.'.'.ACCOUNTS()->tkey ;
        LOGS()->reg_log('Конфигурация ЭСМО','Добавление терминала "'.$form_data['name'].'" ['.$form_data['id'].'/'.$form_data['ip'].'] в группу '.ACCOUNTS()->get_group_name($form_data['group_id']),array('reffers'=>array($result['reffer']))) ;
        return($result) ;
      }

   function prepare_terminal_status_to_xmpp($group_id)
   {
     $arr=array() ;
     $recs=execSQL_row('select id,status from obj_site_account where parent="'.$group_id.'" and clss=203 and enabled=1') ;
     return($recs) ;

   }

   function get_list_terminals($group_id=0,$type='',$usl='')
   { if (!$group_id) $group_id=MEMBER()->cur_group_id ;

     $usl_group=($group_id>0)? ' and t1.parent in ('.ACCOUNTS()->tree[$group_id]->get_list_child().') ':'' ;
     $usl_type=($type)? ' and t1.terminal_type="'.$type.'"':'' ;
     $dop_usl=($usl)? ' and '.$usl.' ':'' ;
       $recs=execSQL('select t1.*,t2.obj_name as _group_name 
                      from obj_site_account t1 
                      left join obj_site_account t2 on t2.pkey=t1.parent
                      where t1.clss=203 and t1.enabled=1 and t1.id>0 '.$usl_type.$usl_group.$dop_usl.' 
                      order by t1.parent,t1.id') ;
       if (_sizeof($recs)) foreach($recs as $id=>$rec) $this->prepare_public_info_to_terminal($recs[$id]) ;

     return($recs) ;
   }

   function get_list_disabled_terminals($type='',$usl='')
   { $usl_type=' and t1.terminal_type="'.$type.'" ' ;
     $dop_usl=($usl)? ' and '.$usl.' ':'' ;
     $recs=execSQL('select t1.*,t2.obj_name as _group_name 
                      from obj_site_account t1 
                      left join obj_site_account t2 on t2.pkey=t1.parent
                      where t1.clss=203 and t1.enabled=0 '.$usl_type.$dop_usl.' 
                      order by t1.parent,t1.id') ;
     if (_sizeof($recs)) foreach($recs as $id=>$rec) $this->prepare_public_info_to_terminal($recs[$id]) ;

     return($recs) ;
   }

   function get_terminals_ids($group_id)
   { $ids=array() ;
     if (isset(ACCOUNTS()->tree[$group_id]))
     {   $child_ids=ACCOUNTS()->tree[$group_id]->get_list_child() ;
         $recs=execSQL_line('select id from obj_site_account where parent in ('.$child_ids.') and clss=203 and enabled=1 order by id') ;
         if (_sizeof($recs)) $ids=implode(',',$recs) ;  else $ids='' ;
     }
     return($ids) ;
   }

    function get_available_terminal_firmware() {
        $recs=execSQL('
          select * from obj_site_terminal_firmware as a
          order by pkey') ;
        return($recs) ;
    }

   // получение информации по прсоналу АСПМО
   function get_terminal_by_id($id,$options=array())
   { $rec=execSQL_van('select * from obj_site_account where id="'.$id.'" and clss=203',$options) ;
     if ($rec['pkey'])
     {   if ($options['check_reboot'] and $rec['reboot'])
         { reboot_engine() ;
           execSQL_update('update '.$this->table_account.' set reboot=0 where pkey='.$rec['pkey']) ;
         }
         $this->prepare_public_info_to_terminal($rec,$options) ;
     }
     return($rec);
   }

   // получение информации по прсоналу АСПМО
   function get_terminal_by_pkey($id,$options=array())
   { $usl_enabled=($options['include_diabled'])? '':' and enabled=1'   ;
     $rec=execSQL_van('select * from obj_site_account where pkey="'.$id.'" and clss=203 '.$usl_enabled,$options) ;
     if ($rec['pkey']) $this->prepare_public_info_to_terminal($rec,$options) ;
     return($rec);
   }

   function prepare_public_info_to_terminal(&$rec,$options=array())
   {  // переносим информацию из профиля в запись по терминалу
      if ($options['debug']){?><h2>Профиль терминала:</h2><? damp_array(_IL('IL_term_prof')->recs[$rec['profil']],1,-1) ;}
      $rec['_profil']['video']      =_IL('IL_term_prof')->recs[$rec['profil']]['video'] ;
      $rec['_profil']['tonometer']  =_IL('IL_term_prof')->recs[$rec['profil']]['tonometer'] ;
      $rec['_profil']['thermometer']=_IL('IL_term_prof')->recs[$rec['profil']]['thermometer'] ;
      $rec['_profil']['alcotester'] =_IL('IL_term_prof')->recs[$rec['profil']]['alcotester'] ;
      $rec['_profil']['pupilometer']=_IL('IL_term_prof')->recs[$rec['profil']]['pupilometer'] ;
      $rec['_profil_name']          =_IL('IL_term_prof')->recs[$rec['profil']]['obj_name'] ;
      $rec['_group_name']=ACCOUNTS()->tree[$rec['parent']]->name ;
      $rec['__href']='/window/esmo_setting/terminal/card/'.$rec['pkey'].'/' ;
      $rec['__href_virt']=($rec['virt'])? '/term/'.$rec['id'].'/':'/term/' ;
      if ($rec['ext_info']) $rec['_ext_info']=unserialize($rec['ext_info'])  ;
      if ($rec['devices']) $rec['_devices']=unserialize($rec['devices'])  ;
      if (!isset($rec['settings'])) $rec['settings']=[] ;
      if (isset($rec['settings']) and !is_array($rec['settings'])) $rec['settings']=[] ;
      $rec['settings']['remote_endpoint']='/';
      $rec['settings']['question']=1 ;
      $rec['settings']['signature']=1 ;
   }


   // получение информации по прсоналу АСПМО
   function get_terminal_by_ip($ip,$options=array())
   { $recs=execSQL('select * from obj_site_account where ip="'.$ip.'" and clss=203',0,1) ;
     if ($options['check_multipule_device'] and _sizeof($recs)>1) return(array('error'=>'Найдено несколько терминалов с данным IP')) ;
     elseif ($recs[0]['pkey'])
     {   $rec=$recs[0] ;
         if ($options['check_reboot'] and $rec['reboot'])
          { reboot_engine() ;
            execSQL_update('update '.$this->table_account.' set reboot=0 where pkey='.$rec['pkey']) ;
          }
         $this->prepare_public_info_to_terminal($rec,$options) ;
     }
     return($rec);
   }


   //==========================================================================================================================================================================
   //ПОЛУЧЕНИЕ ИНФОРМАЦИИ ПО ДОПУСКУ СОТРУДНИКА К МО
   //==========================================================================================================================================================================

   // проверяем есть ли залогиненный доктор (в текущей или вышестоящей группе) с активной сменой для текущего терминала
   // также идет проверка по IP для АРМ из текущей группы терминала
   // 29.06.17 - Исправлено
   // ищем в таблице obj_site_account запись по аккаунту, у которого активная группа $cur_group_id (иди одно из родительских для $cur_group_id) и smena=1
   //
   function check_doctor($cur_group_id,$options=array())
   { ob_start() ;
     if (isset(ACCOUNTS()->tree[$cur_group_id]))
     { // если доктор авторизован на зарегистрированном АРМ, то ищем активного доктора только в пределах текущей группы
       // иначе ищем в текущей и всех вышестоящих группах
       // сортировка по group_id desc нужна, чтобы на первом месте была фельдшер в искомой группе, а далее уже - фельднер из вышестоящей группы
       if (!$options['rol_id']) $options['rol_id']=2; //по умолчанию ищем для роли фельдшера
       $rol_name = $_SESSION['ARR_roll'][$options['rol_id']]['obj_name'];

       $group_ids=ACCOUNTS()->tree[$cur_group_id]->get_list_parent() ;
       echo 'Ищем активного <strong>"'.$rol_name.'"</strong> в группах '.$group_ids.'<br>' ;
       //execSQL('select pkey,obj_name,enabled,parent,smena,group_id from obj_site_account where pkey=202',2) ;
       $doctor_recs=execSQL('select t1.pkey,t1.obj_name,t1.group_id,t3.obj_name as group_name,t2.ip as arm_ip,t1.ip as login_ip 
                             from '.$this->table_account.' t1
                             left join  '.$this->table_account.' t2 on t2.ip=t1.ip and t2.clss=205 and t2.enabled=1 and t2.parent='.$cur_group_id.'
                             left join  '.$this->table_account.' t3 on t3.pkey=t1.group_id 
                             where t1.clss=210 and t1.enabled=1  and t1.group_id in ('.$group_ids.') and t1.smena=1 and t1.rol='.$options['rol_id'].'
                             order by t1.group_id desc,t1.pkey',2,1) ;
       //if ($options['debug'])
       { echo '<strong>Список активных "'.$rol_name.'"<br>' ; print_2x_arr($doctor_recs) ; }
       $id=$doctor_recs[0]['pkey'] ;
       // опция no_use_default_doctor нужна при опеределении активной смены аккаунта, который авторизуется
       if (!$id and $GLOBALS['LS_default_doctor_id'] and !$options['no_use_default_doctor'])
       {  $id=$GLOBALS['LS_default_doctor_id'] ;
          //if ($options['debug'])
          { echo '<strong>Не найден "'.$rol_name.'" в группе, использован "'.$rol_name.'" по умолчанию</strong><br>' ; }
       }
     }
     else
     { echo 'Группа ID='.$cur_group_id.' не найдена в модели аккаунтов<br>' ;
       echo 'Делаем перезагрузку кеша<br>' ;
       reboot_engine() ;
       if (isset(ACCOUNTS()->tree[$cur_group_id])) echo 'Группа появилась<br>' ; else echo 'Группа так и не появилась<br>' ;
     }
     $text=ob_get_clean() ;
     LOG_JSON('mo_session')->reg('check_doctor',$text) ;
     //if ($options['debug']) echo $text ;
     return($id) ;
   }

   function check_doctor_old($cur_group_id,$options=array())
   { ob_start() ;
     if (isset(ACCOUNTS()->tree[$cur_group_id]))
     { // если доктор авторизован на зарегистрированнмом АРМ, то ищем активного доктора только в пределах текущей группы
       // иначе ищем в текущей и всех вышестоящих группах
       $group_ids=($options['only_use_arm'])? $cur_group_id:ACCOUNTS()->tree[$cur_group_id]->get_list_parent() ;
       echo 'Ищем активного доктора в группах '.$group_ids.'<br>' ;
       $doctor_recs=execSQL('select t1.pkey,t1.obj_name,t2.obj_name as group_name,t2.ip as arm_ip from '.$this->table_account.' t1
                             left join  '.$this->table_account.' t2 on t2.ip=t1.ip and t2.clss=205 and t2.enabled=1 and t2.parent='.$cur_group_id.'
                             where t1.clss=210 and t1.enabled=1 and t1.parent in ('.$group_ids.') and t1.group_id='.$cur_group_id.' and t1.smena=1 
                             order by t2.ip desc,t1.pkey',$options['debug'],1) ;
       if ($options['debug']) { echo '<strong>Список активных доктров</strong><br>' ; print_2x_arr($doctor_recs) ; }
       $id=$doctor_recs[0]['pkey'] ;
       if (!$id and $GLOBALS['LS_default_doctor_id'])
       {  $id=$GLOBALS['LS_default_doctor_id'] ;
          if ($options['debug']) { echo '<strong>Не найден доктор в группе, использован доктор по умолчанию</strong><br>' ; }
       }
     }
     $text=ob_get_clean() ;
     if ($options['debug']) echo $text ;
     return($id) ;
   }

   // проверяем испроавность всех устройст терминала согласно профиля
   // !!! не используется
   function check_terminal_to_active($rec_terminal)
   { $allow=1 ;
     // $rec_terminal['_profil']['...'] - устройство по профилю
     // $rec_terminal['...'] - устройство на терминале по информации с check_status
     // проверяем соответствие устройст терминала заданному для него профилю
     // если профиль требует устройство, но устройство = 0 - оно неисправно
     if ($rec_terminal['_profil']['tonometer'] and !$rec_terminal['tonometer']) { $rec_personal['__check_comment'][]='На терминале неисправен тонометр' ; $allow=0 ; }
     if ($rec_terminal['_profil']['thermometer'] and !$rec_terminal['thermometer']) { $rec_personal['__check_comment'][]='На терминале неисправен термометр' ; $allow=0 ; }
     if ($rec_terminal['_profil']['alcotester'] and !$rec_terminal['alcotester']) { $rec_personal['__check_comment'][]='На терминале неисправен алкотестер' ; $allow=0 ; }
     if ($rec_terminal['_profil']['pupilometer'] and !$rec_terminal['pupilometer']) { $rec_personal['__check_comment'][]='На терминале неисправен пупилометр' ; $allow=0 ; }
     if (!$allow)
     {   $status=array('tonometer'=>$rec_terminal['tonometer'],'thermometer'=>$rec_terminal['thermometer'],'alcotester'=>$rec_terminal['alcotester'],'pupilometer'=>$rec_terminal['pupilometer']) ;
         LOG_JSON('mo_session')->reg('Проверка устройств терминала','<div class="red">Набор исправных устройств терминала не соответствует профилю</div>Проверте правильность назначения профиля, исправность устройств терминала, перезагрузите терминал',
                 array( 'data'=>array('Состояние устройств'=>$status,
                                      'Профиль терминала'=>$rec_terminal['_profil'],
                                      'Название профиля терминала'=>$rec_terminal['_profil_name']
                        ))) ;
     }
     return($allow) ;

   }

   // проверяем соответсвие терминала правилалам проведения МО
   function check_terminal_to_used(&$rec_personal,$rules,$rec_terminal)
   { $allow=1 ;
     // $rec_terminal['_profil']['...'] - устройство по профилю
     // $rec_terminal['...'] - устройство на терминале по информации с check_status
     // проверяем соответствие устройст терминала заданному для него профилю
     // если профиль требует устройство, но устройство = 0 - оно неисправно
     if ($rec_terminal['_profil']['tonometer'] and !$rec_terminal['tonometer']) { $rec_personal['__check_comment'][]='На терминале неисправен тонометр' ; $allow=0 ; }
     // при включенной опции LS_esmo_check_thermometr_error не обращать внимание на признак неисправности термометра в  списке оборудования
     if ($rec_terminal['_profil']['thermometer'] and !$rec_terminal['thermometer'] and !$GLOBALS['LS_esmo_check_thermometr_error']) { $rec_personal['__check_comment'][]='На терминале неисправен термометр' ; $allow=0 ; }
     if ($rec_terminal['_profil']['alcotester'] and !$rec_terminal['alcotester']) { $rec_personal['__check_comment'][]='На терминале неисправен алкотестер' ; $allow=0 ; }
     if ($rec_terminal['_profil']['pupilometer'] and !$rec_terminal['pupilometer']) { $rec_personal['__check_comment'][]='На терминале неисправен пупилометр' ; $allow=0 ; }
     if (!$allow)
     {   $status=array('tonometer'=>$rec_terminal['tonometer'],'thermometer'=>$rec_terminal['thermometer'],'alcotester'=>$rec_terminal['alcotester'],'pupilometer'=>$rec_terminal['pupilometer']) ;
         LOG_JSON('mo_session')->reg(
             'Проверка терминала',
             '<div class="red">Набор исправных устройств терминала не соответствует профилю</div>Проверте правильность назначения профиля, исправность устройств терминала, перезагрузите терминал',
             array('data'=>array('Состояние устройств'=>$status,'Профиль терминала'=>$rec_terminal['_profil'],'Название профиля терминала'=>$rec_terminal['_profil_name']))
         ) ;
     }
     else
     {   if (($rules['s'] or $rules['d'] or $rules['p']) and !$rec_terminal['_profil']['tonometer'])      { $rec_personal['__check_comment'][]='В профиле терминала выключен тонометр (необходим для проверки)' ; $allow=0 ; }
         // температура может измеряться термотром или путилометром
         if ($rules['t'] and !$rec_terminal['_profil']['thermometer'] and  !$GLOBALS['LS_ignore_term_t_disabled'] and !$rec_terminal['_profil']['pupilometer']) { $rec_personal['__check_comment'][]='В профиле терминала выключен термометр (необходим для проверки)' ; $allow=0 ; }
         if ($rules['a'] and !$rec_terminal['_profil']['alcotester'])    { $rec_personal['__check_comment'][]='В профиле терминала выключен алкотестер (необходим для проверки)' ; $allow=0 ; }
         if ($rules['n'] and !$rec_terminal['_profil']['pupilometer'] and  !$GLOBALS['LS_ignore_term_pp_disabled'])    { $rec_personal['__check_comment'][]='В профиле терминала выключен пупилометр (необходим для проверки)' ; $allow=0 ; }

         if (!$allow) LOG_JSON('mo_session')->reg(
                 'Проверка терминала',
                 '<div class="red">Профиль терминала не соответствует набору критериев проверки</div>Необходимо использовать другой терминал для проверки',
                 array('data'=>array('Критерии проверки'=>$rules,'Профиль терминала'=>$rec_terminal['_profil'],'Название профиля терминала'=>$rec_terminal['_profil_name']))
         );
     }

     $rec_personal['__check']['access_terminal']=$allow ;
     if (!$allow) { $rec_personal['__check']['result']=0; $rec_personal['__go_other_terminal']=1; }
   }


   // проверяем права доступа работника
   function check_personal_access(&$rec_personal,$options=array())
   { ob_start() ;
     $options['debug']=2 ;
     $this->check_access_unlimit($rec_personal) ;  // проверка безлимитного доступа, поле full_access
     // ПРОВЕРКА нормы рабочего времени
     $this->check_work_normative($rec_personal) ;
     // ПРОВЕРКА NN мин после последнего меодсмотра
     $this->check_time_last_mo($rec_personal,$options) ;
     // ПРОВЕРКА наличия доступа в данную шахту
     $this->check_access_work($rec_personal) ;
     // ПРОВЕРКА наличие доступа по смене
     $this->check_access_by_tabel($rec_personal) ; // проверка доступа по табелю
     $this->check_access_by_work_time($rec_personal) ; // проверка доступа по времени работы
     $this->check_access_dop_list($rec_personal) ; // проверка доступа по доп. спискам
//     if ($GLOBALS['_SETTING']['modules']['terapevt']) $this->check_access_ct($rec_personal) ; // проверка доступа по доп. спискам
     if ($GLOBALS['LS_check_access_by_mess']) $this->check_personal_message($rec_personal) ; // проверка доступа по доп. спискам
     if ($GLOBALS['LS_mo_check_group_schedule']) $this->check_group_schedule($rec_personal) ; // проверка доступа по расписанию группы
     $this->check_personal_status($rec_personal) ; // проверка доступа по доп. спискам

     ENGINE()->on_event_by_pointer('mo_check_personal_access',$rec_personal) ;
     // WORK_ORDER
     //     if (function_exists('WO')) WO()->mo_check_personal_access($rec_personal) ;

     $rec_personal['__check']['result']=($rec_personal['__check']['rule'] and                        //
                                       $rec_personal['__check']['work_normative'] and              // нормы рабочего времени
                                       $rec_personal['__check']['time_last_mo'] and                //
                                       (!$GLOBALS['LS_check_access_by_mess'] or $rec_personal['__check']['access_mess']) and                //
                                       $rec_personal['__check']['access_by_personal_status'] and                //
                                       //$rec_personal['__check']['work_order'] and                //
                                       $rec_personal['__check']['access_work'] and                 // права доступа на обхект
                                           ($rec_personal['__check']['access_unlimit'] or          // допуск на рабочее место без ограничений
                                            $rec_personal['__check']['access_by_work_time'] or     // допуск по работчему времени
                                            $rec_personal['__check']['access_by_tabel'] or         // допуск по табелю
                                            $rec_personal['__check']['access_dop_list'])           // допуск по доп.спискам
                                      )? 1:0;

     if ($rec_personal['demo_access'] and $rec_personal['__check']['access_by_personal_status']) $rec_personal['__check']['result']=1 ;

     if ($GLOBALS['LS_mo_check_group_schedule'] and !$rec_personal['__check']['access_by_group_schedule']) $rec_personal['__check']['result']=0 ;


     ?><strong>_groups</strong><? if ($rec_personal['_groups']) print_2x_arr($rec_personal['_groups']); else echo '-' ;
     ?><strong>_groups_personal</strong><? if ($rec_personal['_groups_personal'])  print_2x_arr([$rec_personal['_groups_personal']]); else echo '-' ;
     ?><strong>_groups_medic</strong><? if ($rec_personal['_groups_medic'])  print_2x_arr([$rec_personal['_groups_medic']]); else echo '-' ;
     ?><strong>_rules_main</strong><? if ($rec_personal['_rules_main'])  print_2x_arr([$rec_personal['_rules_main']]); else echo '-' ;
     ?><strong>_rules_krit</strong><? if ($rec_personal['_rules_krit'])  print_2x_arr([$rec_personal['_rules_krit']]); else echo '-' ;
     ?><strong>__check</strong><? if ($rec_personal['__check'])  print_2x_arr([$rec_personal['__check']]); else echo '-' ;
     ?><strong>mo_info</strong><? if ($rec_personal['mo_info'])  print_2x_arr([$rec_personal['mo_info']]); else echo '-' ;

     $text=ob_get_clean() ;
     if ($options['debug']) echo $text ;
     //if (!$rec_personal['__check']['result'])
     LOG_JSON('mo_session')->reg('check_personal_access',$text,array('_data'=>$rec_personal)) ;
   }

   // Проверяем нормы рабочего времени
   function check_work_normative(&$rec)
   {
      $rec['__check']['work_normative']=1 ;
   }

   // Проверяем время в минутах от последнего МО
   function check_time_last_mo(&$rec,$options=array())   // rec - rec_member
   { $rec['__check']['time_last_mo']=1 ;
     $rec['debug']=$options['debug'] ;
     if ($rec['demo_access'])
     {   if ($options['debug']) echo 'Сотрудник имеет безлимитный доступ к прохождению МО<br>' ;
         return ;
     }
     // проверяем максимальное кол-во недопусков - перенесено на 1-й уровень
     /*if ($GLOBALS['LS_setting_max_DD_check'])
     {   $cnt_DD=$this->check_count_nedopusk($rec['pkey'],array('debug'=>$options['debug'])) ;
        if ($cnt_DD>=$GLOBALS['LS_setting_max_DD_count'])
        { $rec['__check']['time_last_mo']=0 ;
          $rec['__check']['dopiskSessionDenited']=1 ;
          $rec['__check_comment'][]='Превышено допустимое значение неудачных сессий МО за последние '.$GLOBALS['LS_setting_max_DD_count_hour'].' часов' ;
          $rec['__reason']='dopiskSessionDenited' ;
          $rec['__pause']=0 ;
          return ;
        }
     } */

     // проверяем наличие допуска/запрета допуска по фактическому времени жизни допуска
     if ($options['debug']) echo 'Проверяем наличие допуска/запрета допуска по фактическому времени жизни допуска<br>' ;
     $rec_dopusk=$this->check_active_dopusk($rec['pkey'],array('no_public_info'=>1,'debug'=>$options['debug'])) ;

     if ($rec_dopusk['dopusk']==1)
     { if ($options['debug']) echo 'Найден действующей допуск<br>' ;
       if ($GLOBALS['LS_mo_check_access_go_doctor_by_DA'])
       { $rec['__check']['time_last_mo']=0 ;
         $rec['__check']['dopiskAllowExist']=1 ;
       $rec['__check']['id_prev_mo']=$rec_dopusk['pkey'] ;
         $rec['__check_comment'][]='Допуск уже получен' ;
         $rec['__reason']='dopiskAllowExist' ;
         $rec['__pause']=0 ;
       }
       return ;
     }
     if ($rec_dopusk['dopusk']==2)
     { if ($GLOBALS['LS_mo_check_access_go_doctor_by_DD'])
     { $rec['__check']['time_last_mo']=0 ;
       $rec['__check']['dopiskDenitedExist']=1 ;
       $rec['__check_comment'][]='Допуск запрещен до '.date('d.m.Y H:i',$rec_dopusk['dopusk_time_end']) ;
       $rec['__reason']='dopiskDenitedExist' ;
       $rec['__pause']=0 ;
       }
       return ;
     }



     //$recs_prev_mo=execSQL('select pkey,c_data,e_data,status,alcotester,alko,dopusk,reason,equipment from '.$this->table_mo_sessions.' where member_id='.$rec['pkey'].' and c_data>='.$from.' and doctor_id>0 and (report_id=0 or report_id is null) order by pkey') ;
     if ($GLOBALS['LS_mo_check_mo_term_dubl'])
     {   if ($options['debug']) echo '<strong>Проверка открытой сесси МО</strong> за последние '.$GLOBALS['LS_setting_mo_timeout'].' сек<br>' ;
     $from=time()-$GLOBALS['LS_setting_mo_timeout'];
     if (!$options['cur_mo_session_id']) $options['cur_mo_session_id']=0 ;
     $recs_open_mo=execSQL('select pkey,status from '.$this->table_mo_sessions_now.' where pkey!='.$options['cur_mo_session_id'].' and member_id='.$rec['pkey'].' and c_data>='.$from.' and terminal_id>0  order by pkey limit 10 ',2) ;
     if (_sizeof($recs_open_mo))
     {
         $rec['__check_comment'][]='Сеанс МО начат на другом терминале' ;
         $rec['__reason']='SeansDubl' ;
         $rec['__check']['SeansDubl']=1 ;
         $rec['__check']['time_last_mo']=0 ;
     }
     }

     // LS_mo_session_lenght - по умолчанию 3 часа. // получаем все МО за последние три часа
     if ($options['debug']) echo '<strong>Проверка предыдущих МО</strong><br>' ;
     if ($options['debug']) echo 'Получаем все МО за последние '.$GLOBALS['LS_mo_session_lenght'].' часа<br>' ;
     $sec=(float)$GLOBALS['LS_mo_session_lenght']*60*60 ;
     $from=time()-$sec;

     $recs_prev_mo=execSQL('select pkey,c_data,e_data,status,alcotester,alko,dopusk,reason,equipment from '.$this->table_mo_sessions_now.' where member_id='.$rec['pkey'].' and c_data>='.$from.' and doctor_id>0  order by pkey limit 10',2) ;
     // надо удалить все МО перед последним допуском
     $arr_id=array() ; //$check_prev_mo
     if (_sizeof($recs_prev_mo)) foreach($recs_prev_mo as $mo_id=>$rec_mo)
     {  $arr_id[]=$mo_id ;
        if ($rec_mo['dopusk']) { foreach($arr_id as $del_mo_id) unset($recs_prev_mo[$del_mo_id]) ; $arr_id=array() ; }
     }
     if ($options['debug']) print_2x_arr($recs_prev_mo) ;
     $cnt_dopusk=0 ; $cnt_alko=0 ; $cnt_failedMO=0 ; $cnt_EE=0 ;   $cnt_failedMO2=0 ;  $first_failed_time=0 ;  $cnt_negativeResponse=0 ;  $cnt_denited=0 ;
     if (_sizeof($recs_prev_mo)) foreach($recs_prev_mo as $rec_mo)
     {  // dopusk проверяется ранее
        //if ($rec_mo['dopusk']==1 or $rec_mo['dopusk']==2) { $cnt_dopusk++  ; $cnt_failedMO=0 ; $cnt_alko=0 ; $cnt_EE=0 ; $cnt_negativeResponse=0 ; $cnt_failedMO2=0 ;}// после фиксации допуска сбрасываем все флаги
        if ($rec_mo['reason']!="equipmentFailure" and $rec_mo['alcotester']==1 and $rec_mo['alko']==1) $cnt_alko++  ;
        if ($rec_mo['reason']=="equipmentError") $cnt_EE++  ;
        if ($rec_mo['reason']=="negativeResponse") $cnt_negativeResponse++  ;
        if ($rec_mo['status']==3) $cnt_failedMO++  ;
        if ($rec_mo['status']==3 and $rec_mo['reason']!='equipmentFailure') { $cnt_failedMO2++  ; $first_failed_time=$rec['c_data'] ; }
        if ($rec_mo['error']==5) $cnt_denited++  ;
        if ($rec_mo['error']==6) $cnt_denited++  ;
     }
     if ($options['debug'])
     {  echo '<strong>Результаты проверки предудущих МО:</strong><br>' ;
        ?><table class="basic fz_small left">
            <tr><td>Выявлен алкоголь</td><td>$cnt_alko</td><td><?echo $cnt_alko?></td></tr>
            <tr><td>Число попыток неудачного прохождения МО на терминале.</td><td>$cnt_EE</td><td><?echo $cnt_EE?></td></tr>
            <tr><td>Жалобы на здоровье</td><td>$cnt_negativeResponse</td><td><?echo $cnt_negativeResponse?></td></tr>
            <tr><td>Общее число попыток непрохождения МО на терминале (status=3).</td><td>$cnt_failedMO</td><td><?echo $cnt_failedMO?></td></tr>
            <tr><td>Общее число попыток непрохождения МО на терминале (status=3 and reason!=equipmentFailure).</td><td>$cnt_failedMO2</td><td><?echo $cnt_failedMO2?></td></tr>
            <tr><td>Допуск был ранее аннулирован</td><td>$cnt_denited</td><td><?echo $cnt_denited?></td></tr>
          </table><?
     }

     // проверяем флаги
     if ($cnt_alko and $GLOBALS['LS_mo_check_access_go_doctor_by_AL'])
     {   $rec['__check']['time_last_mo']=0 ;
         $rec['__check']['alco_exist']=1 ;
         $rec['__check_comment'][]='Выявлен алкоголь в предущем осмотре.' ;
         $rec['__go_doctor']=1 ;
         $rec['__reason']='alcoExist' ;
     }
     elseif ($cnt_denited and $GLOBALS['LS_mo_check_access_go_doctor_by_AN'])
     {   $rec['__check']['time_last_mo']=0 ;
         $rec['__check']['denitedExist']=1 ;
         $rec['__check_comment'][]='Допуск был ранее аннулирован' ;
         $rec['__go_doctor']=1 ;
         $rec['__reason']='denitedExist' ;
     }
     elseif ($cnt_negativeResponse and $GLOBALS['LS_mo_check_access_go_doctor_by_NR'])
     {   $rec['__check']['time_last_mo']=0 ;
         $rec['__check']['negativeResponseExist']=1 ;
         $rec['__check_comment'][]='Ранее жалоба на здоровье' ;
         $rec['__go_doctor']=1 ;
         $rec['__reason']='negativeResponseExist' ;
     }
     elseif ($cnt_EE>=2 and  $GLOBALS['LS_mo_check_access_go_doctor_by_EE'])
     { $rec['__check']['time_last_mo']=0 ;
       $rec['__check']['EEexist']=1 ;
       $rec['__check_comment'][]='Более двух попыток неудачного прохождения МО на терминале.' ;
       $rec['__go_doctor']=1 ;
       $rec['__reason']='EEexist' ;
     }
     elseif ($cnt_failedMO>=2 and  $GLOBALS['LS_mo_check_access_go_doctor_by_FF'])
     { $rec['__check']['time_last_mo']=0 ;
       $rec['__check']['failedMO']=1 ;
       $rec['__check_comment'][]='Более двух попыток непрохождения МО на терминале.' ;
       $rec['__go_doctor']=1 ;
       $rec['__reason']='failedMO' ;
     }
     /*  // эта проверка работать никогда не будет, так как $cnt_failedMO2 всегду будет меньше чем $cnt_failedMO, а проверка по нему происходит ранее
     elseif ($cnt_failedMO2>$GLOBALS['LS_setting_auto_mo_count']) // старая проверка на превышение допустимого числа неудачных проверок. К врачу тут не отправляли
     {  $e_data=getdate($first_failed_time) ;
        $to=mktime($e_data['hours']+$GLOBALS['LS_mo_session_lenght'],$e_data['minutes'],$e_data['seconds'],$e_data['mon'],$e_data['mday'],$e_data['year']);
        $rec['__check']['time_last_mo']=0 ;
        $rec['__reason']='failedMO_count' ;
        $rec['__check_comment'][]='Превышен лимит числа проверок. Следующая проверка не ранее '.date('H:i d.m.Y',$to) ;

     } */
     else // проверяем соблюдение интервала между проверками
         {   //$rec_last_mo=$this->get_last_mo_session_to_member($rec['pkey']) ;
             // берем последнуюю проведенную проверку по сотруднику со статусом 2 и 3 (завершенный сеанс)
             $_usl=array() ;
             $_usl[]='member_id='.$rec['pkey'] ;
             $_usl[]='status in (2,3)' ;
             $_usl[]='tk=0' ;
             // учет включенного флага LS_esmo_check_thermometr_error, когда игнориться ошибка термометра при МО
             $_usl[]=($GLOBALS['LS_esmo_check_thermometr_error'])? '(reason!="equipmentFailure" or (reason="equipmentFailure" and equipment="thermometer"))':'reason!="equipmentFailure"' ;
             if ($GLOBALS['LS_esmo_equipmentError_alcotester_ignore']) $_usl[]='not (reason="equipmentError" and equipment="alcotester")';
             $usl_select=implode(' and ',$_usl) ;

             $rec_last_mo=execSQL_van('select pkey,c_data,dopusk,dopusk_time,dopusk_time_end from '.$this->table_mo_sessions_now.' where '.$usl_select.' order by pkey desc limit 1',array('debug'=>$options['debug'])) ;
             $int_m=(time()-$rec_last_mo['c_data'])/60 ;
             $GLOBALS['LS_setting_auto_mo_interval']=ENGINE()->get_setting_value('LS_setting_auto_mo_interval') ;
             if ($options['debug'])
              {
                  echo '<strong>Проверяем соблюдение интервала между проверками:</strong><br>' ;
                  ?><table class="basic fz_small left">
                              <tr><td>ID последнего МО</td><td></td><td><?echo $rec_last_mo['pkey']?></td></tr>
                              <tr><td>Время последнего МО</td><td></td><td><?echo  date('d.m.Y H:i',$rec_last_mo['c_data'])?></td></tr>
                              <tr><td>Интервал в минутах от последнего МО</td><td>$int_m</td><td><?echo $int_m?></td></tr>
                              <tr><td>Минимальный интревал в настройках системы</td><td>LS_setting_auto_mo_interval</td><td><?echo $GLOBALS['LS_setting_auto_mo_interval']?></td></tr>
                     </table><?
              }
             //echo '$int_m='.$int_m.'<br>' ;
             //$e_data=getdate($rec_last_mo['e_data']) ;
             //$to=mktime($e_data['hours'],$e_data['minutes']+$GLOBALS['LS_setting_auto_mo_interval'],$e_data['seconds'],$e_data['mon'],$e_data['mday'],$e_data['year']);
             //  если допуск уже получен и еще действует
             /* проверка на наличие действующего допуска/запрета допуска производиться в первую очередь
              * if ($rec_last_mo['dopusk']==1 and $rec_last_mo['dopusk_time_end']>time())
             { $rec['__check']['time_last_mo']=0 ;
               $rec['__reason']='minIntAfterDopusk' ;  // 'Не выдержан минимальный интервал между осмотрами' ;
               $rec['__pause']=0 ;
               LOG_JSON('mo_session')->reg('check_dopusk','Попытка пройти осмотр во время действия ранее полученного допуска. Срок действия текущего допуска: '.date('d.m.Y H:i',$rec_last_mo['dopusk_time']).' - '.date('d.m.Y H:i',$rec_last_mo['dopusk_time_end'])) ;
             }
             else*/if ($rec_last_mo['pkey'] and $int_m<$GLOBALS['LS_setting_auto_mo_interval'])
             { $rec['__check']['time_last_mo']=0 ;
               //$rec['__check_comment'][]='Минимальный интервал между проверками '.$GLOBALS['LS_setting_auto_mo_interval'].' мин. Следующая проверка не ранее '.date('H:i d.m.Y',$to) ;
               $rec['__check_comment'][]='Минимальный интервал между проверками '.$GLOBALS['LS_setting_auto_mo_interval'].' мин.' ;
               $rec['__reason']='minIntAfterCheck' ;  // 'Не выдержан минимальный интервал между проверками' ;
               $rec['__pause']=round($GLOBALS['LS_setting_auto_mo_interval']-$int_m) ;
               LOG_JSON('mo_session')->reg('check_osmotr','Попытка пройти осмотр ранее чем через '.$GLOBALS['LS_setting_auto_mo_interval'].' минут после последней попытки. Последняя попытка была  в '.date('d.m.Y H:i',$rec_last_mo['c_data'])) ;
             }
         }

   }

   function check_access_ct(&$rec)
   { // последняя запись по вызову на прием
     $rec_priem=execSQL_van('select * from obj_site_ct_req where personal_id='.$rec['pkey'].' order by pkey desc limit 1') ;
     if ($rec_priem['pkey'] and $rec_priem['status']==1)
     { if (!$rec_priem['cnt_view']) $rec_priem['cnt_view']=0 ;
       $rec_priem['cnt_view']++ ;
       execSQL_update('update obj_site_ct_req set cnt_view='.$rec_priem['cnt_view'].' where pkey='.$rec_priem['pkey']) ;
       if ($rec_priem['cnt_view']<=5)
       { $rec['__terminal_comment']='Вам необходимо пройти прием у цехового терапевта (сообщение № '.$rec_priem['cnt_view'].')' ;
         $rec['__check']['access_ct']=1 ;
       }
       else
       { //$rec['__check_comment']=array() ;
         $rec['__check_comment'][]='Проведение МО будет возможно только после посещения цехового терапевта' ;
         $rec['__check']['access_ct']=0 ;
         $rec['__pause']=0 ;
       }

     }
     else $rec['__check']['access_ct']=1 ;
   }

   function check_group_schedule(&$rec,$options=array())
   { ob_start() ;
     //  $uid=ENGINE()->save_temp_setting(['rec'=>$rec,'options'=>$options]) ; echo $uid ;
     // проверяем - если для текущей группы МО расписание ищем расписание для группы сотрудника
     include(_DIR_TO_MODULES.'/aspmo/i_mo_schedule.php') ;
     $mo_schedule=new i_mo_schedule() ;
     list($allow_mo,$t_end_block,$time_wait)=$mo_schedule->check_chedule($rec['mo_info']['group_id'],$rec['_groups_personal']);
     if (!$allow_mo)
     {
         $rec['__check_comment'][]='Ваше прохождение МО заблокировано расписанием группы, до <strong>'.$t_end_block.'</strong>.<br><br> Пожалуйста, подойдите через <strong>'.$time_wait.'</strong>' ;
         $rec['__pause']=0 ; // =0 заблокирует вывод "Пожалуйста, подойдите через ... минут" в c_server:229

         $rec['__check']['access_by_group_schedule']=0;
     }
     else $rec['__check']['access_by_group_schedule']=1;

     $text=ob_get_clean() ;
     LOG_JSON('mo_session')->reg('check_group_schedule',$text) ;
   }


   // перенести эту функцию в PERSONAL()
   // передавая её только то, что касается МО

   function check_personal_message(&$rec,$options=array())
   { // получаем все сообщения сотруднику
     //  - новое и прочитанное
     //  - завершенный показ но с блокировкой МО
     // получаем активные сообщения для сотрудника
     $recs_mess=PERSONAL()->get_active_mess_to_personal($rec['pkey'],array(/*'view_mode'=>'1,3',*/'view_blocked'=>1)) ;
     $arr_mess_blocked=array() ; $arr_mess_info=array() ; $access_mess=1 ;
     if (_sizeof($recs_mess)) foreach($recs_mess as $rec_mess) //if ($rec_mess['status']==1)
     {   //echo 'view_from='.date('d.m.Y H:i',$rec_mess['view_from']).'<br>' ;
         //echo 'view_to='.date('d.m.Y H:i',$rec_mess['view_to']).'<br>' ;
         //echo 'time='.date('d.m.Y H:i',time()).'<br>' ;
         //if (!$rec_mess['view_from']) echo '!view_from<br>' ;
         //if ($rec_mess['view_from'] and !$rec_mess['view_to'] and $rec_mess['view_from']<time()) echo 'view_from and !view_to and view_from<time<br>' ;
         //if ($rec_mess['view_from'] and $rec_mess['view_to'] and $rec_mess['view_from']<time() and time()<$rec_mess['view_to']) echo 'view_from and view_to and view_from<time<view_to<br>' ;
         // проверяем сроки показа сообщения
         if (  // у сообщения есть два работчих диапазона. Еслди
               // 1-е - диапазон блокировки, он важнее
               ( !$rec_mess['block_from'] or
                 ($rec_mess['block_from'] and !$rec_mess['block_to'] and $rec_mess['block_from']<time()) or
                 ($rec_mess['block_from'] and $rec_mess['block_to'] and $rec_mess['block_from']<time() and time()<$rec_mess['block_to'])
               )
               // 2-е - диапазон показа
               or
               (
                 !$rec_mess['view_from'] or
                 ($rec_mess['view_from'] and !$rec_mess['view_to'] and $rec_mess['view_from']<time()) or
                 ($rec_mess['view_from'] and $rec_mess['view_to'] and $rec_mess['view_from']<time() and time()<$rec_mess['view_to'])
               )
           )
         {
           /* if ($rec_mess['max_day'] and !$rec_mess['block_from']) // если срок показа сообщения ограничен в днях, надо от даты первого показа сообщения посчитать N дней и выставить крайний срок показа сообщения
            {  $now=getdate() ;
               $block_from=mktime(0,0,0,$now['mon'],$now['mday']+$rec_mess['max_day']+1,$now['year']);
               $rec_mess['obj_name'].=', в срок до '.date('d.m.Y',$block_from) ;
               update_rec_in_table('obj_site_personal_mess',array('block_from'=>$block_from,'obj_name'=>$rec_mess['obj_name']),'pkey='.$rec_mess['pkey']) ;
            }*/

            // помечаем сообщение как прочитанное
            $cur_status=PERSONAL()->message_personal_set_view($rec_mess,'МО на терминале '.$rec['mo_info']['terminal_name'].', группа '.$rec['mo_info']['group_name']) ;
                // далее опции для сохранения в журнале событий
                // опции больше не нужны, так как в журнал событий больше не сохраняем
                /*    array('terminal_id' =>$rec['mo_info']['terminal_id'],
                          'personal_id' =>$rec['pkey'],
                          'mo_id'       =>$rec['mo_info']['mo_id'],
                          'reffers'     =>array($rec_mess['_reffer'],
                                                $rec['_reffer'],
                                                $rec['mo_info']['mo_reffer']
                                                )
                         )
                   ) ; */

           // если число показов исчерпано и блокировка МО   $cur_status==3
           if ($cur_status==3/* and $rec_mess['block_mo']*/) $arr_mess_blocked[]=$rec_mess['obj_name']/*.' ('.$rec_mess['account_name'].', #'.$rec_mess['pkey']*/.'<br>' ;
           else                                          $arr_mess_info[]=$rec_mess['obj_name']/*.' ('.$rec_mess['account_name'].', #'.$rec_mess['pkey']*/.'<br>' ;

       }
     }
     //damp_array($arr_mess_blocked,1,-1) ;
     //damp_array($arr_mess_info,1,-1) ;
           // при запрете МО текстовку надо сохранить не в $rec['__terminal_comment'] а в $rec['__check_comment']
     if (_sizeof($arr_mess_blocked))
           {  //$rec['__check_comment']=array() ;
        $rec['__check_comment'][]=implode("\n",$arr_mess_blocked)."\n".'Прохождение МО запрещено.'."\n" ;
        $rec['__terminal_comment']=implode("\n",$arr_mess_blocked)."\n".'Прохождение МО запрещено.'."\n" ;
              $rec['__pause']=0 ;
              $access_mess=0 ;
           }
     else if (_sizeof($arr_mess_info)) $rec['__terminal_comment']=implode("\n",$arr_mess_info);

           $rec['__check']['access_mess']=$access_mess ;
       }


 function check_personal_status(&$rec_personal)
   {   // если блокировка МО
       // при запрете МО текстовку надо сохранить не в $rec['__terminal_comment'] а в $rec['__check_comment']
       if ($rec_personal['mo_block']>0)
       {  $rec_personal['__check_comment']=array() ;
          $rec_personal['__check_comment'][]='Прохождение МО заблокировано в карточке сотрудника' ;
          $rec_personal['__pause']=0 ;
          $rec_personal['__check']['access_by_personal_status']=0 ;
          //LOG_JSON('mo_session')->reg('check_personal_status','',array('data'=>$rec_personal['__check_comment'])) ;
       }
       else $rec_personal['__check']['access_by_personal_status']=1 ;
   }

   // Проверяем наличия доступа в данную шахту
   function check_access_work(&$rec)
   {
      $rec['__check']['access_work']=1 ;
   }

   // Проверяем наличия доступа по смене
   // 1. Доступ "Всегда"
   function check_access_unlimit(&$rec)
   {
      $rec['__check']['access_unlimit']=$rec['full_access'] ;
   }

   // доступ по времени, поля smena_s, smena_e
   function check_access_by_work_time(&$rec)
   {  $rec['__check']['access_by_work_time']=1 ; return ;

      // $GLOBALS['LS_setting_smena_before_in']
      // $GLOBALS['LS_setting_smena_after_out']
      list($h1,$m1)=explode(':',$rec['smena_s']) ;
      list($h2,$m2)=explode(':',$rec['smena_e']) ;
      $cur_time=time() ;
      $now=getdate($cur_time) ; // текущее время
      $time_s=mktime($h1,$m1-$GLOBALS['LS_setting_smena_before_in'],0,$now['mon'],$now['mday'],$now['year']);
      //$time_e=mktime($h2,$m2+$GLOBALS['LS_setting_smena_after_out'],0,$now['mon'],$now['mday'],$now['year']);
      $rec['__check']['access_by_work_time']=0 ;
      if ($cur_time<$time_s) $rec['__check_comment'][]='Доступ разрешен не ранее '.date('d.m.Y H:i',$time_s) ;
      //elseif ($cur_time>$time_e) $rec['__check_comment'][]='Выход разрешен не позднее '.date('d.m.Y H:i',$time_e) ;
      else $rec['__check']['access_by_work_time']=1 ;
   }

   // 2. Доступ по табелю
   function check_access_by_tabel(&$rec)
   {  // если не стоит опция - работа по табелю - даем добро
      if (!$GLOBALS['LS_setting_use_tabel']) { $rec['__check']['access_by_tabel']=1 ; return ; }


      // далее замудренная проверка по времени, если импользуется табель по сменам
      // проверяем, что сотруднику разрешено работать в текущую смену
        $smena_cur=$this->get_cur_smena_interval() ;
        $_from_time=getdate($smena_cur[0]) ; // текущее время
        $day=mktime(0,0,0,$_from_time['mon'],$_from_time['mday'],$_from_time['year']);
        $allow_cur_smena=execSQL_value('select pkey from '.PERSONAL()->table_tabel.' where data='.$day.' and smena='.$smena_cur[2].' and member_id='.$rec['pkey']) ;

        // проверяем, что сотруднику разрешено работать в очередную смену, и до начала смены не более часа
        $smena_from=$this->get_next_smena_interval() ;
        $_from_time=getdate($smena_from[0]) ; // текущее время
        $day=mktime(0,0,0,$_from_time['mon'],$_from_time['mday'],$_from_time['year']);
        $allow_next_smena=execSQL_value('select pkey from '.PERSONAL()->table_tabel.' where data='.$day.' and smena='.$smena_from[2].' and member_id='.$rec['pkey']) ;

        $rec['__check']['access_by_tabel']=($allow_cur_smena or $allow_next_smena)? 1:0 ;
        if (!$rec['__check']['access_by_tabel']) $rec['__check_comment'][]='Выход в смену не предусмотрен по табелю. Пожалуйста, обратитесь к врачу!' ;
   }

   // 3. В доп.списке ДПР
   function check_access_dop_list(&$rec)
   {
      $rec['__check']['access_dop_list']=0;
   }


   //==========================================================================================================================================================================
   // ПОЛУЧЕНИЕ ПАРАМЕТРОВ ПРОВЕДЕНИЯ МО ДЛЯ РАБОТНИКА
   //==========================================================================================================================================================================




   //==========================================================================================================================================================================
   // ПОЛУЧЕНИЕ РЕЗУЛЬТАТОВ МО
   //==========================================================================================================================================================================

    // используетяя только в обработчике нажатия кнопки "разрешить допуск" в мониторинге, при ручном режиме выдаче мед.допуска к смене
    function mo_dopusk_allow($mo_id)
    { $rec_mo=$this->get_mo_by_id($mo_id) ;
      $rec_personal=PERSONAL()->get_personal_by_id($rec_mo['member_id']) ;
      if ($rec_mo['model']==2) $res_session['model']=1 ;
      if ($rec_mo['model']==4) $res_session['model']=3 ;
      if ($rec_mo['model']==6) $res_session['model']=5 ;
      if ($rec_mo['model']==8) $res_session['model']=7 ;
      if ($rec_mo['model']==10) $res_session['model']=9 ;
      $res_session['dopusk']=1 ;
      // для ПП, когда врач дает допуск при красном глазе
      if ($rec_mo['res_n']>1 and $rec_mo['res_a']<=1 and  $rec_mo['res_s']<=1 and  $rec_mo['res_d']<=1 and  $rec_mo['res_t']<=1)
      { $rec_personal['comment']=str_replace($rec_mo['narko'],'',$rec_mo['comment']) ;
        $res_session['status']=2 ;
      }
      $res_session['dopusk_user_id']=MEMBER()->id ;
      $res_session['dopusk_time']=time() ;
      $res_session['dopusk_time_end']=time()+$rec_personal['_dopusk_time_S'] ;

      $this->update_mo_session($mo_id,$res_session)  ;
      //$this->set_model_to_session_mo($mo_id) ;
      // инициируем событие
      ENGINE()->on_event('mo_dopusk_allow',array('mo_id'=>$mo_id)) ;
    }


    function get_mo_session_view_table_tr($mo_session_id,$options=array())
    {  ob_start() ;
       $rec_session=$this->get_mo_by_id_now($mo_session_id, $options) ;
       include_once(_DIR_EXT.'/aspmo/list_mo_sessions_tr.php') ;
       list_mo_sessions_tr($rec_session,$options) ;
       return(ob_get_clean()) ;
    }

    // создаем МО на основе данных формы проверки врачем
    function fixed_hand_check($data,$allow=0)
    { $rec_personal=PERSONAL()->get_personal_by_id($data['personal_id']) ;
      $rules_info=ESMO_RULES()->get_mo_rules_to_personal($rec_personal,array('rmv_mo'=>1,'esmo_group'=>MEMBER()->cur_group_id)) ;
      $rules=$rules_info['_rules'] ; // критерии проверки сотрудника
      if (!$rec_personal['pkey']) return(0) ;
      $time_dopusk_S=($allow)?  $rec_personal['_dopusk_time_S']:$rec_personal['_nedopusk_time_S'] ;

      { $res_session=array('member_id'          =>$rec_personal['pkey'],
                           'doctor_id'          =>MEMBER()->id,         // по идее одного doctor_id достаточно
                           'group_id'           =>MEMBER()->cur_group_id,
                           'creator_id'         =>MEMBER()->id,
                           'tk'                 =>$data['tk'],
                           'hand_check_user_id' =>MEMBER()->id,
                           'dopusk_user_id'     =>MEMBER()->id,
                           'dopusk_time'        =>time(),
                           'dopusk_time_end'    =>time()+$time_dopusk_S,
                           'message_terminal'   =>'success', /// ????? зачем
                           'tonometer'          =>($rules['s'] or $rules['d'] or $data['s'] or $data['d'])? 1:0,
                           'pulsometer'         =>($rules['p'] or $data['p'])? 1:0, // давление и пульс измеряются одним прибором
                           'thermometer'        =>($rules['t'] or $data['t'])? 1:0,
                           'alcotester'         =>($rules['a'] or $data['a'])? 1:0,
                           'systolic'           =>($data['s'])? $data['s']:0,
                           'diastolic'          =>($data['d'])? $data['d']:0,
                           'pulse'              =>($data['p'])? $data['p']:0,
                           'temperature'        =>($data['t'])? $data['t']:0,
                           'alko'               =>($data['a'])? $data['a']:0,
                           'alko_value'         =>($data['alko_value'])? $data['alko_value']:0,
                           'question'           =>($data['q'])? $data['q']:0,
                           'question_comment'   =>$data['qc'],
                           'doctor_comment'     =>$data['qw'],
                           'simptoms'           =>($data['a2'])? $data['simptoms']:0
                          );

        $mo_session_id=$this->open_mo_session($res_session) ; // id записи по проведению МО ;

        // проверяем результат МО врачем, как при автоматической проверке
        $mo_result=ESMO_RULES()->get_mo_result_to_personal($rules,$data,array('tk'=>$data['tk']))  ;
        // по  get_mo_result_to_personal будут заполнены поля status,res_s,res_d,res_p,res_t,res_a

        // дополняем служебной информацией
        $mo_result['e_data']=time() ;
        $mo_result['dopusk']=($allow)? 1:2 ; // 1 = Допуск есть, 2 - допуска нет

        // если недопуск по алкоголю - использовать другое время
        if ($mo_result['dopusk']==2 and $mo_result['res_a']==2)
            { $mo_result['dopusk_time_end']=time()+$rec_personal['_nedopusk_time_S_alco'] ;
              // отправляем сообщение пользователю о недопуске по алкоголю и сроку ограничения
              $mess_reffer=PERSONAL()->message_personal_create(array('mess_text'=>$GLOBALS['LS_setting_auto_mo_denited_alco_message'].', срок до '.date('d.m.Y H:i:s',$mo_result['dopusk_time_end']),
                                                          'group_id'=>MEMBER()->cur_group_id,
                                                          'account_id'=>MEMBER()->id,
                                                          'personal_id'=>$rec_personal['pkey'],
                                                          'view_from'=>time(), // срок - 10 дней от даты получения направления
                                                          'view_to'=>$mo_result['dopusk_time_end'], // срок - 10 дней от даты получения направления
                                                          'block_from'=>time(), // срок - 10 дней от даты получения направления
                                                          'block_to'=>$mo_result['dopusk_time_end'], // срок - 10 дней от даты получения направления
                                                          //'view_mode'=>1, // показывать при прохождении МО
                                                          //'block_mo'=>1, // блокировать прохождение МО
                                                          'auto_close'=>$mo_result['dopusk_time_end'], // автозакрытие сообщения после срока окончания показа
                                                          )) ;
            }
        // сохраняем данные измерений в запись МО
        $this->update_mo_session($mo_session_id,$mo_result) ; // id записи по проведению МО

        $mo_session_url='/cab/mo/'.$mo_session_id.'/' ;
        // сохраняем в логе
        $result=($allow)? 'Доступ разрешен':'Доступ запрещен' ;
        LOG_JSON('mo_session')->reg('Ручной медосмотр',$result) ;

        $this->set_model_to_session_mo($mo_session_id) ;

        if (!$allow and $GLOBALS['LS_setting_max_DD_check'])  ESMO()->check_count_DD_to_personal($rec_personal['pkey']) ;

        $xmpp_message=array() ;
        $xmpp_message['time']=date('d.m.y H:i:s') ; //  подгатавливаем массив информации по всем терминалам текущей группы
        $xmpp_message['from']='c_server::check_access' ;
        $xmpp_message['mo_tr_id']=$mo_session_id ;  ;
        $xmpp_message['mo_tr']=$this->get_mo_session_view_table_tr($mo_session_id) ;  ;
        ESMO()->reg_monitor_mess(MEMBER()->cur_group_id,$xmpp_message) ;

        // инициируем событие
        if ($allow) ENGINE()->on_event('fixed_hand_check_allow',array('mo_id'=>$mo_session_id)) ;
        else        ENGINE()->on_event('fixed_hand_check_denited',array('mo_id'=>$mo_session_id)) ;

       return(array($mo_session_id,$mo_session_url)) ;
    }
  }

    // отмена ранее выданного мед.допуска
    function hand_dopusk_clear($mo_id,$data)
    { $rec_mo=$this->get_mo_by_id($mo_id) ;
      //$rec_personal=PERSONAL()->get_personal_by_id($rec_mo['member_id']) ;

      $res_session=array('model'   =>0,
                         'dopusk'   =>0,
                         'status'   =>4,        // 4 - МО не пройден
                         'error'   =>5,         // по идее одного doctor_id достаточно
                         'error_reason'=>$data['mess'],
                         'dopusk_user_id'=>MEMBER()->id,
                         'dopusk_time'=>time(),
                         'dopusk_time_end'=>0
                        ) ;
      if ($data['s']) $res_session['res_s']=$data['s'];
      if ($data['d']) $res_session['res_d']=$data['d'];
      if ($data['p']) $res_session['res_p']=$data['p'];
      if ($data['t']) $res_session['res_t']=$data['t'];
      if ($data['a']) $res_session['res_a']=$data['a'];
      if ($data['n']) $res_session['res_n']=$data['n'];
      $this->update_mo_session($mo_id,$res_session) ;
      LOGS()->reg_log('Аннулирование допуска доктором',$data['mess'],array('member_id'=>$rec_mo['member_id'],'mo_id'=>$mo_id,'data'=>$data)) ;
      LOG_JSON('mo_session')->reg('Аннулирование допуска доктором',$data['mess'],array('data'=>$data)) ;

        $this->set_model_to_session_mo($mo_id) ;
      if ($rec_mo['mo1_id']) ESMO()->set_model_to_session_mo($rec_mo['mo1_id']) ; // восставливаем модель МО у предудущего МО

        $xmpp_message=array() ;
        $xmpp_message['time']=date('d.m.y H:i:s') ;
        $xmpp_message['from']='hand_dopusk_denited' ;
        $xmpp_message['mo_tr_id']=$mo_id ;  ;
        $xmpp_message['mo_tr']=$this->get_mo_session_view_table_tr($mo_id) ;  ;
        ESMO()->reg_monitor_mess(MEMBER()->cur_group_id,$xmpp_message) ;

        ENGINE()->on_event('hand_check_clear',array('mo_id'=>$mo_id)) ;

    }

    // отмена ранее выданного мед.допуска
    function hand_nedopusk_clear($mo_id,$data)
    { $rec_mo=$this->get_mo_by_id($mo_id) ;
      //$rec_personal=PERSONAL()->get_personal_by_id($rec_mo['member_id']) ;

      $res_session=array('model'   =>0,
                         'dopusk'   =>0,
                         'status'   =>4,        // 4 - МО не пройден
                         'error'   =>6,         // по идее одного doctor_id достаточно
                         'dopusk_user_id'=>MEMBER()->id,
                         'dopusk_time'=>time(),
                         'dopusk_time_end'=>0
                        ) ;

      $this->update_mo_session($mo_id,$res_session) ;

      LOGS()->reg_log('Отмена запрета допуска фельдшером',$data['mess'],array('member_id'=>$rec_mo['member_id'],'mo_id'=>$mo_id,'data'=>$data)) ;
      LOG_JSON('mo_session')->reg('Отмена запрета допуска фельдшером',$data['mess'],array('data'=>$data)) ;

      //$this->set_model_to_session_mo($mo_id) ;
      if ($rec_mo['mo1_id']) ESMO()->set_model_to_session_mo($rec_mo['mo1_id']) ; // восставливаем модель МО у предудущего МО

        $xmpp_message=array() ;
        $xmpp_message['time']=date('d.m.y H:i:s') ;
        $xmpp_message['from']='hand_nedopusk_clear' ;
        $xmpp_message['mo_tr_id']=$mo_id ;  ;
        $xmpp_message['mo_tr']=$this->get_mo_session_view_table_tr($mo_id) ;  ;
        ESMO()->reg_monitor_mess(MEMBER()->cur_group_id,$xmpp_message) ;

        ENGINE()->on_event('hand_check_clear',array('mo_id'=>$mo_id)) ;

    }

   function upload_tabel_from_excel($file_name){return(PERSONAL()->upload_tabel_from_excel($file_name));}
   function append_tabel_from_array($recs){return(PERSONAL()->append_tabel_from_array($recs));}
   function append_tabelHR_from_array($recs){return(PERSONAL()->append_tabelHR_from_array($recs));}
   function append_personal_from_array(&$recs){return(PERSONAL()->append_personal_from_array($recs));}

   //==========================================================================================================================================================================
   // РАСЧЕТ ВРЕМЕНИ ТЕКУЩЕЙ, СЛЕДУЮЩЕЙ И ПРЕДУДУЩЕЙ СМЕНЫ ПО ЗАДАННОМУ ВРЕМЕНИ
   //==========================================================================================================================================================================

   function get_cur_smena_interval($t=0)
   {   if (!$t) $t=time() ; //$t=1404669553 ;
       $now=getdate($t) ; // текущее время
       $cur_smena_id=$this->get_smena_id($t) ;
       $smena_time=$this->smena_time[$cur_smena_id] ;
       if ($smena_time['from']>$smena_time['to']) // если смена приходиться на два дня
       {  if (($now['hours']>=$smena_time['from'] and $now['hours']<=23)) // мы находимся до полуночи, смена идет сегодня и завтра
          { $from=mktime($smena_time['from'],0,0,$now['mon'],$now['mday'],$now['year']);
            $to=mktime($smena_time['to']-1,59,59,$now['mon'],$now['mday']+1,$now['year']);
          }
          else // мы находимся после полуночи, смена идет вчера и сегодня
          { $from=mktime($smena_time['from'],0,0,$now['mon'],$now['mday']-1,$now['year']);
            $to=mktime($smena_time['to']-1,59,59,$now['mon'],$now['mday'],$now['year']);
          }
       }
       else // если смена приходиться на один день
       { $from=mktime($smena_time['from'],0,0,$now['mon'],$now['mday'],$now['year']);
         $to=mktime($smena_time['to']-1,59,59,$now['mon'],$now['mday'],$now['year']);
       }
       return(array($from,$to,$cur_smena_id)) ;
   }

   function get_next_smena_interval($t=0)
   { list($from,$to,$smena_id)=$this->get_cur_smena_interval($t) ;
     $smena_id++ ; if ($smena_id>_sizeof($this->smena_time)) $smena_id=1 ;
     $smena_interval=$this->smena_interval[$smena_id] ; // длительность следущей смены
     $from=$to+1 ; // разбираем время от начала следующей смены
     $_from=getdate($from) ; // разбираем время от начала следующей смены
     $to=mktime($_from['hours']+$smena_interval-1,59,59,$_from['mon'],$_from['mday'],$_from['year']);
     return(array($from,$to,$smena_id)) ;
   }

   function get_prev_smena_interval($t=0)
   { list($from,$to,$smena_id)=$this->get_cur_smena_interval($t) ;
     $smena_id-- ; if (!$smena_id) $smena_id=_sizeof($this->smena_time) ;
     $smena_interval=$this->smena_interval[$smena_id] ; // длительность предыдущей смены
     $to=$from-1 ; // разбираем время от начала следующей смены
     $_to=getdate($to) ; // разбираем время от начала следующей смены
     $from=mktime($_to['hours']-$smena_interval+1,0,0,$_to['mon'],$_to['mday'],$_to['year']);
     return(array($from,$to,$smena_id)) ;
   }


   // составляем список смен по часам
   function get_smena_by_hour($smena)
   { $hours=array() ;
     for($i=0;$i<24;$i++) $hours[$i]='' ;
     if (_sizeof($smena)) foreach($smena as $smena_id=>$smena_time)
     {  if ($smena_time['from']>$smena_time['to'])
        { for($i=$smena_time['from'];$i<=24;$i++) $hours[$i]=$smena_id ;
          for($i=0;$i<$smena_time['to'];$i++) $hours[$i]=$smena_id ;
        }
       else for($i=$smena_time['from'];$i<$smena_time['to'];$i++) $hours[$i]=$smena_id ;
     }
     return($hours) ;
   }

   // составляем список смен по часам
   function get_smena_interval($smena)
   { $intervals=array() ;
     if (_sizeof($smena)) foreach($smena as $smena_id=>$smena_time)
     {  if ($smena_time['from']>$smena_time['to']) $intervals[$smena_id]=24-$smena_time['from']+$smena_time['to'] ;
        else $intervals[$smena_id]=$smena_time['to']-$smena_time['from'] ;
     }
     return($intervals) ;
   }

   function get_smena_id($t)
   { $now=getdate($t) ; // текущее время
     $cur_smena_id=$this->smena_by_hour[$now['hours']] ;
     return($cur_smena_id) ;
   }



   // принудительная установка допуска через нажатие кнопки в карточке МО
   // более не используется
    /*
   function set_dopusk($mo_id,$dopusk)
   { $mo_rec=$this->get_mo_by_id($mo_id) ;
     update_rec_in_table($this->table_mo_sessions,array('dopusk'=>$dopusk,
                                                        'dopusk_user_id'=>MEMBER()->id,
                                                        'dopusk_time'=>time(),
                                                        'dopusk_time_end'=>time()+$rec_personal['_dopusk_time_S'],
                                                        ),'pkey='.$mo_id) ;
     // сохраняем в логе
     LOG_JSON('mo_session')->reg('Допуск к смене',$_SESSION['ARR_status_dopusk'][$dopusk]) ;
   }  */

   function set_member_limit($member_id,$rec)
   {
     $data['s_min']=($rec['s_min']>0)? $rec['s_min']:'NULL' ;
     $data['s_max']=($rec['s_max']>0)? $rec['s_max']:'NULL' ;
     $data['d_min']=($rec['d_min']>0)? $rec['d_min']:'NULL' ;
     $data['d_max']=($rec['d_max']>0)? $rec['d_max']:'NULL' ;
     $data['p_min']=($rec['p_min']>0)? $rec['p_min']:'NULL' ;
     $data['p_max']=($rec['p_max']>0)? $rec['p_max']:'NULL' ;
     $data['t_min']=($rec['t_min']>0)? $rec['t_min']:'NULL' ;
     $data['t_max']=($rec['t_max']>0)? $rec['t_max']:'NULL' ;
     $data['a']=($rec['a'])?  $rec['a']:0;
     $data['n']=($rec['n'])?  $rec['n']:0;
     ob_start() ;
     damp_array($data,1,-1) ;
     //damp_array($data,1,-1) ;
     $res=update_rec_in_table(PERSONAL()->table_personal,$data,'pkey='.$member_id,array('debug'=>2)) ;
     $text=ob_get_clean()  ;
     LOGS()->reg_log('set_member_limit',$text,array('member_id'=>$member_id)) ;
     //damp_array($res) ;
   }

   /*   на удаление
   function reload_rules_MO()
   {
    if (is_object(_IL('IL_dg'))) $_SESSION['IL_dg']=execSQL('select * from '.TM_LIST.' where parent='._IL('IL_dg')->id.' order by time_from,time_to,working,age_min,age_max,pkey',array('use_fname_indx'=>'id')) ;
   } */


   //==========================================================================================================================================================================
   // СЕАНС МЕДОСМОТРА
   //==========================================================================================================================================================================

    // ищем прошлое МО в сессии
    function search_prev_mo_in_session($personal_id,$to,$options=array())
    {  $sec=$GLOBALS['LS_mo_session_lenght']*60*60 ;
       $from=$to-$sec;
       $rec_last_mo=execSQL_van('select * from '.$this->table_mo_sessions_now.' where member_id='.$personal_id.' and c_data>='.$from.' and status in (2,3) and not error in (5,6) order by pkey desc limit 1',array('debug'=>$options['debug'])) ;
       if ($rec_last_mo['dopusk']) $rec_last_mo=array() ;
       $mo_id=(isset($rec_last_mo['pkey']))? $rec_last_mo['pkey']:0 ;
       return($mo_id) ;
    }


   // добавляем запись по МО в таблицу, возвращает id записи
   function open_mo_session($rec_session=array(),$options=array())
   {   ob_start() ;   $rec_prev_mo_old=array() ;  $prev_mo_id=0 ;
       $debug_db=($options['check'])? 2:0 ;
       if ($rec_session['member_id'])
       {   echo 'Открываем новую сессию МО, текущее время '.date('d.m.Y H:i:s').'<br>' ;
           // смотрим последную нормальную сессию за  заданный переод времени
           $now=getdate() ;
           $from_time=mktime($now['hours']-$GLOBALS['LS_setting_smena_after'],$now['minutes'],0,$now['mon'],$now['mday'],$now['year']);

           if (!isset($rec_session['tk']))
           { echo 'Автоматическое определение типа МО (предсменный/послесменный) - проверяем последнее МО за '.$GLOBALS['LS_setting_smena_after'].' часов назад, c '.date('d.m.Y H:i:s',$from_time).'<br>' ;
             $prev_session=execSQL_van('select pkey,c_data,tk from '.$this->table_mo_sessions_now.' where c_data>='.$from_time.' and member_id='.$rec_session['member_id'].' and dopusk=1 order by c_data desc limit 1',2) ;
           $rec_session['tk']=($prev_session['pkey'] and !$prev_session['tk'])? 1:0  ;   // тип контроля 0 - предсменный, 1 - послесменный контроль
             echo 'Определен тип МО "'.$_SESSION['ARR_mo_tk_type'][$rec_session['tk']].'"<br>' ;
           }
           else echo 'Передан фиксированный тип МО "'.$_SESSION['ARR_mo_tk_type'][$rec_session['tk']].'"<br>' ;

           // смотрим, есть ли записи по МО1. Вглубь на LS_mo_session_lenght часа
           $sec=(float)$GLOBALS['LS_mo_session_lenght']*60*60 ;
           $time_from=time()-$sec;

           echo 'Автоматическое определение сеанса МО (MO1/MO2) - проверяем последнее МО за '.$GLOBALS['LS_mo_session_lenght'].' часов назад, c '.date('d.m.Y H:i:s',$time_from).'<br>' ;
           $rec_prev_mo_old=execSQL_van('select * from '.$this->table_mo_sessions_now.' where member_id="'.$rec_session['member_id'].'" and c_data>='.$time_from.' and status in (2,3) and (dopusk=0 or dopusk is null) order by pkey desc limit 1',$debug_db) ;
           echo '$rec_prev_mo_old='.$rec_prev_mo_old['pkey'].'<br>' ;
           $prev_mo_id=$this->search_prev_mo_in_session($rec_session['member_id'],time()) ;
           echo '$prev_mo_id='.$prev_mo_id.'<br>' ;

           /*$prev_mo=execSQL_van('select pkey,session_id,dopusk from '.$this->table_mo_sessions_now.' where member_id='.$rec_session['member_id'].' order by pkey desc limit 1',2) ;
           if ($prev_mo['session_id']<time() or $prev_mo['dopusk'] or !$prev_mo['session_id'])
           {   $now=getdate() ;
               $cur_session_id=mktime($now['hours'],$now['minutes'],$now['seconds']+$GLOBALS['LS_mo_session_lenght']*60*60,$now['mon'],$now['mday'],$now['year']);
               if ($prev_mo['session_id']<time()) $status='session timeout' ;
               if ($prev_mo['dopusk']) $status='dopusk found' ;
               if (!$prev_mo['session_id']) $status='session_id=0' ;
               echo 'open new session: '.$cur_session_id.' - '.$status.'<br>' ;

           }
           else
           {   $cur_session_id=$prev_mo['session_id'] ;
               echo 'continue session: '.$prev_mo['session_id'].'<br>' ;

           }
           $rec_session['session_id']=$cur_session_id ;
           */
           if (!$prev_mo_id)      $rec_session['mo_type']=1 ;  // первичный МО
           else                   { $rec_session['mo_type']=2 ;
                                    $rec_session['mo1_id']=$prev_mo_id ;
                                            } // вторичный МО
           echo 'Определен тип МО - MO'.$rec_session['mo_type'].'<br>' ;


       }
       else
       {
           $rec_session['member_id']=0;
       }

       $rec_session['c_data']=time() ;
       if (isset($rec_session['temperature'])) $rec_session['temperature']=str_replace(',','.',$rec_session['temperature']) ;
       //$rec_session['c_data_m5']=time()/5 ;
       $now=getdate($rec_session['c_data']) ;
       $rec_session['c_data_m']=mktime($now['hours'],$now['minutes'],0,$now['mon'],$now['mday'],$now['year']) ;
       $rec_session['c_data_h']=mktime($now['hours'],0,0,$now['mon'],$now['mday'],$now['year']) ;
       $rec_session['c_data_d']=mktime(0,0,0,$now['mon'],$now['mday'],$now['year']) ;

       $rec_session['e_data']=0 ;
       $rec_session['clss']=250 ;
       if (!$rec_session['status']) $rec_session['status']=1 ;
       if (!$rec_session['doctor_id']) $rec_session['doctor_id']=0 ;
       $rec_session['indx']=1 ;
       $id=0 ;
       if (!$options['check']) $id=adding_rec_to_table($this->table_mo_sessions_now,$rec_session,array('debug'=>0)) ;
       else damp_array($rec_session,1,-1) ;
       $text=ob_get_clean() ;
       LOG_JSON('mo_session')->reg('open_mo_session',$text) ;
       if ($options['check']) echo $text ;
       if ($rec_prev_mo_old['pkey']!=$prev_mo_id)
       { LOGS()->reg_log('mo1_search_bag','old_value='.$rec_prev_mo_old['pkey'].', new_value='.$prev_mo_id,array('mo_id'=>$id)) ;
         LOG_JSON('mo_session')->reg('mo1_search_bag','old_value='.$rec_prev_mo_old['pkey'].', new_value='.$prev_mo_id) ;
       }
     return($id) ;
   }

   function update_mo_session($sess_id,$rec)
   { list($sess_id,$tkey)=explode('.',$sess_id) ;
     if ($GLOBALS['LS_mo_now_enabled']) update_rec_in_table($this->table_mo_sessions_now,$rec,'pkey='.$sess_id,array('debug'=>0)) ;
     update_rec_in_table($this->table_mo_sessions,$rec,'pkey='.$sess_id,array('debug'=>0)) ;
   }

   /* не используется
    * function close_mo_session($status)
   {  if ($_SESSION['cur_mo_sess_id']) update_rec_in_table($this->table_mo_sessions,array('status'=>$status),'pkey='.$_SESSION['cur_mo_sess_id']) ;
      $_SESSION['cur_mo_sess_id']=0 ;
      $_SESSION['cur_mo_sess_status']=0 ;
   } */

   // возвращает последнюю сессию МО
   /*  не используется
   function get_last_mo_session_to_member($member_id)
   { $rec=execSQL_van('select * from '.$this->table_mo_sessions.' where member_id='.$member_id.' order by e_data desc limit 1') ;
     return($rec) ;
   }*/

   /*  не используется
   // возвращает число неудачных сессиий МО за последний $hours часов
   function get_count_failed_mo($member_id,$hours=0)
   { $now=getdate(time()) ;
     $from=mktime($now['hours']-$hours,$now['minutes'],$now['seconds'],$now['mon'],$now['mday'],$now['year']);
     //echo 'time_from='.date('d.m.Y H:i:s',$from) ;
     //$cnt=execSQL_value('select count(pkey) from '.$this->table_mo_sessions.' where member_id='.$member_id.' and e_data>='.$from.' and status=3') ;
     //$time=execSQL_value('select e_data from '.$this->table_mo_sessions.' where member_id='.$member_id.' and e_data>='.$from.' and status=3 order by e_data limit 1') ;
     $res=execSQL_line('select e_data from '.$this->table_mo_sessions.' where member_id='.$member_id.' and e_data>='.$from.' and status=3 and reason!="equipmentFailure" order by e_data')  ;
     //return(array($cnt,$time)) ;
     return(array(_sizeof($res),$res[0])) ;
   } */

   function prepare_public_info_to_mo(&$rec,$options=array())
   {  $t=fixed_time() ;
      $rec['__href']='/cab/mo/'.$rec['pkey'].'/' ;
      $rec['__href_window']='/window/mo/'.$rec['pkey'].'/' ;

      $arr_ids=array() ; //$recs_account=array() ;
      if ($rec['e_data']) $rec['__dlit_mo']=$rec['e_data']-$rec['c_data'] ;
      if ($rec['hand_check_user_id']) $arr_ids[$rec['hand_check_user_id']]=1 ;
      if ($rec['doctor_id'])          $arr_ids[$rec['doctor_id']]=1 ;
      if ($rec['creator_id'])         $arr_ids[$rec['creator_id']]=1 ;
      if ($rec['dopusk_user_id'])     $arr_ids[$rec['dopusk_user_id']]=1 ;
      //if (_sizeof($arr_ids)) $recs_account=ACCOUNTS()->get_members_by_ids(array_keys($arr_ids)) ;

      if ($rec['hand_check_user_id'])   $rec['_hand_check_user_name']=_IL('ARR_accounts')->recs[$rec['hand_check_user_id']]['_rol_name'].' '._IL('ARR_accounts')->recs[$rec['hand_check_user_id']]['obj_name'] ;
      if ($rec['doctor_id'])            $rec['_doctor_name']=_IL('ARR_accounts')->recs[$rec['doctor_id']]['_rol_name'].' '._IL('ARR_accounts')->recs[$rec['doctor_id']]['obj_name'] ;
      if ($rec['doctor_id'])            $rec['_doctor_name_small']=_IL('ARR_accounts')->recs[$rec['doctor_id']]['obj_name'] ;
      if ($rec['creator_id'])           $rec['_creator_name']=_IL('ARR_accounts')->recs[$rec['creator_id']]['_rol_name'].' '._IL('ARR_accounts')->recs[$rec['creator_id']]['obj_name'] ;
      if ($rec['dopusk_user_id'])       $rec['dopusk_user_name']=_IL('ARR_accounts')->recs[$rec['dopusk_user_id']]['_rol_name'].' '._IL('ARR_accounts')->recs[$rec['dopusk_user_id']]['obj_name'] ;
      // если терминал удален из системы, поле terminal_name будет пустов
      if ($rec['terminal_id'] and !$rec['terminal_name']) $rec['terminal_name']='Терминал № '.$rec['terminal_id'] ;

      $rec['_tk_name']=$_SESSION['ARR_mo_tk_type'][$rec['tk']];
      $rec['_data']=date('d.m.Y H:i',$rec['c_data']) ;
      $rec['_data_dopusk_end']=($rec['dopusk_time_end']>0 and ($rec['dopusk']==1 or $rec['dopusk']==2))? date('d.m.Y H:i:s',$rec['dopusk_time_end']):0 ;
      $rec['_status_name']=$_SESSION['ARR_status_sess'][$rec['status']] ;
      $rec['_model_name']=$_SESSION['ARR_model_osmotr'][$rec['model']];
      // если не включен контроль ошибок термометра и ошибка не связана с термометром
      if (!($GLOBALS['LS_esmo_check_thermometr_error'] and $rec['reason']=='equipmentFailure' and $rec['equipment']=='thermometer'))
      {
        if ($rec['reason'])       $rec['_reason']=$_SESSION['ARR_mo_failed_status'][$rec['reason']] ;
      if ($rec['equipment'])    $rec['_equipment']=$_SESSION['ARR_mo_failed_dev'][$rec['equipment']] ;
      }
      if (!$rec['dopusk']) $rec['dopusk']=0 ;
      $rec['_dopusk_name']=($rec['dopusk'])? $_SESSION['ARR_status_dopusk'][$rec['dopusk']]:'' ;

      // 1 - послесменный
      if ($rec['tk']==1) { if ($rec['dopusk']==1) $rec['_dopusk_name_full']='Медосмотр пройден' ;
                        if ($rec['dopusk']==2) $rec['_dopusk_name_full']='Медосмотр не пройден' ;
                        if ($rec['dopusk']==3) $rec['_dopusk_name_full']='Уклонился' ;
                        if (!$rec['dopusk'] and $rec['reason']=='noDoctor') $rec['_dopusk_name_full']='Осмотр не проводился' ;
                        if (!$rec['dopusk'] and $rec['reason']=='noAutorize') $rec['_dopusk_name_full']='Осмотр не проводился' ;
                      }
      // 0 - предсменный, 2 - межсменный
      else            { if ($rec['dopusk']==1) $rec['_dopusk_name_full']='Допуск разрешен' ;
                        if ($rec['dopusk']==2) $rec['_dopusk_name_full']='Допуск запрещен' ;
                        if ($rec['dopusk']==3) $rec['_dopusk_name_full']='Уклонился' ;
                        if (!$rec['dopusk'] and $rec['reason']=='noDoctor') $rec['_dopusk_name_full']='Осмотр не проводился' ;
                        if (!$rec['dopusk'] and $rec['reason']=='noAutorize') $rec['_dopusk_name_full']='Осмотр не проводился' ;
                      }

      if ($rec['dopusk']==1 and $GLOBALS['LS_default_doctor_comment']) $rec['doctor_fixed_comment']=$GLOBALS['LS_default_doctor_comment'] ;

      if ($rec['dopusk']==1 or $rec['dopusk']==2)
      { $rec['_dopusk_status']='<div class="dopusk_state_'.$rec['dopusk'].'">'.$rec['_dopusk_name_full'].'</div>' ;
        if ($rec['dopusk_user_id']) $rec['_dopusk_status'].='<div class="dopusk_comment">'.$rec['dopusk_user_name'].'<br>'.date('d.m.Y H:i',$rec['dopusk_time']).' - '.date('H:i',$rec['dopusk_time_end']).'</div>' ;
        else $rec['_dopusk_status'].='<div class="dopusk_comment">автоматически<br>'.date('d.m.Y H:i',$rec['dopusk_time']).' - '.date('H:i',$rec['dopusk_time_end']).'</div>' ;
      }

      if ($rec['dopusk']==3)
      { $rec['_dopusk_status']='<div class="dopusk_state_'.$rec['dopusk'].'">'.$rec['_dopusk_name_full'].'</div>' ;
        //if ($rec['dopusk_user_id']) $rec['_dopusk_status'].='<div class="dopusk_comment">'.$rec['dopusk_user_name'].'<br>'.date('d.m.Y H:i',$rec['dopusk_time']).' - '.date('H:i',$rec['dopusk_time_end']).'</div>' ;
        //else $rec['_dopusk_status'].='<div class="dopusk_comment">автоматически<br>'.date('d.m.Y H:i',$rec['dopusk_time']).' - '.date('H:i',$rec['dopusk_time_end']).'</div>' ;
      }

      if ($rec['error']==5)
      { $rec['_dopusk_status']='<div class="red bold dopusk_state_2">Допуск аннулирован</div>'.$rec['dopusk_user_name'].'<br>'.date('d.m.Y H:i:s',$rec['dopusk_time']) ;
        if ($rec['error_reason']) $rec['_dopusk_status'].='<br>Причина<br><strong>'.$rec['error_reason'].'</strong>' ;
      }

      if ($rec['error']==6)
      { $rec['_dopusk_status']='<div class="red bold dopusk_state_2">ЗАПРЕТ ДОПУСКА аннулирован</div>'.$rec['dopusk_user_name'].'<br>'.date('d.m.Y H:i:s',$rec['dopusk_time']) ;
        if ($rec['error_reason']) $rec['_dopusk_status'].='<br>Причина<br><strong>'.$rec['error_reason'].'</strong>' ;
      }

      // результат МО
      // либо все хорошо, либо выводим причину почему плохо
      $_arr=array() ;
      //if ($rec['status']==2)                   $_arr[]='<div class=ok>'.$rec['_status_name'].'</div>' ; // выводится отдельно
      // если есть ошибка - выводим расшифровку ошибки
      if ($rec['reason'])                      $_arr[]='<div class=red>'.$rec['_reason'].'</div>' ;
      if ($rec['equipment'])                   $_arr[]='<div class=red>'.$rec['_equipment'].'</div>' ;
      //if ($rec['question_comment'])            $_arr[]='<div class=red>'.$rec['question_comment'].'</div>' ; //  выводиться отдельно
      // если есть комментарий к автоматическому принятию решения сервером - выводим
      if ($rec['comment'])                     $_arr[]='<div class=red>'.$rec['comment'].'</div>' ;
      if (_sizeof($_arr)) $rec['_comment']=implode('',$_arr) ;

      // опция no_get_MO_image нигде не используется
      // вместо нее передавать опцию get_MO_image_url в тех случаях, когда требуется получить ссылки на изображения МО
      // так как при возврате ссылок провеяется наличие изображения через file_exists что вызывает лишню нагрузку на диск
      if (!$options['no_get_MO_image'])
      {   $img_name='' ;
      if ($rec['member_id'])
          if ($rec['member_img'])   $img_name=$rec['member_img'] ;

          $imgRoot=(isset($options["img_path_relative"]) && $options["img_path_relative"])? "":_PATH_TO_SITE ;
          $img_mode=(isset($options["img_path_relative"]) && $options["img_path_relative"])? 'relative':'url' ;

          if ($img_name) $rec['_member_img']=$imgRoot.'/public/personals/400/'.$img_name ; else  $rec['_member_img']=$imgRoot.'/images/no-avatar-62.png' ;
          $rec['_member_img_auth']=$this->get_mo_img_dir_by_id($rec['pkey'],$img_mode,'auth.jpg') ;
          $rec['_member_img_alco']=$this->get_mo_img_dir_by_id($rec['pkey'],$img_mode,'alco.jpg') ;
          $rec['_member_img_DTW']=$this->get_mo_DTW_img_dir_by_id($rec['pkey'],$img_mode) ;
      // есть по текущему МО нет подписи - смотрим в прошлом МО
          if (!$rec['_member_img_DTW'] and $rec['mo1_id']) $rec['_member_img_DTW']=$this->get_mo_DTW_img_dir_by_id($rec['mo1_id'],$img_mode) ;
          // поле _member_img_DTW_gen не используется
          //$rec['_member_img_DTW_gen']=$this->get_mo_img_dir_by_id($rec['pkey'],$img_mode,'DTW_150.png',array('no_default_img'=>1)) ;
      }

     $rec['_work_name']=_IL('IL_works')->recs[$rec['working']]['obj_name'] ;

      // переделать по поле res_n, поле _pp_id берется из въювера
      if ($rec['res_n'])
      { //$rec['_narko']=$rec['_pp_result'] ;  // поле удалено из вьювера view_mo_session, добавлено во вьювер view_mo_session_pp
        switch($rec['res_n'])
        { case 1:  $rec['_narko_icon']='<img src="/images/eye_green.png">' ; break ;
          case 2:  $rec['_narko_icon']='<img src="/images/eye_black.png">' ; break ;
          case 3:  $rec['_narko_icon']='<img src="/images/eye_red.png">' ; break ;
        }
        //if ($rec['res_n']==1)
        //else if ($rec['res_n']==2),'Недостаточный процент распознания')!==false)  $rec['_narko_icon']='<img src="/images/eye_black.png">' ;
        //else                                                                             $rec['_narko_icon']='<img src="/images/eye_red.png">' ;
      }
      else if ($rec['reason']=='equipmentError' and $rec['equipment']=='pupilometer') $rec['_narko_icon']='<img src="/images/eye_black.png">' ;
      else $rec['_narko_icon']='' ;

      // вопросы есть/нет
      if($rec['question']==1)                                                           $rec['_question']='<span class="red bold">Есть</span>' ;
      else                                                                              $rec['_question']='Нет' ;

      if ($rec['status']==2 or $rec['status']==3) { $rec['_question']=($rec['question']==1)? '<span class="red bold">Есть</span>':'Нет' ; } else $rec['_question']='-' ;

      // озвучиваем решение по алкоголю
      if ($rec['alcotester'])
      {   if ($rec['alko']==-1 and !$rec['equipment']=='alcotester')                        $text='Не додул/ошибка' ;
          else if ($rec['equipment']=='alcotester' and $rec['reason']=='equipmentError')    $text='Сбой замера' ;
          else if ($rec['equipment']=='alcotester' and $rec['reason']=='equipmentFailure')  $text='Неисправность оборудования' ;
          else if ($rec['res_a']==2)                                                        $text='<span class="red bold">Есть</span>' ;
          else if ($rec['res_a']==1)                                                        $text='Нет' ;
          else                                                                              $text='-' ;
          if ($rec['alko_value']>0 and $GLOBALS['LS_view_alcotest_value'])   $text='<span class=nowrap>'.$text.' (<span class="red">'.$rec['alko_value'].'</span>)</span>' ;
          $rec['_alko']=$text ;
      }
      else $rec['_alko']='-';

      if ($rec['tonometer'])
      {   $text='' ;
          if ($rec['systolic']==-1 and $rec['equipment']!='tonometer')                      $text='Измерение не проведено' ;
          else if ($rec['equipment']=='tonometer' and $rec['reason']=='equipmentError')     $text='Сбой замера' ;
          else if ($rec['equipment']=='tonometer' and $rec['reason']=='equipmentFailure')   $text='Неисправность оборудования' ;
          else if ($rec['systolic']>0)                                                      $text=$rec['systolic'] ;
          else if ($rec['systolic']==0)                                                     $text='-' ;
          $rec['_systolic']=$text ;

          $text='' ;
          if ($rec['diastolic']==-1 and $rec['equipment']!='tonometer')                     $text='Измерение не проведено' ;
          else if ($rec['equipment']=='tonometer' and $rec['reason']=='equipmentError')     $text='Сбой замера' ;
          else if ($rec['equipment']=='tonometer' and $rec['reason']=='equipmentFailure')   $text='Неисправность оборудования' ;
          else if ($rec['diastolic']>0)                                                     $text=$rec['diastolic'] ;
          else if ($rec['diastolic']==0)                                                    $text='-' ;
          $rec['_diastolic']=$text ;

          if ($rec['_systolic'] or $rec['_diastolic']) $rec['_sd']=$rec['_systolic'].'/'.$rec['_diastolic'] ;
          if ($rec['_systolic']=='Измерение не проведено' and $rec['_diastolic']=='Измерение не проведено') $rec['_sd']='Измерение не проведено' ;
          if ($rec['_systolic']=='Сбой замера' and $rec['_diastolic']=='Сбой замера') $rec['_sd']='Сбой замера' ;
          if ($rec['_systolic']=='Неисправность оборудования' and $rec['_diastolic']=='Неисправность оборудования') $rec['_sd']='Неисправность оборудования' ;
      }
      else
      { $rec['_systolic']='-' ;
        $rec['_diastolic']='-' ;
        $rec['_sd']='-' ;
      }

      if ($rec['pulsometer'])
      {   $text='' ;
          if ($rec['pulse']==-1 and $rec['equipment']!='pulse')                             $text='Измерение не проведено' ;
          else if ($rec['equipment']=='pulse' and $rec['reason']=='equipmentError')         $text='Сбой замера' ;
          else if ($rec['equipment']=='pulse' and $rec['reason']=='equipmentFailure')       $text='Неисправность оборудования' ;
          else if ($rec['pulse']>0)                                                         $text=$rec['pulse'] ;
          else if ($rec['pulse']==0)                                                        $text='-' ;
          $rec['_pulse']=$text ;
      }
      else $rec['_pulse']='-' ;


      if ($rec['thermometer'])
      {   $text='' ;  $text_csv='' ;
          if (!$rec['pupilometer']) // если есть пупиллометр, температура измеряется пупиллометром
          { if ($rec['temperature']==-1 and $rec['equipment']!='thermometer')                 $text='Измерение не проведено' ;
            else if ($rec['equipment']=='thermometer' and $rec['reason']=='equipmentError')   $text='Сбой замера' ;
            else if ($rec['equipment']=='thermometer' and $rec['reason']=='equipmentFailure'  and !$GLOBALS['LS_esmo_check_thermometr_error']) $text='Неисправность оборудования' ;
            else if ($rec['temperature']>0)                                                   { $text=sprintf('%.1f',$rec['temperature']).'˚' ; $text_csv=sprintf('%.1f',$rec['temperature']) ; }
            else if ($rec['temperature']==0)                                                  $text='-' ;
            $rec['_temperature']=$text ;
            $rec['_temperature_csv']=($text_csv)? $text_csv:$text ;
          }
      } else $rec['_temperature']='-' ;

      // убрали проверку температуры на основе правил пользователя и перевели на флаги проверок
      if ($rec['thermometer'] and ($rec['pupilometer'] or $GLOBALS['LS_view_temp_value_as_text']) and $rec['temperature']>0)
       {
          if ($GLOBALS['LS_view_temp_value_as_text']) {
              if ($rec['res_t']==2) {
              $res='<span class="red">Повышенная температура</span>' ;
              $res_csv='Повышенная температура';
          }
          elseif ($rec['res_t']==3) {
              $res='<span class="red">Пониженная температура</span>' ;
              $res_csv='Пониженная температура';
          }
          else {
              $res='<span class=green>Норма</span>'  ;
              $res_csv='Норма';
          }
          $rec['_temperature']='<div class="view_hint">'.$res.'<span class=hint>'.sprintf('%.1f',$rec['temperature']).'˚</span></div>'  ;
          $rec['_temperature_csv']=$res_csv  ;
          } else {
              $rec['_temperature']=sprintf('%.1f',$rec['temperature']).'˚';
              $rec['_temperature_csv']=sprintf('%.1f',$rec['temperature']);
          }
       }

      // проверка внимания
      if ($rec['vcheck'])
       {  if ($rec['res_v']==2) $res='<span class="red">Не пройден</span>' ;
          else $res='<span class=green>Пройден</span>'  ;
          if (!$rec['v_error']) $rec['v_error']=0 ;
          //$rec['_vcheck']='<div class="view_hint">'.$res.'<span class=hint>'.$rec['v_time'].' '.get_case_by_count_1_2_5($rec['v_time'],'секунда,секунды,секунд').', '.$rec['v_error'].' '.get_case_by_count_1_2_5($rec['v_error'],'ошибка,ошибки,ошибок').', '.$rec['v_ball'].' '.get_case_by_count_1_2_5($rec['v_ball'],'балл,балла,баллов').'</span></div>'  ;
          $rec['_vcheck']='<div class="view_hint">'.$res.'<span class=hint>'.$rec['v_time'].' / '.$rec['v_error'].'</span></div>'  ;
          $rec['_vcheck_csv']=$res  ;

       }

       // включать показ печати по допуску
       if ($options['view_sertificate_stamp'] and $rec['dopusk']==1 and !$rec['tk'])
       {  include_once(_DIR_EXT.'/image_print/i_image_print.php') ;
          if (class_exists($options['view_sertificate_stamp']))
          { $IM = new $options['view_sertificate_stamp']($rec) ;
            $rec['_sertificate_stamp_base64']=base64_encode($IM->get_image_content()) ;
          }
       }

       // включен модуль разбора инцидентов
       if ($GLOBALS['LS_trassir_enable']) {
          if ($rec['terminal_id']) {
              $cnt_cameras=execSQL_value('select count(pkey) from obj_site_trassir_camera_terminal where terminal_id='.$rec['terminal_id'].' or group_id='.$rec['group_id']);
              if ($cnt_cameras) $rec['_use_in_trassir']=1;
          }
          if ($rec['hand_check_user_id']) {
              $cnt_cameras=execSQL_value('select count(pkey) from obj_site_trassir_camera_terminal where hand_check_group_id='.$rec['group_id']);
              if ($cnt_cameras) $rec['_use_in_trassir']=1;
          }
       }
   }

   // Возвращет массив с путем до файла МО заданного типа в трех разных форматах
   // dir - абсолютный путь от корня сервера
   // url - абсолютный URL для доступа к файлу из браузера
   // relative - относительный путь для доступа к файлу из браузера
   // type=auth.jpg,
   // $mode=dir,url,relative

   // для получения имени файла перед его создание необходимо передать опции
   // check_directory и no_check_exist_file

   // в случае если не удасться создать директорию для хранения блока файлов, имя будет сформировано по старой схеме
   // для совместимости с файлами, хранящимися по старой схеме если не найден файл по новой схеме, будет проверка наличия файлов по старой схеме
   // если и по старой схеме нет файла - показываем заглушку

   function get_mo_img_dir_by_id($mo_id,$mode,$type,$options=array())
   {  $max_file_count=10000 ; // максимальное кол-во файлов в директории
      $dir_number=(int)($mo_id/$max_file_count)  ;
      $dir_name_old='/public/mo_photo/' ;
      $file_dir_old=$dir_name_old.$mo_id.'_'.$type ;

      $dir_name='/public/mo_photo/'.$dir_number.'/' ;
      $file_dir_default='/images/no-avatar-62.png' ;

      // при получении имени файла для его последующего сохранения должна передаваться опция check_directory, по ней будет создана нужная директория
      if ($options['check_directory'] and !file_exists(_DIR_TO_ROOT.$dir_name))
      {  // создаем директорию для блока файлов
         if (!@mkdir(_DIR_TO_ROOT.$dir_name))
         { LOGS()->reg_log('create_dir','Не удалось создать директорию '.$dir_name) ;
           LOG_JSON('mo_session')->reg('create_dir','<div class=red>Не удалось создать директорию '.$dir_name.'</div>') ;
           $dir_name=$dir_name_old ; // если не удалось создать директорию - работаем по старой схеме
         }
         //else LOGS()->reg_log('create_dir','Cоздана директория '.$dir_name) ;
      }

      $file_dir=$dir_name.$mo_id.'_'.$type ;

      // при получении имени файла для его последующего сохранения должна передаваться опция no_check_exist_file, по ней будет возвращено имя файла в нужной директории
      if ($options['no_check_exist_file'])                   $result=array('dir'=>_DIR_TO_ROOT.$file_dir,'url'=>_PATH_TO_SITE.$file_dir,'relative'=>$file_dir) ;
      else if (file_exists(_DIR_TO_ROOT.$file_dir))          $result=array('dir'=>_DIR_TO_ROOT.$file_dir,'url'=>_PATH_TO_SITE.$file_dir,'relative'=>$file_dir) ;
      else if (file_exists(_DIR_TO_ROOT.$file_dir_old))      $result=array('dir'=>_DIR_TO_ROOT.$file_dir_old,'url'=>_PATH_TO_SITE.$file_dir_old,'relative'=>$file_dir_old) ;
      else if (!$options['no_default_img'])                  $result=array('dir'=>_DIR_TO_ROOT.$file_dir_default,'url'=>_PATH_TO_SITE.$file_dir_default,'relative'=>$file_dir_default) ;
      else                                                   $result=array('dir'=>'','url'=>'','relative'=>'') ;

      if ($mode) return($result[$mode]) ;
      else return($result) ;
   }

   // тоже что и прошлая функция, но для поиска файла подписи
   // по хранению файл подписи было три версии
   // 1. /public/mo_photo/000_DTW.png
   // 2. /public/mo_photo/XXX/000_DTW.png
   // 3. /public/mo_sign_image/XXX/000_DTW.png
   function get_mo_DTW_img_dir_by_id($session_id,$mode='',$options=array())
   {
      $dir_to_photo=ENGINE()->get_number_dir_by_id($session_id,'/public/mo_sign_image/') ;
      $max_file_count=10000 ; // максимальное кол-во файлов в директории
      $dir_number=(int)($session_id/$max_file_count)  ;
      $fname=$session_id.'_DTW.png' ;

      $file_dir=$dir_to_photo.$fname ;
      $file_dir_old1='/public/mo_photo/'.$dir_number.'/'.$fname ;
      $file_dir_old2='/public/mo_photo/'.$fname ;

      // при получении имени файла для его последующего сохранения должна передаваться опция no_check_exist_file, по ней будет возвращено имя файла в нужной директории
      if ($options['no_check_exist_file'])                   $result=array('dir'=>_DIR_TO_ROOT.$file_dir,'url'=>_PATH_TO_SITE.$file_dir,'relative'=>$file_dir) ;
      else if (file_exists(_DIR_TO_ROOT.$file_dir))          $result=array('dir'=>_DIR_TO_ROOT.$file_dir,'url'=>_PATH_TO_SITE.$file_dir,'relative'=>$file_dir) ;
      else if (file_exists(_DIR_TO_ROOT.$file_dir_old1))     $result=array('dir'=>_DIR_TO_ROOT.$file_dir_old1,'url'=>_PATH_TO_SITE.$file_dir_old1,'relative'=>$file_dir_old1) ;
      else if (file_exists(_DIR_TO_ROOT.$file_dir_old2))     $result=array('dir'=>_DIR_TO_ROOT.$file_dir_old2,'url'=>_PATH_TO_SITE.$file_dir_old2,'relative'=>$file_dir_old2) ;
      else           $result=array('dir'=>'','url'=>'','relative'=>'') ;

      //damp_array($result);
      if ($mode) return($result[$mode]) ;

      else return($result) ;
   }

   // тоже что и прошлая функция, но для поиска DATA подписи
   // по хранению файл подписи было три версии
   // 1. /public/mo_sign/000_DTW.png
   // 2. /public/mo_sign/XXX/000_DTW.png
   function get_mo_DTW_data_dir_by_id($session_id,$mode,$options=array())
   {  $dir_to_photo=ENGINE()->get_number_dir_by_id($session_id,'/public/mo_sign/') ;
      $fname=$session_id.'.data' ;

      $file_dir=$dir_to_photo.$fname ;
      $file_dir_old='/public/mo_sign/'.$fname ;

      // при получении имени файла для его последующего сохранения должна передаваться опция no_check_exist_file, по ней будет возвращено имя файла в нужной директории
      if ($options['no_check_exist_file'])                   $result=array('dir'=>_DIR_TO_ROOT.$file_dir,'url'=>_PATH_TO_SITE.$file_dir,'relative'=>$file_dir) ;
      else if (file_exists(_DIR_TO_ROOT.$file_dir))          $result=array('dir'=>_DIR_TO_ROOT.$file_dir,'url'=>_PATH_TO_SITE.$file_dir,'relative'=>$file_dir) ;
      else if (file_exists(_DIR_TO_ROOT.$file_dir_old))      $result=array('dir'=>_DIR_TO_ROOT.$file_dir_old,'url'=>_PATH_TO_SITE.$file_dir_old,'relative'=>$file_dir_old) ;
      else           $result=array('dir'=>'','url'=>'','relative'=>'') ;

      if ($mode) return($result[$mode]) ;
      else return($result) ;
   }

    // получаеи ID последнего МО и используем его фото
    function get_photo_auth_from_last_mo_session($personal_id)
    {   $value='' ;
        $last_mo_id=execSQL_value('select max(pkey) from obj_site_mo_session where member_id='.$personal_id.' and status in (2,3)') ;
        if (!$last_mo_id)  execSQL_value('select max(pkey) from obj_site_mo_session_now where member_id='.$personal_id.' and status in (2,3)') ;
        if ($last_mo_id)  $value=$this->get_mo_img_dir_by_id($last_mo_id,'dir','auth.jpg') ;
        return($value) ;
    }

   function get_usl_select_mo_by_filter($options=array())
   {   $_usl=array() ; $usl='' ;
       //damp_array($options,1,-1) ;
        $_usl[]=1  ;

        $group_ids='' ;
        if (_sizeof($options['group_ids']))     $group_ids=ACCOUNTS()->get_childs_ids_for_group_ids(array_keys($options['group_ids'])) ;
        else if ($options['group_id']) $group_ids=ACCOUNTS()->get_childs_ids_for_group_ids([$options['group_id']]) ;
        if ($group_ids) $_usl[]='group_id in ('.$group_ids.')' ;


        if ($options['group_id'] and isset(ACCOUNTS()->tree[$options['group_id']])) $_usl[]=(isset(ACCOUNTS()->tree[$options['group_id']]))?  'group_id in ('.ACCOUNTS()->tree[$options['group_id']]->get_list_child().')':'group_id in ('.$options['group_id'].')' ;
        if ($options['member_id']) $_usl[]='member_id='.$options['member_id'] ;
        // предвыборка по имени сотрудника, номеру пропуска или вод.удостоверения
        if ($options['text_info'])
        {   $arr_ids=execSQL_line('select pkey from obj_site_personals where clss=211 and obj_name like "%'.addslashes($options['text_info']).'%" or propusk like "'.addslashes($options['text_info']).'" or driving like "'.addslashes($options['text_info']).'" or tab_number like "'.addslashes($options['text_info']).'"') ;
            if (_sizeof($arr_ids))  $_usl[]='member_id in ('.implode(',',$arr_ids).')' ;
            else                   $_usl[]='member_id=-1' ;
        }
        if ($options['name'])
        {   $arr_ids=execSQL_line('select pkey from obj_site_personals where clss=211 and obj_name like "%'.addslashes($options['name']).'%"') ;
            if (_sizeof($arr_ids))  $_usl[]='member_id in ('.implode(',',$arr_ids).')' ;
            else                   $_usl[]='member_id=-1' ;
        }
        if ($options['propusk'])
        {   $arr_ids=execSQL_line('select pkey from obj_site_personals where clss=211 and propusk like "'.addslashes($options['propusk']).'"') ;
            if (_sizeof($arr_ids))  $_usl[]='member_id in ('.implode(',',$arr_ids).')' ;
            else                   $_usl[]='member_id=-1' ;
        }
        // номера сессий MO
        if ($options['mo_schedule'])  $_usl[]='mo_schedule = '.($options['mo_schedule']-1) ;
        if ($options['mo_ids'])     $_usl[]='pkey in ('.$options['mo_ids'].')' ;
        if ($options['to_mo_id'])     $_usl[]='pkey< '.$options['to_mo_id'].'' ;
        // время передаваемое в unix формате
        if ($options['time_from'])     { $_usl[]='c_data>='.$options['time_from'] ; if ($options['debug']) echo 'Дата от '.date('d.m.Y H:i:s',$options['time_from']).'<br>' ; }
        if ($options['time_to'])       { $_usl[]='c_data<='.$options['time_to'] ; if ($options['debug']) echo 'Дата до '.date('d.m.Y H:i:s',$options['time_to']).'<br>' ; }
         //echo 'time_from='.date('d.m.Y H:i',$options['time_from']).'<br>' ;

        // время передаваемое в текстовом формате
        if ($options['data_from'])     { $_usl[]='c_data>='.strtotime($options['data_from']) ; if ($options['debug']) echo 'Дата от '.date('d.m.Y H:i:s',strtotime($options['data_from'])).'<br>' ; }
        if ($options['data_to'])       { $arr=explode(' ',trim($options['data_to'])) ;
                                         $time_to=(!$arr[1])? strtotime($options['data_to'].' 23:59:59'):strtotime($options['data_to']) ;
                                         $_usl[]='c_data<='.$time_to ;
                                         if ($options['debug']) echo 'Дата до '.date('d.m.Y H:i:s',$time_to) ;
                                       }
        // терминал
        if ($options['terminal_id'])  $_usl[]='(terminal_id in ('.$options['terminal_id'].') or terminal_id is null)' ;
        if ($options['terminal_id_only'])  $_usl[]='(terminal_id in ('.$options['terminal_id_only'].'))' ;
        if ($options['doctor_id'])     $_usl[]='(doctor_id='.$options['doctor_id'].' or dopusk_user_id='.$options['doctor_id'].' or hand_check_user_id='.$options['doctor_id'].')' ;
        if ($options['doctor_id_or_any'])  $_usl[]='(doctor_id='.$options['doctor_id_or_any'].' or dopusk_user_id='.$options['doctor_id_or_any'].' or hand_check_user_id='.$options['doctor_id_or_any'].' or doctor_id=0 or doctor_id is null)' ;

        // допуск
        if (isset($options['dopusk_arr'])) $_usl[]='dopusk in ('.implode(',',array_keys($options['dopusk_arr'])).')' ;
        elseif (isset($options['dopusk']))     $_usl[]='dopusk in ('.$options['dopusk'].')' ;

        // статус МО - начат, пройден, не пройден, прерван
        if ($options['status']) {
            if (is_array($options['status'])) {
                $_usl[]='status in ('.implode(',',array_keys($options['status'])).')' ;
            } else {
                $_usl[]='status in ('.$options['status'].')' ;
            }
        }
        //
        if ($options['only_check_success'])        $_usl[]='message_terminal="success"'  ;
        if ($options['reader'])        $_usl[]='reader="'.$options['reader'].'"'  ;
        //
        if ($options['only_member_enabled'])        $_usl[]='member_enabled=1'  ;
        if ($options['only_member_disabled'])        $_usl[]='member_enabled=0'  ;

        if ($options['intrusion']==1)        $_usl[]='reason!="intrusion"';
        if ($options['intrusion']==2)        $_usl[]='reason="intrusion"' ;

        //if ($options['denited_auto'])  $_usl[]='dopusk=2 and (dopusk_user_id is null or dopusk_user_id=0)' ;
        //if ($options['denited_hand'])  $_usl[]='dopusk=2 and dopusk_user_id>0' ;
        //if ($options['handmade'])      $_usl[]='hand_check_user_id>0' ;
        //if ($options['dopusk_user_id'])      $_usl[]='hand_check_user_id>0' ;
        if ($options['only_model']=='all') $_usl[]='model>0' ; else if ($options['only_model'] or $options['only_model']==='0') $_usl[]='model in ('.$options['only_model'].')' ;
        // тип контроля - предсменный, послесменный
        if ($options['tk']==1)         $_usl[]='tk=0' ;
        if ($options['tk']==2)         $_usl[]='tk=1' ;
        if ($options['tk']==3)         $_usl[]='tk=2' ;
        // отдел или организация сотрудника
        if ($options['org_id'])        $_usl[]='personal_parent2="'.$options['org_id'].'"' ;
        if ($options['otdel_id'])      $_usl[]='personal_parent3="'.$options['otdel_id'].'"' ;
        if (_sizeof($options['working'])) $_usl[]='working in ('.implode(',',array_keys($options['working'])).')' ;

        // check_filter_array - проверяет где находится организации - в ключе или в значениях
        // организации или отделы сотрудника
        if ($options['org_ids'])
            if (is_array($options['org_ids'])) { if (_sizeof($options['org_ids']))   $_usl[]='personal_parent2 in ('.implode(',',$this->check_filter_array($options['org_ids'])).')' ; }
            else                               { $_usl[]='personal_parent2 in ('.$options['org_ids'].')' ; }
        if ($options['otdel_ids'])
            if (is_array($options['otdel_ids'])) { if (_sizeof($options['otdel_ids'])) $_usl[]='personal_parent3 in ('.implode(',',$this->check_filter_array($options['otdel_ids'])).')' ;}
            else                               $_usl[]='personal_parent3 in ('.$options['otdel_ids'].')' ;

       if ($options['dep_id'])
       {  $dep_level=execSQL_value('select level from obj_site_personals where pkey='.$options['dep_id']) ;
          $_usl[]='personal_parent'.$dep_level.'='.$options['dep_id'] ;

       }

       if ($options['personal_id'])   $_usl[]='personal_id in ('.$options['personal_id'].')' ;
        // причина непрохождения МО
        if ($options['res_stat']['no_a']) $_usl[]='res_a!=2' ;
        if ($options['res_stat']['a']) $_usl[]='res_a=2' ;
        if ($options['res_stat']['d']) $_usl[]='(res_s in (2,3) or res_d in (2,3))' ;
        if ($options['res_stat']['p']) $_usl[]='res_p in (2,3)' ;
        if ($options['res_stat']['t']) $_usl[]='res_t in (2,3)' ;
        if ($options['res_stat']['q']) $_usl[]='question=1' ;
        if ($options['res_stat']['n']) $_usl[]='res_n in (2,3)' ;
        if ($options['res_stat']['v']) $_usl[]='res_v=2' ;


        if ($options['min_s']) $_usl[]='systolic>='.$options['min_s'] ;
        if ($options['max_s']) $_usl[]='systolic<'.$options['max_s'] ;

        if ($options['res_stat']['ssz']) $_usl[]='(res_s in (2,3) or res_d in (2,3) or res_p in (2,3))' ;
        if ($options['res_stat']['other']) $_usl[]='res_a<=1 and res_s<=1 and res_d<=1 and res_p<=1' ;
        if ($options['res_stat']['other2']) $_usl[]='res_a<=1 and res_s<=1 and res_d<=1' ;

        // условие по ошибке оборудования
        if ($options['res_stat']['e_dev']) $_usl[]='reason="equipmentFailure"' ;

        if ($options['otkaz_mo']) $_usl[]='reason="equipmentError"' ;


        if (isset($options['reason']))    $_usl[]=$this->get_usl_from_array($options['reason']) ;
        if (isset($options['no_reason'])) $_usl[]='reason!="'.$options['no_reason'].'"' ;
        if (isset($options['equipment'])) $_usl[]=$this->get_usl_from_array($options['equipment']) ;


        //if ($options['otkaz_mo'])            $_usl[]=' result>0' ;
        // !!!skoro использует параметр smena_from
       // if ($options['skoro'])               $_usl[]=' (status=3 or (status=4 and (reason="nonRule" or reason="failedMO"))) and (dopusk is null or dopusk=0) and tk in ('.$GLOBALS['LS_mo_doctor_use_tk'].') and not member_id in (select distinct(member_id) from obj_site_mo_session where c_data>='.$options['skoro'].' and dopusk in (1,2))' ;


      /* if ($options['skoro'])               $_usl[]=' (status=3 or
                                                        (status=4 and (reason="nonRule" or reason="failedMO"))
                                                        ) and

                                                        (dopusk is null or dopusk=0)
                                                        and tk in ('.$GLOBALS['LS_mo_doctor_use_tk'].')
                                                        and not member_id in (select distinct(member_id) from obj_site_mo_session where c_data>='.$options['skoro'].' and dopusk in (1,2))' ;
       */
       if ($options['skoro'])               $_usl[]=' ((  (model=2 or model=4) 
                                                          or (reason like "intrusion" and status=2 and dopusk=0)
       
       
                                                        ) 
       
       
                                                        and c_data>='.$options['skoro'].') ' ;






        if ($options['dopusk_member_allow']) $_usl[]=' dopusk_user_id='.$options['dopusk_member_allow'] ;

        if ($options['only_unscripted']) $_usl[]='(report_id=0 or report_id is null) ' ; // только неподписанные
        if ($options['only_scripted'])   $_usl[]='report_id>0' ; // только подписанные
        if ($options['use_usl'])   $_usl[]=$options['use_usl'] ;


       if ($options['use_member_personal_filter'] and MEMBER()->personal_viewer_name and MEMBER()->rol!=1) $_usl['account_personal_filter']='personal_id in (select pkey from '.MEMBER()->personal_viewer_name.')' ;

        $usl_gb=[];
        if (_sizeof($options['group_pers'])) foreach($options['group_pers'] as $group_id=>$flag) $usl_gb[]='personal_id in (select pkey from view_personals_group_'.$group_id.')' ;
        if (_sizeof($usl_gb)) $_usl[]='('.implode(' or ',$usl_gb).')' ;

        //damp_array($options,1,-1) ;
        //damp_array($_usl,1,-1) ;
        //$options['debug'] =2 ;
        //$debug=$options['debug'] ;
        if (_sizeof($_usl)) $usl=implode(' and ',$_usl) ;
        return($usl) ;
   }

   function check_filter_array($arr)
   { list($id,$value)=each($arr) ;
     if (!$id) return($arr) ;
     else return(array_keys($arr)) ;

   }

   function get_usl_from_array($arr)
   {  if (is_array($arr) and _sizeof($arr))
      {  $_tt=array() ;
         foreach($arr as $tt) $_tt[]='reason="'.$tt.'"' ;
         $str='('.implode(' or ',$_tt).' )' ;
      }
      else $str='reason="'.$arr.'"' ;
      return($str) ;
   }

   // позвращаем НЕПОДПИСАННЫЕ записи МО
   function get_mo_recs($options=array())
   { $order=($options['order'])? $options['order']:'pkey desc' ;
     $limit='' ;
     if ($options['limit'])   $limit=' limit '.$options['limit'] ;
     //$join = '';
     //if ($options['join'])   $join=' left join '.$options['join'] ;
     $usl=$this->get_usl_select_mo_by_filter($options);
     if ($options['debug']) echo 'usl='.$usl.'<br>' ;
     // поле sign_id включено в вьювер
     $fields=($options['fields'])? $options['fields']:'*' ;
     //$options['debug']=0 ;
     $table_name=($options['view_name'])? $options['view_name']:$this->view_mo_session ;
     $recs=execSQL('select '.$fields.' from '.$table_name.' where '.$usl.' order by '.$order.$limit,array('debug'=>$options['debug'])) ;
     if (_sizeof($recs) and !$options['no_public_info']) foreach($recs as $id=>$rec) $this->prepare_public_info_to_mo($recs[$id],$options) ;
     //if (!$options['no_stats']) $stats=execSQL_van('select min(c_data) as time_from,max(c_data) as time_to,count(pkey) as cnt from '.$this->table_mo_sessions.' t1 where '.$usl)  ;
     else $stats=array() ;
     //print_2x_arr($recs);
     return(array($recs,$stats)) ;
   }

    // возвращает последний МО с терминала в пределах срока действия мед.допуска
    function get_last_mo_rec_from_terminal_in_allow_time($member_id)
    { $now=getdate(time()) ; $rec=array() ;
      $from=mktime($now['hours']-$GLOBALS['LS_setting_auto_mo_allow_interval'],$now['minutes'],$now['seconds'],$now['mon'],$now['mday'],$now['year']);
      $last_mo_id=execSQL_value('select pkey from '.$this->table_mo_sessions_now.' where member_id="'.$member_id.'" and terminal_id>0 and c_data>='.$from.' and status in (2,3) order by c_data desc limit 1') ;
      if ($last_mo_id)
      {   $rec=execSQL_van('select * from '.$this->view_mo_session_now.' where pkey='.$last_mo_id) ;
          $this->prepare_public_info_to_mo($rec) ;
      }
      return($rec) ;
    }

    function get_last_mo_rec_in_dopusk_time($member_id,$options=array()) { return($this->check_active_dopusk($member_id,$options));}
    function check_active_dopusk($member_id,$options=array())
    { ob_start() ;
      $rec=array() ;
      echo 'Получаем активные допуски/недопуски свыше текущено времени - '.date('d.m.Y H:i:s',time()).'<br>' ;
      $usl=array() ;
      $usl[]='member_id='.$member_id ;
      if (!$options['dopusk']) $usl[]='dopusk in (1,2) and dopusk_time_end>'.time() ;
      else if (is_array($options['dopusk']))   $usl[]='dopusk in ('.implode(',',$options['dopusk']).') and dopusk_time_end>'.time() ;
      else                                     $usl[]='dopusk in ('.$options['dopusk'].') and dopusk_time_end>'.time() ;
      // опция no_check_tk добавлена для поста печати, где надо делать вывод всех типов МО
      if (!$options['no_check_tk']) $usl[]='tk in (0,2)' ; // только предсменные и межсменные МО
      $usl_select=implode(' and ',$usl) ;
      $last_mo_id=execSQL_value('select pkey from '.$this->table_mo_sessions_now.' where '.$usl_select.' order by c_data desc limit 1',array('debug'=>1)) ;
      if ($last_mo_id)
      {   $rec=execSQL_van('select * from '.$this->view_mo_session_now.' where pkey='.$last_mo_id) ;
          if (!$options['no_public_info']) $this->prepare_public_info_to_mo($rec) ;
      }
      $text=ob_get_clean() ;
      LOG_JSON('mo_session')->reg('check_active_dopusk',$text) ;
      return($rec) ;
    }

    // проверяем превышение числа последних запретов допуска подряд и в случае обнаружения превышения - отправляем уведомление
    // используем настройки
    // -  LS_setting_max_DD_check - маскимальное число запретов допуска продряд (обычно два)
    // -  LS_setting_max_DD_count_hour - время блокировки МО после двух МО подряд, от первого МО из серии
    function check_count_DD_to_personal($personal_id)
    {  if ($GLOBALS['LS_setting_max_DD_check'])
       {  // проверяем число недопусков подряд
          ob_start() ;
          echo 'LS_setting_max_DD_check='.$GLOBALS['LS_setting_max_DD_check'].'<br>' ;
          if ($GLOBALS['LS_setting_max_DD_check'])
            {  $arr_DD=ESMO()->check_count_nedopusk($personal_id,array('return_arr'=>1,'debug'=>2)) ;
               damp_array($arr_DD,1,-1) ;
               if (_sizeof($arr_DD)>=$GLOBALS['LS_setting_max_DD_count'])
               {  ksort($arr_DD) ;  // самый старый МО - в начало списка
                  $first_mo=reset($arr_DD) ; // получить данные по первому МО
                  echo 'Первый запрет допуска: '.date('d.m.Y H:i:s',$first_mo) ;
                  $now=getdate($first_mo) ;
                  $to=mktime($now['hours']+$GLOBALS['LS_setting_max_DD_count_hour'],$now['minutes'],0,$now['mon'],$now['mday'],$now['year']);
                  echo 'Конец блокировки: '.date('d.m.Y H:i:s',$to) ;
                  PERSONAL()->message_personal_create(array('mess_text'=>'Более двух запретов допуска, следущая проверка не ранее '.date('d.m.Y H:i:s',$to),
                                                           'group_id'=>MEMBER()->cur_group_id,
                                                           'account_id'=>MEMBER()->id,
                                                           'personal_id'=>$personal_id,
                                                           'view_from'=>time(),
                                                           'view_to'=>$to,
                                                           'block_from'=>time(), // срок - 10 дней от даты получения направления
                                                           'block_to'=>$to, // срок - 10 дней от даты получения направления
                                                           //'view_mode'=>1, // показывать при прохождении МО
                                                           //'block_mo'=>1, // блокировать прохождение МО
                                                           'auto_close'=>$to, // автозакрытие сообщения после срока окончания показа
                                                          )) ;

               }
            }
          $text=ob_get_clean() ;
          LOG_JSON('mo_session')->reg('check_max_DD_count',$text) ;
       }
    }


    // получаем число последних подряд недопусков за указанный период времени
    function check_count_nedopusk($member_id,$options=array())
    { $usl=array() ; $now=getdate(time()) ;
      $max_DD_check=$GLOBALS['LS_setting_max_DD_count'] ;
      $max_DD_count_hour=$GLOBALS['LS_setting_max_DD_count_hour'] ;
      $from=mktime($now['hours']-$max_DD_count_hour,$now['minutes'],$now['seconds'],$now['mon'],$now['mday'],$now['year']);
      if ($options['debug']) echo 'Получаем число последних недопусков подряд от - '.date('d.m.Y H:i:s',$from).', макс '.$GLOBALS['LS_setting_max_DD_count'].' недопуска<br>' ;
      $usl[]='member_id='.$member_id ;
      $usl[]='model>0 and dopusk>0' ;
      $usl[]='c_data>='.$from ;
      //$usl[]='tk in (0,2)' ; // только предсменные и межсменные МО
      $usl_select=implode(' and ',$usl) ;
      $last_mo_recs=execSQL('select pkey,model,dopusk,c_data from '.$this->table_mo_sessions_now.' where '.$usl_select.' order by pkey desc',array('debug'=>$options['debug'])) ;
      $arr_nedopusk=array() ; // массив - недоспуски подряд
      if (_sizeof($last_mo_recs)) foreach($last_mo_recs as $rec)
      { if ($rec['dopusk']==2)
        { $arr_nedopusk[$rec['pkey']]=$rec['c_data'] ;
          if (_sizeof($arr_nedopusk)==$max_DD_check) break ;
             }
        else { $arr_nedopusk=array() ; break ; }
      }
      if ($options['debug']) damp_array($arr_nedopusk,1,-1) ;
      if ($options['return_arr']) return($arr_nedopusk) ;
      else return(_sizeof($arr_nedopusk)) ;
    }
    /* не используется
    function get_rec_mo_by_id($id,$options=array())
    {   $rec=array() ;
        $debug=$options['debug'] ;
        if ($id)
        {$rec=execSQL_van('select t1.*,t2.obj_name as member_name,t2.pkey as member_id,t2.working,t2.age,t2.propusk from '.$this->table_mo_sessions.' t1 '.
                   'left join '.PERSONAL()->table_personal.' t2 on t2.pkey=t1.member_id '.
                   'where t1.pkey='.$id,$debug) ;
        }
        return($rec) ;
    }
    */

    function get_mo_by_id($id,$options=array())
    {   $rec=array() ;
        if ($id)
        { $rec=execSQL_van('select * from '.$this->view_mo_session_now.' where pkey='.$id,array('debug'=>$options['debug'])) ;
          if (!$rec['pkey']) $rec=execSQL_van('select * from '.$this->view_mo_session.' where pkey='.$id,array('debug'=>$options['debug'])) ;
          if ($rec['pkey'] and !$options['no_public_info']) $this->prepare_public_info_to_mo($rec,$options) ;
        }
        return($rec) ;
    }

    function get_mo_by_id_now($id,$options=array())
    {   $rec=array() ;
        if ($id)
        { $rec=execSQL_van('select * from '.$this->view_mo_session_now.' where pkey='.$id,array('debug'=>$options['debug'])) ;
          if ($rec['pkey'] and !$options['no_public_info']) $this->prepare_public_info_to_mo($rec,$options) ;
        }
        return($rec) ;
    }

    function get_mo_by_ids($ids,$options=array())
    {   $recs=array() ;
        if (_sizeof($ids))
        { $recs=execSQL('select * from '.$this->view_mo_session.' where pkey in ('.implode(',',$ids).')',array('debug'=>$options['debug'])) ;
          if (_sizeof($recs) and !$options['no_public_info']) foreach($recs as $id=>$rec) $this->prepare_public_info_to_mo($recs[$id],$options) ;
        }
        return($recs) ;
    }

    function get_mo_by_ids_now($ids,$options=array())
    {   $recs=array() ;
        if (_sizeof($ids))
        { $recs=execSQL('select * from '.$this->view_mo_session_now.' where pkey in ('.implode(',',$ids).')',array('debug'=>$options['debug'])) ;
          if (_sizeof($recs) and !$options['no_public_info']) foreach($recs as $id=>$rec) $this->prepare_public_info_to_mo($recs[$id],$options) ;
        }
        return($recs) ;
    }

    /* не используется
    function get_mo_by_URL($URL)
    {   $arr=explode('.',$URL) ; //damp_array($arr) ;
        $rec=$this->get_mo_by_id($arr[0]) ;
        return($rec) ;
    } */

    function get_mo_recs_to_personal($member_id,$options=array())
    {   $options['member_id']=$member_id ;
        list($mo_rec,$stats)=$this->get_mo_recs($options) ;
        return($mo_rec) ;
    }

    // используется в РМТ
    function get_last_mo_rec_to_personal($member_id,$options=array())
    {   $options['member_id']=$member_id ;
        $options['limit']=1 ;
        list($mo_recs,$stats)=$this->get_mo_recs($options) ;
        $rec=array() ;
        if (_sizeof($mo_recs)) list($id,$rec)=each($mo_recs) ;
        return($rec) ;
    }

    function set_model_to_session_mo($mo_session_id,$options=array())
      {     $rec=execSQL_van('select * from '.$this->view_mo_session_now.' where pkey='.$mo_session_id,array('debug'=>$options['debug'])) ;
            $model=0 ;
            /// !!! в случае непрохождения терминала, недоступ автоматичски не ставиться.
            //  допуск автоматическидается только в случае успешного прохождения терминала
            // соответсвенно значение поля $rec['dopusk']==2 говорит о том, что сотрудник был у врача
            // а $rec['dopusk']==1 и $rec['status'] ==2   говорит о том, что сотрудник был у врача
            // смотрим предыдущую запись по МО для т
            //echo 'id='.$mo_session_id.'<br>' ;
            $rec_prev_mo=array() ;  $data=array() ;
            $sec=$GLOBALS['LS_mo_session_lenght']*60*60 ;
            $from=$rec['c_data']-$sec;




            if ($rec['member_id'] and $rec['mo1_id'])
            { // добавлено, что не учитывать МО с аннулированными результатами
              //if ($options['debug']) echo 'Ищем МО пользователя '.$rec['member_id'].' с MO_ID<'.$mo_session_id.' дата МО не позднее чем '.date('d.m.Y H:i:s',$from).' статус 2 или 3, error!=5,6<br>' ;
              //$rec_prev_mo=execSQL_van('select * from '.$this->table_mo_sessions.' where member_id='.$rec['member_id'].' and pkey<'.$mo_session_id.' and c_data>='.$from.' and status in (2,3) and not error in (5,6) order by pkey desc limit 1',array('debug'=>$options['debug'])) ;
              //$rec_prev_mo=execSQL_van('select * from obj_site_mo_session where member_id="'.$rec['member_id'].'" and c_data>='.$rec['c_data'].' and status in (2,3) and (dopusk=0 or dopusk is null) order by pkey desc limit 1') ;
                               //execSQL('select * from '.$this->table_mo_sessions.' where member_id='.$rec['member_id'].' and pkey<'.$mo_session_id.' and c_data>='.$from.' and status in (2,3) order by pkey desc',2) ;
              // предыдущее МО уже указано в mo1_id - оно заполняется при открытии сессии МО
              $rec_prev_mo=execSQL_van('select pkey,model from '.$this->table_mo_sessions_now.' where pkey='.$rec['mo1_id']) ;
            }


            define('MO1',1) ; define('MO2',2) ; // mo_type
            define('OK',2) ; define('ALERT',3) ; // status
            define('YES',1) ; define('NO',2) ; // dopusk
            //---------------------------------
            if ($rec['mo_type']==MO1 and                  // первичный МО
                $rec['status'] ==OK                       // проверка = "OK"
               )
            $model=1 ;                             // МО1+ : МО пройден по результатам первичной проверки на терминале, допуск выдается автоматом
            //---------------------------------
            if ($rec['mo_type']==MO1 and                  // первичный МО
                $rec['status']==ALERT and                 // проверка = "ALERT"
                (!$rec['dopusk'] or $rec['dopusk']==3)                          // допуск не определн
               )
            $model=2 ;                             // МО1- : МО не пройден по результатам первичной проверки на терминале, сотрудник более ни к кому не обращался, ждет 15 мин до следующей проверки
            //---------------------------------
            if ($rec['mo_type']==MO2 and                  // вторичный МО
                $rec['status'] ==OK                       // проверка = "OK"
               )
            $model=3 ;                             // МО1-, МО2+ : МО пройден по результатам повторной проверки на терминале
            //---------------------------------
            if ($rec['mo_type']==MO2 and                  // вторичный МО
                $rec['status']==ALERT and                 // проверка = "ALERT"
            (    !$rec['dopusk'] or $rec['dopusk']==3)                           // допуск не определн
               )
            $model=4 ;                             // МО1-, МО2- : МО не пройден по результатам повторной проверки на терминале, сотрудник более ни к кому не обращался
            //---------------------------------
            if ($rec['mo_type']==MO2 and                  // вторичный МО
                $rec['status']==ALERT and                 // проверка = "ALERT"
                $rec['dopusk']==2 and                        // допуск запрещен
                $GLOBALS['LS_setting_auto_nedopusk']
               )
            $model=4 ;                             //  : МО не пройден по результатам повторной проверки на терминале, допуск запреш автомаатическ
            //---------------------------------

            // видим что был задан допуск вручную. (поле dopusk_user_id содержит значение)
            // Значит сотрудник пошел к врачу, значит проверку на терминале не прошел
            //---------------------------------
            if ($rec['hand_check_user_id'] and              // врач провел проверку
                !$rec['terminal_id'] and                    // и это не было проверка на терминале
                $rec_prev_mo['model']==4 and                // до этого было МО1-, МО2-
                $rec['dopusk']==YES                         // допуск = "YES"
               )
            $model=5 ;                                      // МО1-, МО2-, РМВ+
            //---------------------------------
            if ($rec['hand_check_user_id'] and              // врач провел проверку
                !$rec['terminal_id'] and                    // и это не было проверка на терминале
                $rec_prev_mo['model']==4 and                // до этого было МО1-, МО2-
                $rec['dopusk']==NO                          // допуск = "NO"
               )
            $model=6 ;                                      // МО1-, МО2-, РМВ- ; МО не пройден по результатам первичной проверки на терминале, и сотрудник не получил допуск через врача
            //---------------------------------
            if ($rec['hand_check_user_id'] and              // врач провел проверку
                !$rec['terminal_id'] and                    // и это не было проверка на терминале
                $rec_prev_mo['model']==2 and                // до этого было МО1-
                $rec['dopusk']==YES                         // допуск = "YES"
               )
            $model=7 ;                                      // МО1-, РМВ+ ;
            //---------------------------------
            if ($rec['hand_check_user_id'] and              // врач провел проверку
                !$rec['terminal_id'] and                    // и это не было проверка на терминале
                $rec_prev_mo['model']==2 and                // до этого было МО1-
                $rec['dopusk']==NO                          // допуск = "NO"
               )
            $model=8 ;                                      // МО1-, РМВ- ; МО не пройден по результатам первичной проверки на терминале, и сотрудник не получил допуск через врача
            //---------------------------------
            if ($rec['hand_check_user_id'] and              // врач провел проверку
                !$rec['terminal_id'] and                    // и это не было проверка на терминале
                !$rec_prev_mo['pkey'] and                   // до этого не было МО
                $rec['dopusk']==YES                         // и
            )
            $model=9;                                       // РМВ+ ;  сотрудник получил допуск через врача
            //---------------------------------
            if ($rec['hand_check_user_id'] and              // врач провел проверку
                !$rec['terminal_id'] and                    // и это не было проверка на терминале
                !$rec_prev_mo['pkey'] and                   // до этого не было МО
                $rec['dopusk']==NO                          // и
            )
            $model=10;                                       // РМВ- ; сотрудник НЕ получил допуск через врача
          //echo '$model='.$model.'<br>' ;
          //$data['mo1_id']=0 ; - задается только при открытии сессии МО
          //if ($rec_prev_mo['pkey'] and !$rec_prev_mo['dopusk'])   - $rec_prev_mo не может быть с допуском
          if ($rec_prev_mo['pkey'])
                                    { $prev_data=array('model'=>0) ;
              //if ($rec_prev_mo['dopusk']==3) $prev_data['dopusk']=0 ; - $rec_prev_mo не может быть с допуском
        				              $this->update_mo_session($rec_prev_mo['pkey'],$prev_data) ; // сбрасываем модель у первичного МО, чтобы не учавствовала в статистике
              //$data['mo1_id']=$rec_prev_mo['pkey'] ; - уже задано ранее
                                    }
          $data['model']=(int)$model ;
          $data['temp']=1 ;
          $this->update_mo_session($mo_session_id,$data) ;
          return($model) ;
      }

    function on_event_fixed_hand_check_allow($options=array())
    {
        ob_start() ; $rec_mo=array() ;
        if ($options['mo_id']) $rec_mo=ESMO()->get_mo_by_id($options['mo_id']) ;
        $text=ob_get_clean() ;
        LOG_JSON('mo_session')->reg('on_event_fixed_hand_check_allow',$text) ;
    }
    function on_event_fixed_hand_check_denited($options=array())
    {
        ob_start() ; $rec_mo=array() ;
        if ($options['mo_id']) $rec_mo=ESMO()->get_mo_by_id($options['mo_id']) ;
        $text=ob_get_clean() ;
        LOG_JSON('mo_session')->reg('on_event_fixed_hand_check_denited',$text) ;
    }

    function on_event_hand_check_clear($options=array())
    {
        ob_start() ; $rec_mo=array() ;
        if ($options['mo_id']) $rec_mo=ESMO()->get_mo_by_id($options['mo_id']) ;
        $text=ob_get_clean() ;
        LOG_JSON('mo_session')->reg('on_event_hand_check_clear',$text) ;
    }


    // обрабочик события прошедшего МО
    function on_event_examination_result($options=array())
      {   $rec_mo=$this->get_mo_by_id($options['mo_id']) ;
          // отправка уведомления, если был выявлен алкоголь
          if ($GLOBALS['LS_mo_notife_alco'])
          { if ($rec_mo['alcotester'] and $rec_mo['res_a']==2 and $rec_mo['model'] and ($rec_mo['dopusk']==2 or $rec_mo['dopusk']==3))  $this->send_email_notice_by_alco($rec_mo) ;
          }

      // синхронная отправка данных на шлюз
          if ($GLOBALS['LS_mo_push_sync'] and ($rec_mo['dopusk']==1 or $rec_mo['dopusk']==2))  $this->send_push_mo_result_sync($options['mo_id']) ;

          // // если человек был в статусе отложенного увольнения, после прохождения МО этот статус снимается
          if ($rec_mo['personal_id']) PERSONAL()->personal_fired_pause_cancel($rec_mo['personal_id']) ;

    }

    function send_email_notice_by_alco($rec_mo)
        { // отправляем уведомление о наличии алкоголя
          ob_start();

            ?><strong>Добрый день!</strong><br>
            При прохождении МО был выявлен алкоголь:<br>
            <table>
                <tr><td style="text-align:left;">Показания прибора</td><td><?echo $rec_mo['alko_value']?></td></tr>
                <tr><td style="text-align:left;">ФИО сотрудника</td><td><?echo $rec_mo['personal_name']?> [UID: <?echo $rec_mo['member_uid']?>]</td></tr>
                <tr><td style="text-align:left;">Место работы</td><td><?echo $rec_mo['_org_name']?>, <?echo $rec_mo['_otdel_name']?></td></tr>
                <tr><td style="text-align:left;">Дата/время медицинского осмотра</td><td><?echo $rec_mo['_data']?></td></tr>
                <tr><td style="text-align:left;">ФИО фельдшера</td><td><?echo $rec_mo['_doctor_name']?></td></tr>
            <tr><td style="text-align:left;">Комментарий фельдшера</td><td><?echo $rec_mo['doctor_comment']?></td></tr>
                <tr><td style="text-align:left;">Рабочая группа</td><td><?echo $rec_mo['group_name']?></td></tr>
                <tr><td style="text-align:left;">Номер терминала</td><td><?echo ($rec_mo['terminal_id'])? $rec_mo['terminal_id']:'РМВ'?></td></tr>
                <tr><td style="text-align:left;">ID медицинского осмотра</td><td><?echo $rec_mo['pkey']?></td></tr>
            </table>
          <?
          $text = ob_get_clean();
         $rec_org=PERSONAL()->get_org_by_id($rec_mo['personal_parent2']) ;
         $rec_otdel=PERSONAL()->get_otdel_by_id($rec_mo['personal_parent3']) ;
         $arr_str_email=array() ;
         echo 'основной email для отправки уведомлений по алкоголю: '.$GLOBALS['LS_mo_notife_alco_email'].'<br>' ;
         if ($GLOBALS['LS_mo_notife_alco_email']) $arr_str_email[]=$GLOBALS['LS_mo_notife_alco_email'] ;
         if ($rec_org['_ext_info']['notify_email'] ) $arr_str_email[]=$rec_org['_ext_info']['notify_email'] ;
         echo 'email организации для отправки уведомлений по алкоголю: '.$rec_org['_ext_info']['notify_email'].'<br>' ;
         if ($rec_otdel['_ext_info']['notify_email']) $arr_str_email[]=$rec_otdel['_ext_info']['notify_email'] ;
         echo 'email подразделения для отправки уведомлений по алкоголю: '.$rec_otdel['_ext_info']['notify_email'].'<br>' ;
         $str_email=implode(',',$arr_str_email) ;

         $str_email=str_replace(array(' ',';'),',',$str_email) ;
         $arr_emails=explode(',',$str_email) ;
         if (_sizeof($arr_emails))
         { $email=trim($arr_emails[0]) ; unset($arr_emails[0]) ;
           $mail_options['cc']=array() ;
           $mail_options['debug']=1;
           $mail_options['no_asyns_send_mail']=1;
           if (_sizeof($arr_emails)) foreach($arr_emails as $cc_email) if (trim($cc_email)) $mail_options['cc'][trim($cc_email)]=trim($cc_email) ;
           MAILS()->send_mail($email,'Автоматическое уведомление о выявлении алкоголя на МО',$text,$mail_options);
         }

            $text = ob_get_clean();
            echo $text;
            $name = LOGS()->reg_file_log('send_email_alco_notife',$text);
            LOGS()->reg_log('Автоматическое уведомление о выявлении алкоголя на МО','<a target=_blank href="' . $name . '">Отчет</a>'.$text);
        LOG_JSON('mo_session')->reg('Автоматическое уведомление о выявлении алкоголя на МО','<a target=_blank href="' . $name . '">Отчет</a>'.$text);
        }


    // перенести в модуль ИНТЕГРАЦИЯ
    function send_push_mo_result_sync($mo_id)
    {   if (!$GLOBALS['LS_mo_push_server']) return ; // не задан сервер - выход
        if (!_sizeof($GLOBALS['LS_mo_push_fields'])) return ; // не заданы настройки полей - выход
        if (!$GLOBALS['LS_mo_push_sync']) return ; // выключен асинхронный режим - выход
        $time_start=($GLOBALS['LS_mo_push_time_from'])? strtotime($GLOBALS['LS_mo_push_time_from']):$GLOBALS['LS_mo_push_sync'] ;
        if ($time_start>time()) return ; // если время старта еще не наступило - выход

      include(_DIR_EXT.'/esmo_gateway/i_push_mo.php') ;
      $push_obj=new i_push_mo() ;
        $push_obj->send_sync($mo_id) ;
    }


    function cron_send_push_mo_result_async()
    {
       $result=$this->send_push_mo_result_async() ;
       damp_array($result,1,-1);
    }


    // перенести в модуль ИНТЕГРАЦИЯ
    function send_push_mo_result_async()
    { $result=[] ;
      if (!$GLOBALS['LS_mo_push_server']) $result=['error'=>'LS_mo_push_server не задано'] ; // не задан сервер - выход
      if (!$GLOBALS['LS_mo_push_fields']) $result=['error'=>'LS_mo_push_fields не задано'] ; ; // не заданы настройки полей - выход
      if (!$GLOBALS['LS_mo_push_async']) $result=['error'=>'LS_mo_push_async=0'] ; ; // выключен асинхронный режим - выход
      $time_start=($GLOBALS['LS_mo_push_time_from'])? strtotime($GLOBALS['LS_mo_push_time_from']):$GLOBALS['LS_mo_push_async'] ;
      if ($time_start>time()) $result=['error'=>'Время начала отправки уведомлений еще не наступило','LS_mo_push_time_from'=>$GLOBALS['LS_mo_push_time_from'],'LS_mo_push_async'=>$GLOBALS['LS_mo_push_async']] ; // если время старта еще не наступило - выход

      if (!$result['error'])
      {   $result['time_from']=date('d.m.Y H:i:s',$time_start) ;
          include_once(_DIR_EXT.'/esmo_gateway/i_push_mo.php') ;
          $push_obj=new i_push_mo() ;
          $mo_ids=$push_obj->get_mo_ids_to_async_send($time_start) ;
          $result['mo_ids']=implode(',',$mo_ids) ;

          echo _sizeof($mo_ids).' МО для отправки<br>' ;
          if (_sizeof($mo_ids))
          {   $result_send=$push_obj->send_async($mo_ids) ;
              $result['send_result']=$result_send ;
              ?><p><strong>Статус ответа:</strong> <?echo '<span style="font-size:22px;" class="'.(($result_send['status']==200)? 'green':'red').'">'.$result_send['status']?></span></p><?
              if ($result_send['send_result']!='success')
              {    ?><p><strong>Ошибка:</strong> <?echo '<span style="font-size:16px;color:red;">'.$result_send['send_error']?></span></p><p>Подробный отчет: <a href="<? echo $result_send['log_url']?>" target="_blank">перейти</a></p><?
                   ?><p><strong>Время ответа:</strong> <?echo round($result_send['time_exec'],4).' сек.'?></p><?
                   ?><p><strong>Ответ:</strong></p><?
                   echo nl2br($result_send['send_response']) ;
                   // отправка уведомления на монитор фельдшера
                   if ($GLOBALS['LS_mo_push_notify_doctor'])
                   { $message=array() ;
                     $message['notife']='alert' ;
                     $message['notife_text']='Не удалось отправить уведомление о прохождении МО' ;
                     $message['from']='m_aspmo::send_push_mo_result_async' ;
                     $group_ids=execSQL_line('select group_id from '.$this->table_mo_sessions_now.' where pkey in ('.implode(',',$mo_ids).')') ;
                     if (_sizeof($group_ids)) foreach($group_ids as $group_id) ESMO()->reg_monitor_mess($group_id,$message) ;
                   }
              }
          }
      }
      return($result) ;

    }

    function group_medic_create($form_data)
    { $id=_IL('IL_group_medic')->append_rec_to_list($form_data) ;
      ESMO()->group_medic_change($id) ; ;
      return($id) ;
    }

    function get_check_schulte_result($setting,$time,$error)
    { ob_start() ;
      damp_array($setting,1,-1) ;
      echo 'cur_time='.$time.'<br>' ;
      echo '$error='.$error.'<br>' ;
      $res=2 ; // 2 - не пройдено
      $ball=1 ;  // пока непонятно как считать баллы
      if (_sizeof($setting['krit'])) foreach($setting['krit'] as $rec_krit)
      {   $max_time=$rec_krit['time'] ;
          $max_error=$rec_krit['error'] ;
          $access=$rec_krit['access'] ;
          if ($time<=$max_time and $error<=$max_error) { $res=$access ; break ; }
      }
      echo 'select_time='.$max_time.'<br>' ;
      echo 'select_erors='.$max_error.'<br>' ;
      $text=ob_get_clean() ;
      LOG_JSON('mo_session')->reg('check_schulte_result',$text);
      //echo $text ;
      return(array($ball,$res)) ;
    }

    function group_medic_delete($group_id)
    { $result=_IL('IL_group_medic')->rec_delete($group_id) ;
      execSQL_update('DROP VIEW  view_personals_medic_group_'.$group_id,array('debug'=>0)) ;
      return($result) ;
    }

    function group_medic_change($group_id)
      {
          ob_start() ;
          $viewer_name='view_personals_medic_group_'.$group_id ;
          $rec_medic=_IL('IL_group_medic')->recs[$group_id] ;
          $sql='select  *
                from view_personals
                where clss=211 and pkey in (select o_id from obj_site_link where p_id='.$rec_medic['pkey'].' and p_clss='.$rec_medic['clss'].') 
                ' ;
          SETUP()->create_viewer($viewer_name,$sql) ;
          $text=ob_get_clean() ;
          //LOGS()->reg_log('group_personal_medic_change',$text) ;
          echo $text ;
      }


    function get_allow_view_button_hand_check_in_mo_tr($rec)
      { if ($rec['status']==3 and $rec['model']>0 and !$rec['dopusk'] and
          ($GLOBALS['LS_mo_hand_check_always'] or
             (($GLOBALS['LS_mo_hand_check_by_sd'] and ($rec['res_s']>1 or $rec['res_d']>1) and $this->check_hand_mo_allow($rec,$GLOBALS['LS_mo_hand_check_by_sd'])) or // при давлении и пульсе только если это mo2
              ($GLOBALS['LS_mo_hand_check_by_p'] and $rec['res_p']>1 and $this->check_hand_mo_allow($rec,$GLOBALS['LS_mo_hand_check_by_p'])) or
              ($GLOBALS['LS_mo_hand_check_by_a'] and $rec['res_a']>1 and $this->check_hand_mo_allow($rec,$GLOBALS['LS_mo_hand_check_by_a'])) or
              ($GLOBALS['LS_mo_hand_check_by_t'] and $rec['res_t']>1 and $this->check_hand_mo_allow($rec,$GLOBALS['LS_mo_hand_check_by_t'])) or
              ($GLOBALS['LS_mo_hand_check_by_pp'] and $rec['res_n']>1 and $this->check_hand_mo_allow($rec,$GLOBALS['LS_mo_hand_check_by_pp'])) or
              ($rec['reason']=='equipmentError' and $rec['mo1_id']) or
              ($rec['question']==1)
             ))) $result=1 ;
         else $result=0 ;

         $data=array() ;
         $data['МО status']=$rec['status'];
         $data['МО model']=$rec['model'];
         $data['МО dopusk']=$rec['dopusk'];
         $data['МО res_s']=$rec['res_s'];
         $data['МО res_d']=$rec['res_d'];
         $data['МО res_p']=$rec['res_p'];
         $data['МО res_t']=$rec['res_t'];
         $data['МО res_a']=$rec['res_a'];
         $data['МО res_n']=$rec['res_n'];
         $data['МО reason']=$rec['reason'] ;
         $data['МО mo1_id']=$rec['mo1_id'] ;
         $data['МО question']=$rec['question'] ;
         $data['LS_mo_hand_check_by_sd']=$GLOBALS['LS_mo_hand_check_by_sd'] ;
         $data['LS_mo_hand_check_by_p']=$GLOBALS['LS_mo_hand_check_by_p'] ;
         $data['LS_mo_hand_check_by_a']=$GLOBALS['LS_mo_hand_check_by_a'] ;
         $data['LS_mo_hand_check_by_t']=$GLOBALS['LS_mo_hand_check_by_t'] ;
         $data['LS_mo_hand_check_by_pp']=$GLOBALS['LS_mo_hand_check_by_pp'] ;
         $data['LS_mo_hand_check_always']=$GLOBALS['LS_mo_hand_check_always'] ;
         $data['RESULT']=$result ;

          LOG_JSON('button_hand_check')->reg('get_allow_view_button_hand_check_in_mo_tr',$rec['pkey'],array('data'=>$data)) ;

         return($result) ;
      }

    function check_hand_mo_allow($rec,$option)
    {
        if (($option==1) or ($option==2 and $rec['mo1_id'])) return true; else return false;
    }

    function update_uklonist_status()
     {
         $now=getdate(time()) ;
         $from=mktime($now['hours'],$now['minutes'],$now['seconds']-$GLOBALS['LS_mo_session_lenght']*60*60,$now['mon'],$now['mday'],$now['year']);
         $cnt=execSQL('select count(pkey) from '.$this->table_mo_sessions_now.' where dopusk=0 and tk=0 and model>0 and error=0 and e_data>0 and e_data<='.$from.' order by e_data desc') ;
         if ($cnt)
         { ob_start() ;
           $t=fixed_time() ;
           $new_status=($GLOBALS['LS_setting_uklonist_status'])? $GLOBALS['LS_setting_uklonist_status']:3 ;
           $dopusk_time=($new_status==2)? time():0 ;
           $nedopusk_time_S=(float)$GLOBALS['LS_setting_auto_mo_denited_interval']*60*60 ; // срок действия меддопуска в секундах
           $nedopusk_time_S_alco=(float)$GLOBALS['LS_setting_auto_mo_denited_alco_interval']*60*60 ; // срок действия меддопуска в секундах
           //$dopusk_time_end=($new_status==2)? mktime($now['hours']+$GLOBALS['LS_setting_auto_mo_denited_interval'],$now['minutes'],$now['seconds'],$now['mon'],$now['mday'],$now['year']):0 ;
           $dopusk_time_end=($new_status==2)?time()+$nedopusk_time_S:0 ;
           $dopusk_time_end_alco=($new_status==2)?time()+$nedopusk_time_S_alco:0 ;
           echo 'Время окончания недопуска: '.date('d.m.Y H:i:s',$dopusk_time_end).'<br>' ;
           // удален учет error так как сотрудники затягивая МО, уходят от получения допуска
           $cnt=execSQL_update('update '.$this->table_mo_sessions_now.' set r_data='.time().',dopusk='.$new_status.',dopusk_time='.$dopusk_time.',dopusk_time_end='.$dopusk_time_end.' where dopusk=0 and tk=0 and res_a!=2 and model>0 and e_data>0 and e_data<='.$from,array('debug'=>0)) ;
           $cnt=execSQL_update('update '.$this->table_mo_sessions_now.' set r_data='.time().',dopusk='.$new_status.',dopusk_time='.$dopusk_time.',dopusk_time_end='.$dopusk_time_end_alco.' where dopusk=0 and tk=0 and res_a=2 and model>0 and e_data>0 and e_data<='.$from,array('debug'=>0)) ;
           echo 'Обработано <strong>'.$cnt.'</strong> записей<br>' ;
           fixed_time($t,'Время выполнения операции') ;
           $text=ob_get_clean() ;
           //LOGS()->reg_log('Перевод МО в статус Уклонился',$text) ;
         }
     }

    function clear_mo_old_images()
    { if ($GLOBALS['LS_mo_photo_storage_time'])  exec('find '._DIR_TO_ROOT.'/public/mo_photo -name "*.jpg" -mmin +'.($GLOBALS['LS_mo_photo_storage_time']*60-1).' -print0 | xargs -0 rm -rf') ;
      if ($GLOBALS['LS_mo_dsign_storage_time'])  exec('find '._DIR_TO_ROOT.'/public/mo_sign -name "*.data" -mmin +'.($GLOBALS['LS_mo_dsign_storage_time']*60-1).' -print0 | xargs -0 rm -rf') ;
      if ($GLOBALS['LS_mo_sign_storage_time'])  exec('find '._DIR_TO_ROOT.'/public/mo_photo -name "*.png" -mmin +'.($GLOBALS['LS_mo_sign_storage_time']*60-1).' -print0 | xargs -0 rm -rf') ;
      if ($GLOBALS['LS_mo_sign_storage_time'])  exec('find '._DIR_TO_ROOT.'/public/mo_sign_image -name "*.png" -mmin +'.($GLOBALS['LS_mo_sign_storage_time']*60-1).' -print0 | xargs -0 rm -rf') ;
    }

  //==========================================================================================================================================================================
  // МОНИТОР
  //==========================================================================================================================================================================

    function reg_monitor_mess($group,$arr_mess)
    {
        if ($GLOBALS['LS_monitoring_use_WS']) \cab\system\i_ws::send_monitor_mess_to_WS($group,$arr_mess);
        else {
            // пишем событие для HTML версии
            // получаяем очередной ID события

            $event_id=execSQL_value('select last_mo_event from obj_site_account where pkey='.$group) ;
            $event_id++ ;
            execSQL_update('update obj_site_account set last_mo_event='.$event_id.' where pkey='.$group) ;
            if (!is_dir(_DIR_TO_ROOT.'/temp/monitor/')) check_exists_dir('/temp/monitor/') ;
            $fname=_DIR_TO_ROOT.'/temp/monitor/evt_'.$group.'_'.$event_id.'.json' ;
            file_put_contents($fname,json_encode($arr_mess)) ;
            // сохраняем в файл last_mo_event_GRP_ID.txt id последнего события по группе
            $fname=_DIR_TO_ROOT.'/temp/monitor/last_mo_event_'.$group.'.txt' ;
            file_put_contents($fname,$event_id) ;
            return($fname) ;
        }
    }

    function get_last_monitor_mess_id_HTML($group=0)
    {   $last_id=execSQL_value("SELECT last_mo_event  from obj_site_account where pkey=".$group) ;
        return($last_id) ;
    }

    // перенос данных по МО из оперативной таблицы в основную
    // внимаение! требуется исправление в engine - добавлена опция no_reffers
    function copy_mo_from_now($show_text=1)
    {

     $stats=execSQL_van('select count(pkey) as cnt,min(c_data) as mo_from,max(c_data) as mo_to from obj_site_mo_session_now') ;
     if (!$stats['cnt']) echo 'Оперативная таблица пуста' ;
     else
    {ob_start() ;
     $t=fixed_time() ;
         echo 'Оперативная таблица <strong>'.$stats['cnt'].'</strong> записей, от <strong>'.date('d.m.Y H:i:s',$stats['mo_from']).'</strong> до <strong>'.date('d.m.Y H:i:s',$stats['mo_to']).'</strong><br>' ;

     $table_descr=execSQL('describe obj_site_mo_session') ;
     $table_descr_now=execSQL('describe obj_site_mo_session_now') ;
     foreach($table_descr as $fname=>$finfo) if (!isset($table_descr_now[$fname])) unset($table_descr[$fname]) ;
//     unset($table_descr['с_data']) ;
     $cnt=execSQL_update('replace into obj_site_mo_session ('.implode(',',array_keys($table_descr)).') 
                          select '.implode(',',array_keys($table_descr)).' 
                          from obj_site_mo_session_now order by pkey') ;
     //echo 'cnt='.$cnt.'<br>' ;
         fixed_time($t,'Затронуто '.$cnt.'  записей при синхронизации с оперативной таблицей') ;

     if ($cnt and $GLOBALS['LS_setting_mo_now_len'])
     { $t2=fixed_time() ;
       // удаляем из оперативной таблицы  записи старше заданной величины
       $now=getdate() ;
       $from=mktime($now['hours']-$GLOBALS['LS_setting_mo_now_len'],$now['minutes'],$now['seconds'],$now['mon'],$now['mday'],$now['year']);
       echo 'Удаляем из оперативной таблицы записи старее <strong>'.$GLOBALS['LS_setting_mo_now_len'].'</strong> часов - до <strong>'.date('d.m.Y H:i:s',$from).'</strong><br>' ;
       $cnt=execSQL_update('delete from obj_site_mo_session_now where c_data<'.$from) ;
       //echo 'Удалено: <strong>'.$cnt.'</strong> записей<br>' ;
       fixed_time($t2,'Удалено '.$cnt.' МО из оперативной таблицы') ;
           $stats=execSQL_van('select count(pkey) as cnt,min(c_data) as mo_from,max(c_data) as mo_to from obj_site_mo_session_now') ;
           if ($stats['cnt']) echo 'Оперативная таблица <strong>'.$stats['cnt'].'</strong> записей, от <strong>'.date('d.m.Y H:i:s',$stats['mo_from']).'</strong> до <strong>'.date('d.m.Y H:i:s',$stats['mo_to']).'</strong><br>' ;
           else echo 'Оперативная таблица пуста<br>' ;
     }
     $text=ob_get_clean() ;
     if ($show_text) echo $text ;
     LOGS()->reg_log('copy_mo_from_now',$text) ;
    }
    }

    // перенос данных по МО из основной таблицы в оперативной
    // внимаение! требуется исправление в engine - добавлена опция no_reffers
    function copy_mo_to_now()
    {//ob_start() ;
     $t=fixed_time() ;
     $table_descr=execSQL('describe obj_site_mo_session') ;
     $table_descr_now=execSQL('describe obj_site_mo_session_now') ;
     foreach($table_descr as $fname=>$finfo) if (!isset($table_descr_now[$fname])) unset($table_descr[$fname]) ;

     $now=getdate() ;
     $from=mktime($now['hours']-$GLOBALS['LS_setting_mo_now_len'],$now['minutes'],$now['seconds'],$now['mon'],$now['mday'],$now['year']);

     $cnt=execSQL_update('replace into obj_site_mo_session_now ('.implode(',',array_keys($table_descr)).') select '.implode(',',array_keys($table_descr)).' from obj_site_mo_session where c_data>='.$from.' order by pkey') ;
     //echo 'cnt='.$cnt.'<br>' ;
     fixed_time($t,'Перенос '.$cnt.' МО из основную таблицы в оперативную') ;

     // ставим auto_increment для pkey в оперативной таблице аналично основной таблице
	 $last=execSQL_value('SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA="'.$GLOBALS['_SETTING']['main_db']['db_name'].'" AND TABLE_NAME="obj_site_mo_session"') ;
	 execSQL_update('ALTER TABLE obj_site_mo_session_now AUTO_INCREMENT='.$last) ;

     //$text=ob_get_clean() ;
     //if ($show_text) echo $text ;
     //LOGS()->reg_log('copy_mo_to_now',$text) ;
    }

    function clear_mo_from_now()
    {   echo 'Удаляем из оперативной таблицы все записи<br>' ;
        $cnt=execSQL_update('delete from obj_site_mo_session_now')  ;
        echo 'Удалено: <strong>'.$cnt.'</strong> записей<br>' ;
    }

    function mo_now_enabled()
    {  ob_start() ;
       ?><strong>Включение оперативной таблицы:</strong><?
       // производим очистку оперативной таблицы
       ESMO()->clear_mo_from_now() ;
       // производим копирование данных по глубине ОТ
       ESMO()->copy_mo_to_now() ;
       // включаем задание планировщика
       SETUP()->change_cron_status('ESMO/copy_mo_from_now',1) ;
       // включаем использование оперативной таблицы
       SETUP()->update_site_setting('LS_mo_now_enabled',1) ;
       // перегружаем систему
       reboot_engine() ;
       //echo 'ESMO.table_mo_sessions_now='.$this->table_mo_sessions_now.'<br>' ;
       //echo 'ESMO.view_mo_session_now='.$this->view_mo_session_now.'<br>' ;
       $text=ob_get_clean() ;
       LOGS()->reg_log('Оперативная таблица',$text) ;
       echo $text ;
    }

    function mo_now_disabled()
    {  ob_start() ;
       ?><strong>Выключение оперативной таблицы:</strong><?
       // производим копирование данных по глубине ОТ
       ESMO()->copy_mo_from_now() ;
       // производим очистку оперативной таблицы
       ESMO()->clear_mo_from_now() ;
       // выключаем задание планировщика
       SETUP()->change_cron_status('ESMO/copy_mo_from_now',0) ;
       // включаем использование оперативной таблицы
       SETUP()->update_site_setting('LS_mo_now_enabled',0) ;
       // перегружаем систему
       reboot_engine() ;
       $text=ob_get_clean() ;
       LOGS()->reg_log('Оперативная таблица',$text) ;
       echo $text ;
    }

    function get_greetings_for_terminal($rec_personal)
    {   ob_start() ;
        $arr=explode(' ',$rec_personal['obj_name']) ;
        $io=$arr[1].' '.$arr[2] ; // имя отчество
        $H=date('H') ;
        $int1=explode('-',$GLOBALS['LS_hello_morning_int']) ;
        $int2=explode('-',$GLOBALS['LS_hello_day_int']) ;
        $int3=explode('-',$GLOBALS['LS_hello_evening_int']) ;
        $int4=explode('-',$GLOBALS['LS_hello_night_int']) ;
        echo'H='.$H.'<br>' ;
        echo print_r($int1,true).'<br>' ;
        echo print_r($int2,true).'<br>' ;
        echo print_r($int3,true).'<br>' ;
        echo print_r($int4,true).'<br>' ;


        if ($H>=(int)$int1[0] and $H<(int)$int1[1]) $text=$GLOBALS['LS_hello_morning_text'].', '.$io ;
        else if ($H>=(int)$int2[0] and $H<(int)$int2[1]) $text=$GLOBALS['LS_hello_day_text'].', '.$io ;
        else if ($H>=(int)$int3[0] and $H<(int)$int3[1]) $text=$GLOBALS['LS_hello_evening_text'].', '.$io ;
        else if ($H>=(int)$int4[0] or $H<=(int)$int4[0]) $text=$GLOBALS['LS_hello_night_text'].', '.$io ;
        else $text='Здравствуйте, '.$io ;

        $text2=ob_get_clean() ;
        //LOGS()->reg_log('get_greetings_for_terminal',$text2) ;
        //echo $text ;

        return($text) ;
    }


    function med_org_create($form_data)
        {
            $result=\cab\aspmo\i_med_org::create($form_data) ;
            return($result) ;
        }

        function get_med_org_by_id($id)
        {
            $rec=\cab\aspmo\i_med_org::get_rec_by_pkey($id) ;
            return($rec) ;
        }

        function get_med_org_by_uid($uid)
        {
            $rec=\cab\aspmo\i_med_org::get_rec_by_uid($uid) ;
            return($rec) ;
        }

        function med_org_save($med_org_id,$form_data)
        {
            $result=\cab\aspmo\i_med_org::save($med_org_id,$form_data) ;
            return($result) ;
        }

        function med_org_delete($med_org_id)
        {
            $result=\cab\aspmo\i_med_org::delete($med_org_id) ;
            return($result) ;
        }

        function get_arr_med_ords_for_select($options=[])
        {
            $recs=execSQL_row('select pkey,obj_name from catalog_med_orgs') ;
            if ($options['append_default_value']) $recs[-1]='В соответствии с организацией сотрудника' ;
            asort($recs) ;
            //damp_array($recs);
            return($recs) ;
        }

        function get_med_org_to_event_pass($event_id,$personal_id)
        { $rec=array() ;
          $med_org_id=execSQL_value('select med_org_id from obj_site_events_pass where event_id='.$event_id.' and personal_id='.$personal_id) ;
          if (!$med_org_id)
            $med_org_id=execSQL_value('select t2.med_org_id 
                                       from obj_site_personals t1 
                                       left join obj_site_personals t2 on t2.pkey=t1.parent2 
                                       where t1.pkey='.$personal_id) ;

          if ($med_org_id) $rec=$this->get_med_org_by_id($med_org_id) ;
          //damp_array($rec);
          return($rec) ;
        }





}

?>
