<?php
include_once('i_workgroups.php') ;

$__functions['init'][]='_accounts_site_vars' ;
$__functions['boot_site'][]='_accounts_site_boot' ;

function ACCOUNTS($options=array()) {
  if (isset($_SESSION['accounts_system'])){
    return($_SESSION['accounts_system']);
  } else {
    $_SESSION['accounts_system']=new c_accounts_system($options);
    return($_SESSION['accounts_system']);
  }
}

function _accounts_site_vars()
{

    $_SESSION['ARR_smena_status']=array (0=>'close',
                                         1=>'active',
                                         2=>'pause',
                                         3=>'out',
                                         4=>'unactive',
                                         5=>'block'
                                        ) ;

    $_SESSION['init_options']['accounts']['debug']=0 ;
    //$_SESSION['init_options']['goods']['patch_mode']='TREE_NAME' ;
    $_SESSION['init_options']['accounts']['patch_mode']='NAME' ;
    $_SESSION['init_options']['accounts']['root_dir']	='/cab/personal/' ;
    $_SESSION['init_options']['accounts']['clss_items']='211' ;
    //$_SESSION['init_options']['accounts']['usl_show_items']='enabled=1 and _enabled=1' ;
    $_SESSION['init_options']['accounts']['usl_show_items']='_enabled=1' ; // показываем всех сотрудников, уволенных и действующих
    $_SESSION['init_options']['accounts']['tree_fields']='pkey,parent,clss,indx,enabled,obj_name,tkey' ;


    // определяем условия для формирование дерева
    $_SESSION['init_options']['accounts']['tree']['debug']=0;
    $_SESSION['init_options']['accounts']['tree']['clss']='1,206' ;
    $_SESSION['init_options']['accounts']['tree']['include_space_section']=1 ;
    $_SESSION['init_options']['accounts']['tree']['order_by']='indx' ;
    $_SESSION['init_options']['accounts']['tree']['get_count_by_clss']=0 ;


}

function _accounts_site_boot($options)
{
  create_system_modul_obj('accounts',$options) ;

}


class c_accounts_system extends c_system_catalog
{
    var $accounts ;
    var $table_account ;

    function __construct($create_options=array())
    { $this->table_name ='obj_site_account' ;
      $this->table_account ='obj_site_account' ;
      parent::__construct($create_options) ;

     //регистрируем документы
     // кешируемые аккаунты - врач и так далее
     // перемещено в  mc_ext_moduls.php::after_init_system
     //$this->accounts=execSQL('select * from view_account where enabled=1') ;
     //if (_sizeof($this->accounts)) foreach($this->accounts as $id=>$rec) $this->prepare_public_info_to_member($this->accounts[$id]) ;

    }

  function declare_menu_items_1($page)
  {

  }


    //==========================================================================================================================================================================
      // АВТОРИЗАЦИЯ и ВЫХОД из аккаунта
      //==========================================================================================================================================================================

    // функция входа  работает с объектом $member
    function member_login($login,$pass,$options=array())
    {   //$GLOBALS['LS_select_group_to_account']=1 ;
        //$GLOBALS['LS_ecp_check_sert_by_auth']=1 ;
        LOG_JSON('account_autorize')->reg('member_login','login='.$login.'<br>pass='.$pass,array('data'=>$options)) ;
        if (!$_SESSION['member']->id)
        if ($login and $pass)
        { $check=($GLOBALS['LS_account_autorize_limit'])? $this->check_account_autorize_limit():1 ;
          if ($check)
        { $rec=$this->get_member_by_login_and_pass($login,$pass,$options) ;
              if ($rec['pkey']) { LOG_JSON('account_autorize')->reg('member_login','Получена запись по комбинации логин/пароль',array('data'=>$rec)) ;
                                  // если включена проверка сертифика при авторизации
                                  // и у аккаунта не эмуляция
                                  // и аккаунт начинает смену
                                  // возвращаем код "check_sertificate" с указанием  id аккаунта, который необходимо проверить
                                  //
                                  $log_data=array() ; $rec_ARM=$this->get_group_id_to_ARM_by_ip(IP) ;
                                  $log_data['Включена проверка сертификата']=($GLOBALS['LS_ecp_check_sert_by_auth'])? 'Да':'Нет' ;
                                  $log_data['Включен выбор группы']=($GLOBALS['LS_select_group_to_account'])? 'Да':'Нет' ;
                                  $log_data['Найден АРМ для IP '.IP]=($rec_ARM['id'])? 'Да, ID '.$rec_ARM['id']:'Нет' ;

                                  $_SESSION['autorize_process']['account_group_id']=$rec['parent'] ;

                                  $check_sertificate=($GLOBALS['LS_ecp_check_sert_by_auth'] and $rec['certificate']['IssuerName']!='Эмуляция ЭЦП' and $_SESSION['ARR_roll'][$rec['rol']]['use_auch_as_smena']==1 and !$_SESSION['autorize_process']['sert_valid'])? 1:0 ;
                                  // выборн группы требуется если включена опция LS_select_group_to_account и родительская группа аккаунта содержит подгруппы
                                  $has_childrens_group=execSQL_value('select count(pkey) from obj_site_account where parent='.$rec['parent'].' and clss=206 and enabled=1') ;
                                  $select_group=($GLOBALS['LS_select_group_to_account'] and $rec['rol']==2 and $has_childrens_group and !$_SESSION['autorize_process']['group_id'] and !$rec_ARM['id'])? 1:0 ;

                                  if ($check_sertificate)  {$log_data['Требуется проверка сертификата']='Да' ; $log_data['Сертификат']=$rec['certificate'] ; } else $log_data['Требуется проверка сертификата']='Нет' ;
                                  if ($select_group)  $log_data['Требуется выбор группы']='Да' ;  else $log_data['Требуется выбор группы']='Нет' ;

                                  $log_data['Авторизация как начало смены']=($_SESSION['ARR_roll'][$rec['rol']]['use_auch_as_smena'])? 'Да':'Нет' ;
                                  echo 'Логин/пароль подтвержден, account ID:'.$rec['pkey'].' clss='.$rec['clss'].'<br>' ;
                                  LOGS()->reg_log('ACCOUNTS/member_login','Логин/пароль подтвержден',array('data'=>$log_data)) ;
                                  LOG_JSON('account_autorize')->reg('member_login','Логин/пароль подтвержден',array('data'=>$log_data)) ;
                                  // проверяем, что для текущего аккаунта, если он не админ, есть заведенный в систему АРМ. Если АРМ не найден, сотрудник будет перенаправлен на страницу выбора группы

                                  if ($select_group) $result=array('code'=>'select_group','account_id'=>$rec['pkey']) ;
                                  elseif ($check_sertificate) $result=array('code'=>'check_sertificate','account_id'=>$rec['pkey']) ;
                                  else
                                  {   if ($_SESSION['autorize_process']['group_id']) $options['group_id_to_auth']=$_SESSION['autorize_process']['group_id'] ;
                                      $result=$this->member_autorize($rec,$options) ;  // авторизуем пользователя
                                  }
                            }
          else              {  LOG_JSON('account_autorize')->reg('member_login','Не найдена запись по комбинации логин/пароль') ;
                               // внимание!!! не переименовывать событие, по его названию отрабатывает функция check_account_autorize_limit
                               $text='Логин:<strong>'.$login.'</strong>' ;
                               if ($GLOBALS['LS_account_save_open_pass']) $text.='<br>Пароль:<strong>'.$pass.'</strong>' ;
                               LOGS()->reg_log('Ошибка авторизации',$text);
                               $result=prepare_result('member_not_found') ;
                            }
          }  else $result=prepare_result('check_account_autorize_limit_failed') ;
        }
        else $result=prepare_result('space_field') ;
      else $result=prepare_result('no_login_for_member') ;
      LOG_JSON('account_autorize')->reg('member_login','member_id='.MEMBER()->id,array('data'=>$result)) ;

      return($result) ;
    }

    function check_account_autorize_limit()
    {  echo 'Проверяем авторизацию персонала за последние '.$GLOBALS['LS_account_autorize_time'].' минут<br>' ;
       $cur_time=getdate() ;
       $from=mktime($cur_time['hours'],$cur_time['minutes']-$GLOBALS['LS_account_autorize_time'],$cur_time['seconds'],$cur_time['mon'],$cur_time['mday'],$cur_time['year']);
       echo 'Проверка от '.date('d.m.Y H:i:s',$from) ;
       $recs=execSQL('select pkey,obj_name,IP,comment,c_data,data from obj_site_mo_log where (obj_name="Авторизация персонала" or obj_name="Выход персонала" or obj_name="Ошибка авторизации" or obj_name="account_login_failed") and IP="'.IP.'" and c_data>='.$from.' order by pkey desc') ;
       $cnt_error=0 ;
       // считаем ошибок авторизации авторизаций до первой успешной авторизации или выхода
       if (_sizeof($recs)) foreach($recs as $rec)
       {  if ($rec['obj_name']=='Авторизация персонала' or $rec['obj_name']=='Выход персонала') break ;
          if ($rec['obj_name']=='Ошибка авторизации') $cnt_error++ ;
       }
       echo 'Найдено '.$cnt_error.' ошибок авторизации<br>' ;
       $result=($cnt_error>=$GLOBALS['LS_account_autorize_limit'])? 0:1 ;
       return($result) ;
    }


    // функция выхода теперь также работает с обхектом member
    function member_logout($comment='',$options=array())
    {  if (MEMBER()->from_AD) $_SESSION['member_AD_is_logout']=1 ;
       $_SESSION['member']->superreader=0 ; // выключаем режим чуперчитателя
       //$member_name=$_SESSION['member']->name.' ['.$_SESSION['member']->login.']' ;
       LOGS()->reg_log('Выход персонала',$comment,array('reffers'=>MEMBER()->reffer)) ;
       $this->member_save($_SESSION['member']->id,array('ip'=>'','time_logout'=>time(),'smena'=>0)) ;
       unset($_SESSION['member']) ;
       $_SESSION['member']=new i_account() ; // создаем неавторизированного пользователя
       if ($options['logout_via_exit_button'])  $_SESSION['logout_via_exit_button']=1; //запоминаем в сессию выход по кнопке
       return(prepare_result('logout_success')) ;
    }

    // smena=0,1 - признак активной смены
    // smena_in - время начала смены
    // smena_out - время окончания смены
    // комбинации полей после авторизации сотрудников, с активным флагом в роли use_auch_as_smena
    // smena=0   - close, смена закрыта
    // smena=1   - active, смена активна
    // smena=2   - paused, смена приостановлена другим пользователем
    // smena=3   - out, смена закрыта по операции закрытия смены

    // задаем активную смену для персонала в его группе
    function  member_smena_in($smena_in=0)
    { if (!$smena_in) $smena_in=time() ;
      // сбрасываем смену у всех врачей в текущей группе (не разделе!!!)
      if (MEMBER()->smena_monopole_mode)
      {   $recs_smena_active=execSQL_row('select pkey,obj_name from obj_site_account where clss='.MEMBER()->info['clss'].' and group_id='.MEMBER()->cur_group_id.' and rol='.MEMBER()->info['rol'].' and smena=1 and pkey!='.MEMBER()->id) ;
          if (_sizeof($recs_smena_active)) { echo 'Будет приостановлена смена сотрудников:' ; damp_array($recs_smena_active,1,-1) ; }
          execSQL_update('update obj_site_account set smena=2 where clss='.MEMBER()->info['clss'].' and group_id='.MEMBER()->cur_group_id.' and rol='.MEMBER()->info['rol'].' and smena=1') ;
      }
      // ставим себе начало смены
      execSQL_update('update obj_site_account set smena_in='.$smena_in.',smena_out=0,smena=1,group_id='.MEMBER()->cur_group_id.' where pkey='.MEMBER()->id) ;
      // данные аккаунта будут заново прочитаны из базу
      $this->update_member_info($_SESSION['member']) ;
    }

    // закрытие смены сотрудника, есть id не передан, закрываем смену текущего аккаунта
    function  account_smena_out($account_id=0) {$this->member_smena_out($account_id);}
    function  member_smena_out($account_id=0)
    {   if (!$account_id) $account_id=MEMBER()->id ;
        $this->member_save($account_id,array('smena_out'=>time(),'smena'=>3)) ; //смена закрыта, пользователь может только разлогиниться, группу не трогаем
        // если разлогинивается текущий пользователь - обновляем его данные из базы
        if ($account_id==MEMBER()->id) $this->update_member_info($_SESSION['member']) ; // данные аккаунта будут заново прочитаны из базу
        $member_name=MEMBER()->name.' ['.MEMBER()->login.']' ;
        ENGINE()->on_event('member_smena_out',array('member'=>$account_id)) ;
        LOGS()->reg_log('Смена персонала',$member_name.' - окончание смены',array('member_id'=>$account_id)) ;
    }

    function get_group_id_to_ARM_by_ip($ip)
    {   $rec_ARM=execSQL_van('select t1.pkey as id,t1.parent as group_id,t2.obj_name as group_name from obj_site_account t1 left join obj_site_account t2 on t2.pkey=t1.parent where t1.ip="'.$ip.'" and t1.clss=205 and t1.enabled=1',0) ;
        return($rec_ARM) ;
    }

     // создание объекта member по записи $rec и вся необходимая обвязка
     function member_autorize($rec,$options=array())
     { LOG_JSON('account_autorize')->reg('autorize_by_ajax_request','member_autorize: '.$rec['obj_name'],array('data'=>$options)) ;
       ob_start() ;
       ?><strong><?echo $rec['obj_name']?></strong>, <?echo IP.'<br>' ;
       include_once('i_account.php')  ;
       $_SESSION['member']=new i_account($rec) ;  // создаем авторизированного пользователя. Данные из $rec будут внесены в $_SESSION['member']
       $_SESSION['member']->use_system='aspmo_system' ;
       $_SESSION['member']->login_time=time() ;
       $_SESSION['smena_podpis']=0 ;

       $_SESSION['member']->rol=$rec['rol']   ;
       $_SESSION['member']->use_auch_as_smena=$_SESSION['ARR_roll'][$rec['rol']]['use_auch_as_smena']   ;
       $_SESSION['member']->smena_monopole_mode=$_SESSION['ARR_roll'][$rec['rol']]['smena_monopole_mode']   ;
       $_SESSION['member']->autologout=$_SESSION['ARR_roll'][$rec['rol']]['autologout']   ;

       LOG_JSON('account_autorize')->reg('member_autorize','',array('data'=>MEMBER())) ;
         $_SESSION['member2']=$_SESSION['member'] ;
         $_SESSION['member3']='aaa' ;

       if (_sizeof($_SESSION['autorize_process']['logs'])) echo implode('<br>',$_SESSION['autorize_process']['logs']).'<br>' ;

       echo 'Должность: '.$_SESSION['ARR_roll'][$_SESSION['member']->rol]['obj_name'].'<br>' ;
       echo 'Считать авторизацию как качало смены: <strong>'.(($_SESSION['member']->use_auch_as_smena)? 'Да':'Нет').'</strong><br>' ;
       echo 'Только одна активная смена в группе: <strong>'.(($_SESSION['member']->smena_monopole_mode)? 'Да':'Нет').'</strong><br>' ;
       if ($options['block_smena']) echo 'Блокировка открытия смены: <strong>Да</strong><br>' ;

       // ищем АРМ с IP аккаунта. Если АРМ найден - аккаунт будет зарегистрирован в данной группе
       // по умолчанию используем родительскую группу аккаунта
       $group_id=$rec['parent'] ;

       // если сотрудник не admin то он должен попасть в группу согласно своему АРМ
       if ($_SESSION['member']->rol!=1)
       { $rec_ARM=$this->get_group_id_to_ARM_by_ip(IP) ;
         if ($rec_ARM['group_id'])
         {   $group_id=$rec_ARM['group_id'] ;
             echo '<div class=green>Найден АРМ с IP '.IP.' в группе '.$rec_ARM['group_name'].' ['.$rec_ARM['group_id'].']</div>' ;
         }
         else if ($options['group_id_to_auth'])
         { $group_id=$options['group_id_to_auth'] ;
           $group_name=ACCOUNTS()->get_group_name($group_id) ;
           echo '<div class=green>Сотрудник выбрал группу <strong>'.$group_name.'</strong> ['.$group_id.'] при авторизации</div>' ;
         }
         else
         {  $group_name=ACCOUNTS()->get_group_name($group_id) ;
            echo '<div class=red>АРМ с IP '.IP.' не найден, будет использована родительская группа <strong>'.$group_name.'</strong> ['.$rec['parent'].']</div>' ;
         }
       }

       $this->cur_member_group_set($group_id) ;


       echo 'Сотрудник авторизован в группе <strong>'.$_SESSION['member']->cur_group_name.'</strong> ['.$_SESSION['member']->cur_group_id.']<br>' ;

       // необходимо обновить поля по записи аккауента в базе
       $data=array('ip'=>$_SERVER['REMOTE_ADDR'],'time_login'=>time(),'time_logout'=>0,'sess_id'=>session_id(),'group_id'=>$_SESSION['member']->cur_group_id) ;

       $this->member_save($_SESSION['member']->id,$data) ;
       $this->update_member_info($_SESSION['member']) ; // данные аккаунта будут заново прочитаны из базу
       $member_name=$_SESSION['member']->name.' ['.$_SESSION['member']->login.']' ;

       // проверяем работает ли данная роль по сменам - пока только для врачей
       if ($_SESSION['member']->use_auch_as_smena and !$options['block_smena'])
       { echo '<strong>Выполняем проверку активной смены</strong><br>' ;
         // проверяем нет ли другого активного логина на этой роли с открытой сменой
         // only_use_arm - флаг, что доктор аторизиуется на зарегистрировнном АРМ,
         // соответственно проверять активную смену необходимо только в пределах рабочей группы данного АРМ
         $doctor_id=ESMO()->check_doctor(MEMBER()->cur_group_id,array(
                 'debug'=>1,
                 'only_use_arm'=>MEMBER()->cur_group_id,
                 'no_use_default_doctor'=>1,    // проверить дежурного фельдшера без учета доктора по умолчанию
                 'rol_id'=>$rec['rol']
         )) ;

         if ($doctor_id and $_SESSION['member']->smena_monopole_mode)
         {   $active_doctor_name=$this->get_member_name_by_id($doctor_id) ;
             if ($doctor_id==$rec['pkey']) // если активная смена - наша
             {  $this->member_smena_in($rec['smena_in'])  ;
                echo '<div class="green">'.$member_name.' - автоматическое возобновление смены после аварийного закрытия браузера</div>' ;
             }
             else //есть активная смена другого врача
             {  // отмечаем что смена открыта у другого пользователя
               execSQL_update('update obj_site_account set smena=4 where pkey='.MEMBER()->id) ;  // 4 - UNACTIVE
               echo '<div class="red">'.$member_name.' - Автоматическое открытие смены заблокировано, смена уже открыта сотрудником '.$active_doctor_name.'</div>' ;
             }
         }
         // активных смен нет или ёто не важно - открываем свою сменe
         else if ($rec['smena_in'] and !$rec['smena_out']) // если была своя ранее открытая смена
         {
           $this->member_smena_in($rec['smena_in'])  ;
           echo '<div class="green">'.$member_name.' - Автоматическое возобновление смены после выхода из браузера</div>' ;
         }
         else
         {

           $this->member_smena_in()  ;
           echo $member_name.' - Нормальное открытие смены после авторизации' ;
         }
       }
       elseif ($options['block_smena'])
       { //$this->member_smena_out() ;
           execSQL_update('update obj_site_account set smena=5 where pkey='.MEMBER()->id) ;  // 4 - UNACTIVE
       }

       $this->update_member_info($_SESSION['member']) ; // данные аккаунта будут заново прочитаны из базу

       $event_name=($options['event_name'])? $options['event_name']:'Авторизация через логин/пароль' ;
       $text=ob_get_clean()  ;
       //LOGS()->reg_log('Авторизация персонала',$text,array('reffers'=>MEMBER()->reffer)) ; // регистрируем событие 'Вход на сайт через пароль'
       LOGS()->reg_log('ACCOUNTS.member_autorize',$text,array('reffers'=>MEMBER()->reffer)) ; // регистрируем событие 'авторизация пользователя'
       LOG_JSON('account_autorize')->reg('member_autorize',$text,array('data'=>MEMBER())) ;
       if ($options['debug']) echo $text ;
       //_event_reg($event_name,$text,array('reffers'=>MEMBER()->reffer)) ; // регистрируем событие 'Вход на сайт через пароль'

       unset($_SESSION['autorize_process']) ;

       // включаем режим суперчитателя
       $_SESSION['member']->superreader=($rec['_ext_info']['superreader'])? 1:0 ;
       return(prepare_result('login_success')) ;
      }

     function cur_member_group_set($group_id)
     {   $rec_group=$this->get_group_by_id($group_id) ;
         MEMBER()->cur_zone_id=0 ;
         MEMBER()->cur_group_id=$group_id ;
         //MEMBER()->cur_group_name= execSQL_value('select obj_name from obj_site_account where pkey="'.MEMBER()->cur_group_id.'"') ;
         MEMBER()->cur_group_name= $rec_group['obj_name'] ;
         MEMBER()->cur_groups_visible=ACCOUNTS()->tree[MEMBER()->cur_group_id]->get_list_child() ;

         //$group_setting=unserialize(execSQL_value('select settings from obj_site_account where pkey="'.MEMBER()->cur_group_id.'"')) ;
         MEMBER()->timezone=($rec_group['_ext_info']['timezone'])? $rec_group['_ext_info']['timezone']:'Europe/Moscow' ;
         // обновляем вьювер сотрудников
         MEMBER()->viewer_name=ACCOUNTS()->update_viewer_account(MEMBER()->info,['check_autorize_group'=>0,'use_group_id'=>$group_id]) ; ;
         // временно для совместимости со старыми отчетами, в которых используется MEMBER()->setting['personal']['usl_select']
         MEMBER()->setting['personal']['usl_select']='pkey in (select pkey from '.MEMBER()->viewer_name.')' ;




         $time_zone=(MEMBER()->timezone)? MEMBER()->timezone:'Europe/Moscow' ;
         date_default_timezone_set($time_zone) ;
     }


      // обновить инфрмацию объекта $member
      function update_member_info($member)
      { if ($member==null) return ;
        $rec=$this->get_member_by_id($member->id,array('get_right'=>1)) ;  // damp_array($rec) ;
        $member->update_info($rec) ; // будет выхвана функция clss_200->update_member_info
        if (MEMBER()->id==$member->id)
          { $time_zone=($member->timezone)? $member->timezone:'Europe/Moscow' ;
            date_default_timezone_set($time_zone) ;
            //LOGS()->reg_log('timezone','update_member_info - '.$time_zone.' ['.date('d.m.Y H:i:s').'] '._CUR_PAGE_DIR) ;
          }
      }

      function get_pass_hash($login,$pass)
      {
         return(hash('sha256',$login.$pass)) ;
      }


       function change_pass($member_id,$new_value,$options=array())
       { if (is_object($member_id)) $member_id=$member_id->id ;  // если вместо $member_id  передан объект member
         list($member_id,$tkey)=explode('.',$member_id) ; // преобразования reffer в id
         $rec_account=execSQL_van('select login,password from '.$this->table_account.' where pkey='.$member_id) ;
         $old_value_hash=$rec_account['password'] ;
         $new_value_hash=$this->get_pass_hash($rec_account['login'],$new_value) ;
         // проверяем, изменилось ли значение поля
         if (check_nochange_form_value($new_value_hash,$old_value_hash))  return(array('type'=>'error','text'=>'Значение не изменилось','code'=>'nochange')) ;
         // проверяем заполнение обязательных полей
         if ($new_value=='') return(array('type'=>'error','code'=>'space_field','text'=>'Был передан пустой пустой пароль')) ;
         // проверяем требования к паролю
         $check_result=array() ;
         if (!$GLOBALS['LS_use_simple_pass'])
         { $res=$this->check_pass($rec_account['login'],$new_value) ;
           if (!$res['login']) $check_result[]='Пароль содержит логин текущего пользователя' ;
           if (!$res['len'])   $check_result[]='Недостаточная длина пароля' ;
           if (!$res['big']) $check_result[]='Пароль не содержит заглавных латинских букв' ;
           if (!$res['small']) $check_result[]='Пароль не содержит прописных латинских букв' ;
           if (!$res['big']) $check_result[]='Пароль не содержит цифр' ;
           if (!$res['spec']) $check_result[]='Пароль не содержит специальных символов (!, $, #, %, @))' ;
         }
         if (_sizeof($check_result) and !$options['no_validate'])   return(array('type'=>'error','code'=>'unvalidate','text'=>implode('<br>',$check_result))) ;


         // проверка прав доступа текущего аккаунта к аккаунту $member
         //if ($res=$this->check_access($member_id)!='ok')  return(array('type'=>'error','code'=>'access_denited')) ;
         // сохраняем в базе
         update_rec_in_table($this->table_account,array('password'=>$new_value_hash),'pkey='.$member_id) ;
         // регистрируем событие
         $account_reffer=$member_id.'.'.$this->tkey ;
         $log_pass_value=substr($new_value,0,1).'*****'.substr($new_value,strlen($new_value)-1,1) ;
         LOGS()->reg_log('Измененение данных аккаунта','Пароль: '.$log_pass_value) ;
         // сохраняем данные в аккаунте
         if ($_SESSION['member']->id==$member_id) $this->update_member_info($_SESSION['member']) ;
         // отправляем почтовое уведомление
         //$this->send_mail_change_password($member_id,array('use_event_id'=>$evt_id)) ;
         // возвращаем событие успешного обловления
         return(array('type'=>'success','code'=>'pass_change_success','text'=>'Пароль был успешно изменен')) ;
       }

       function check_pass($login,$password)
       {  $res['login']=(strpos($password,$login)===false)? 1:0 ;
          $res['len']=(strlen($password)>=6)? 1:0 ;
          $res['big']=(preg_match("/[A-Z]/", $password, $matches)) ;
          $res['small']=(preg_match("/[a-z]/", $password, $matches)) ;
          $res['dig']=(preg_match("/[1-90]/", $password, $matches)) ;
          $res['spec']=(preg_match("/[\!\$\#\%\@]/", $password, $matches)) ;
          return($res) ;

       }

      //==========================================================================================================================================================================
      // РАБОТА С СОТРУДНИКАМИ АСПМО
      //==========================================================================================================================================================================

      // получаем id группы на АРМ которой сейчас работает сотрудник на основании IP адреса его машины
      function get_member_cur_group_rec()
      { $arm_ip=$_SERVER['REMOTE_ADDR'] ;
        $arm_rec=execSQL_van('select * from obj_site_account where pkey=(select parent from obj_site_account where clss=205 and enabled=1 and ip="'.$arm_ip.'")') ;
        return($arm_rec) ;
      }

      // получаем  АРМ по его IP
      function get_ARM_rec_by_IP($IP)
      { $arm_rec=execSQL_van('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=205 and t1.enabled=1 and t1.ip="'.$IP.'"') ;
        return($arm_rec) ;
      }

      function get_group_name($id)
      { $name=execSQL_value('select obj_name from obj_site_account where pkey="'.$id.'"') ;
        return($name) ;
      }

      function get_member_by_login_and_pass($login,$pass,$options=array())
      {   //ob_start() ;
          $login=stripslashes(trim($login)) ;
          $pass=stripslashes(trim($pass)) ;
          $pass_hash=(is_array($options) and $options['pass_is_hash'])? $pass:$this->get_pass_hash($login,$pass) ;
          //  опция - разрещить ли авторизоваться по логину/паролю тем, кто ранее авторизовался по AD по этому логину
          $usl=($GLOBALS['LS_AD_disallow_pass_after_AD'] and !$options['pass_is_hash'])? ' and (UID="" or UID is null or UID=0)':'' ;
          $sql='select * from '.$this->table_account.' where login="'.trim($login).'" and password="'.$pass_hash.'" and enabled=1 '.$usl ;
          LOG_JSON('account_autorize')->reg('sql',$sql) ;
          $rec=execSQL_van($sql) ;
          //$text=ob_get_clean() ; LOGS()->reg_log('get_member_by_login_and_pass',$text) ;
          if ($rec['pkey']) $this->prepare_public_info_to_member($rec,array('get_right'=>1)) ;

          return($rec) ;
      }

      function get_member_by_login($login)
      {  $login=addslashes(trim($login)) ;
          $rec=execSQL_van('select * from '.$this->table_account.' where login="'.$login.'"') ;
          if ($rec['pkey']) $this->prepare_public_info_to_member($rec,array('get_right'=>1)) ;
          return($rec) ;
      }

      // получение информации по прсоналу АСПМО
      function get_account_by_id($id,$options=array()){return($this->get_member_by_id($id,$options));}
      function get_member_by_id($id,$options=array())
      { list($id,$tkey)=explode('.',$id) ;
        $tkey=_DOT('obj_site_account')->pkey ;
        $usl_clss=($options['clss'])? ' and clss='.$options['clss']:'' ;
        $rec=execSQL_van('select * from view_account where pkey="'.$id.'" '.$usl_clss) ;
        //$rec=get_obj_info($id.'.'.$tkey) ;
        if ($rec['pkey']) $this->prepare_public_info_to_member($rec,$options) ;
        return($rec);
      }

      // получение информации по прсоналу АСПМО
      function get_member_name_by_id($id,$options=array())
      { list($id,$tkey)=explode('.',$id) ;
        $usl_clss=($options['clss'])? ' and clss='.$options['clss']:'' ;
        $rec=execSQL_van('select * from obj_site_account where pkey="'.$id.'" '.$usl_clss) ;
        if ($rec['pkey']) $this->prepare_public_info_to_member($rec,$options) ;
        //return($rec['_rol_name'].' '.$rec['obj_name']);
        return($rec['obj_name']);
      }

      // получение информации по прсоналу АСПМО
      function get_members_names_by_ids($ids,$options=array())
      { $usl_clss=($options['clss'])? ' and clss='.$options['clss']:'' ;
        $str_ids=(is_array($ids))? (($options['ids_in_keys'])? implode(',',array_keys($ids)):implode(',',$ids)):$ids ;
        $recs=execSQL_row('select pkey,obj_name from obj_site_account where pkey in ('.$str_ids.') '.$usl_clss) ;
        $names=implode(', ',$recs) ;
        //if ($rec['pkey']) $this->prepare_public_info_to_member($rec,$options) ;
        //return($rec['_rol_name'].' '.$rec['obj_name']);
        return($names);
      }

      // получение информации по прсоналу АСПМО
      function get_terminal_name_by_id($id,$options=array())
      { list($id,$tkey)=explode('.',$id) ;
        $usl_clss=($options['clss'])? ' and clss='.$options['clss']:'' ;
        $name=execSQL_van('select obj_name from obj_site_account where pkey="'.$id.'" '.$usl_clss) ;
        return($name);
      }

      function get_names_by_ids($ids)
      {
        $arr=execSQL_row('select pkey,obj_name from obj_site_account where pkey in ('.implode(',',$ids).')') ;
        return($arr) ;
      }

      // получение информации по прсоналу АСПМО
      // кешируем в globals результаты, так как функция вызывается очень часто в цикле
      function get_members_by_ids($arr_ids,$options=array())
      { $usl_clss=($options['clss'])? ' and clss='.$options['clss']:'' ;
         // todo проверить  вызов этой функции
        $recs=execSQL('select * from obj_site_account where pkey in ('.$arr_ids.') '.$usl_clss) ;
        if (_sizeof($recs)) foreach($recs as $id=>$rec) $this->prepare_public_info_to_member($recs[$id],$options) ;
        return($recs);
      }

      function prepare_public_info_to_member(&$rec,$options=array())
      { $rec['__href']='/cab/setting/member/'.$rec['pkey'].'/' ;
        $rec['__href_window']='/window/setting/member/'.$rec['pkey'].'/' ;
        $rec['_rol_name']=($rec['working'])? $rec['working']:$_SESSION['ARR_roll'][$rec['rol']]['obj_name'] ;
        if ($rec['ext_info']) {$rec['_ext_info']=unserialize($rec['ext_info']) ; unset($rec['ext_info']) ; }
        if (_sizeof($rec['_ext_info']['certificate'])) $rec['certificate']=$rec['_ext_info']['certificate'] ;

        // временная совместимость со старым хранением данных по сертиикату
        if (!$rec['certificate']['SerialNumber'] and $rec['sert_id'])       $rec['certificate']['SerialNumber']=$rec['sert_id'] ;
        if (!$rec['certificate']['SubjectName'] and $rec['sert_name'])      $rec['certificate']['SubjectName']=$rec['sert_name'] ;
        if (!$rec['certificate']['IssuerName'] and $rec['sert_ud'])         $rec['certificate']['IssuerName']=$rec['sert_ud'] ;
        if (!$rec['certificate']['ValidFromDate'] and $rec['sert_from'])    $rec['certificate']['ValidFromDate']=date('d.m.Y H:i:s',$rec['sert_from']) ;
        if (!$rec['certificate']['ValidToDate'] and $rec['sert_to'])        $rec['certificate']['ValidToDate']=date('d.m.Y H:i:s',$rec['sert_to']) ;

        // CN=УЦ ЗАО «ПФ «СКБ Контур» (Qualified), OU=Удостоверяющий центр, O=ЗАО «ПФ «СКБ Контур», L=Екатеринбург, S=66 Свердловская облас
        if ($rec['certificate']['IssuerName'])
        { $arr=explode(',',$rec['certificate']['IssuerName']) ;
     	  if (_sizeof($arr)>1) foreach($arr as $id=>$value)
     	    { $arr2=explode('=',$value) ;
              $rec['certificate']['Issuer'][$arr2[0]]=$arr2[1] ;
     	    }
     	  else $rec['certificate']['Issuer']['CN']=$rec['certificate']['IssuerName'] ;
        }
        // SNILS=02419314926, G=Анна Евгеньевна, SN=Смирнова, CN=Смирнова Анна Евгеньевна, L=Видное, S=50 Московская область, C=RU, E=asmir
        if ($rec['certificate']['SubjectName'])
        { $arr=explode(',',$rec['certificate']['SubjectName']) ;
       	  if (_sizeof($arr)>1) foreach($arr as $id=>$value)
       	    { $arr2=explode('=',$value) ;
                $rec['certificate']['Subject'][$arr2[0]]=$arr2[1] ;
       	    }
       	  else $rec['certificate']['Subject']['CN']=$rec['certificate']['SubjectName'] ;
        }


        if (_sizeof($rec['_ext_info']['cryptopro']))   $rec['cryptopro']=$rec['_ext_info']['cryptopro'] ;
        /*
        if ($options['get_right'] and $rec['rol'])
        { $rol_reffer=$_SESSION['ARR_roll'][$rec['rol']]['_reffer'] ;
          $links=get_arr_links_to_reffer($rol_reffer,array('clss'=>97,'debug'=>0)) ;
          if (_sizeof($links)) foreach($links as $rec_link)
            { if ($rec_link['obj_clss']==97)  $rec['_right'][$_SESSION['menu_system']->tree[$rec_link['obj_pkey']]->rec['title']]=1 ;
              if ($rec_link['link_clss']==97) $rec['_right'][$_SESSION['menu_system']->tree[$rec_link['link_pkey']]->rec['title']]=1 ;
            }

        } */
        //if (_DOT($rec['tkey'])->list_clss[3]) $stamp_rec=execSQL_van('select pkey,tkey,file_name from obj_site_account_image where parent='.$rec['pkey'].' and alt="stamp"') ;
        //if ($stamp_rec['pkey']) $rec['stamp']=$stamp_rec ;
        if ($rec['_signature_file_name']) $rec['signature']=array('file_name'=>$rec['_signature_file_name'],'tkey'=>_DOT('obj_site_account_image')->pkey) ;
        if ($rec['_stamp_file_name']) $rec['stamp']=array('file_name'=>$rec['_stamp_file_name'],'tkey'=>_DOT('obj_site_account_image')->pkey) ;

        /*
        if (_sizeof($rec['obj_clss_3'])) foreach($rec['obj_clss_3'] as $i=>$rec_img)
            switch($rec_img['alt'])
            { case 'stamp':    $rec['stamp']=$rec_img ; unset($rec['obj_clss_3'][$i]) ; break ;
              case 'signature':    $rec['signature']=$rec_img ; unset($rec['obj_clss_3'][$i]) ; break ;
            }
        */


        //if ($rec['_sert_file_name']) $rec['sert_file']=_DOT('obj_site_account_files')->dir_to_file.'/'.$rec['_sert_file_name'] ;
        //damp_array($rec,1,-1) ;
      }

      function get_list_members($options=array())
      { $_usl=array() ;

        if ($options['group_id']) $_usl[]=' (group_id in ('.ACCOUNTS()->tree[$options['group_id']]->get_list_child().') or parent in ('.ACCOUNTS()->tree[$options['group_id']]->get_list_child().'))';
        else if (!$options['no_filter_by_cur_group']) $_usl[]='(group_id in ('.ACCOUNTS()->tree[MEMBER()->cur_group_id]->get_list_child().') or parent in ('.ACCOUNTS()->tree[MEMBER()->cur_group_id]->get_list_child().'))' ;
        if ($options['rol']) $_usl[]='rol in ('.$options['rol'].')' ;
        if (!$options['and_disabled']) $_usl[]='enabled=1' ;
        $usl=' and '.implode(' and ',$_usl) ;
        $recs=execSQL('select * from obj_site_account where clss=210 '.$usl.' order by obj_name') ;
        if (_sizeof($recs)) foreach($recs as $id=>$rec) $this->prepare_public_info_to_member($recs[$id],$options) ;
        return($recs) ;
      }

      //обновляем данные аккаунта в базе
      function account_save($id,$form_data,$options=array())  {return($this->member_save($id,$form_data,$options));}
      function member_save($id,$form_data,$options=array())
      { //echo 'member_save=<br>' ;
        //damp_array($form_data,1,-1) ;
        $rec=$this->get_member_by_id($id) ; $res=0 ;
        $ext_info=$rec['_ext_info'] ;
        $data=array() ;
        if ($form_data['ext_info']) $data['ext_info']=$rec['_ext_info'] ; // если будут изменены дополнительные поля, надо сохрянять весь массив доп. полей
        if ($rec['pkey'])
        { $reg_log=0 ;
          if (_sizeof($form_data)) foreach($form_data as $fname=>$value) if ($fname!='personals' and $fname!='personals_filter_item_remove')
              {  if ($fname!='ext_info') {  if($rec[$fname]!=$value) {$data[$fname]=$value; $reg_log=1 ; }}  // сохраняем только изменишиеся поля
                 else if (_sizeof($value)) foreach($value as $ext_fname=>$ext_value) { $ext_info[$ext_fname]=$ext_value; $reg_log=1 ; }//  для доп.полей сохраняем все
              }

            $data['ext_info']=$ext_info ;

          //if (_sizeof($data) and $reg_log)
          { ob_start() ;
              $res=update_rec_in_table('obj_site_account',$data,'pkey='.$rec['pkey'],array('debug'=>2)) ;
            $text=ob_get_clean() ;
            if ($options['save_log']) LOGS()->reg_log('Изменение данных персонала',$text,array('data'=>$data,'reffers'=>array($rec['_reffer']))) ;
          }
          //else $res=0 ;

        }
        return($res) ;
      }

      function account_create($form_data,$options=array()) {return($this->member_create($form_data,$options));}
      function member_create($form_data,$options=array())
      { if (!isset($form_data['rol']))  return(array('error'=>'Не задана роль')) ;
        if (!isset($form_data['group_id']))  return(array('error'=>'Не задана рабочая группа')) ;
        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['group_id'])  $form_data['group_id']=MEMBER()->cur_group_id ;

        if (!$options['no_check_login'])
        { $login_exist=execSQL_value('select pkey from obj_site_account where login="'.$form_data['login'].'" and clss=210') ;
        if ($login_exist)  return(array('error'=>'Данный логин уже используется.')) ;
        }

        $data=array() ;
        $data['clss']=210 ;
        $data['access_pass']=md5(rand(1,1000)) ;
        $data['parent']=$form_data['group_id'] ;
        $data['obj_name']=$form_data['name'] ;
        $data['rol']=$form_data['rol'] ;
        $data['login']=$form_data['login'] ;
        $data['password']=$this->get_pass_hash($data['login'],$form_data['password']) ;
        $data['UID']=$form_data['UID'] ;
        $data['indx']=1 ;
        // Устанавливаем должность: приоритет - переданное значение, затем из роли
        if (isset($form_data['working']) && $form_data['working']) {
            $data['working']=$form_data['working'] ;
        } elseif (isset($_SESSION['ARR_roll'][$form_data['rol']]['working']) && $_SESSION['ARR_roll'][$form_data['rol']]['working']) {
            $data['working']=$_SESSION['ARR_roll'][$form_data['rol']]['working'] ;
        }

        $result['id']=adding_rec_to_table('obj_site_account',$data) ;
        $result['info']='Аккаунт успешно добавлен - "<strong>'.$form_data['login'].'</strong>"' ;

        $result['reffer']=$result['id'].'.'.ACCOUNTS()->tkey ;
        if (!$options['no_log']) LOGS()->reg_log('Конфигурация ЭСМО','Добавление персонала ЭСМО "'.$form_data['name'].'" ['.$form_data['login'].'], '.$_SESSION['ARR_roll'][$data['rol']]['obj_name'].' в группу '.ACCOUNTS()->get_group_name($form_data['group_id']),array('reffers'=>array($result['reffer']))) ;

        return($result) ;
      }


      function member_delete($id)
      { $member_rec=$this->get_member_by_id($id) ;
        $res=execSQL_update('delete from obj_site_account where pkey='.$id.' and clss=210') ;
        //$result=$this->XMPP_action_user('delete',array('login'=>$member_rec['XMPP_login'],'pass'=>$member_rec['XMPP_password'])) ;
          $result=array() ;
        return(array_merge($result,$res)) ;
      }


     // возвращает список дочерних групп для массива групп
     // $group_ids - массив групп, id групп в значениях
     // выход -      строка с id групп через запятую
     function get_childs_ids_for_group_ids($group_ids)
     {   $chids_groups=array() ;
         if (_sizeof($group_ids)) foreach($group_ids as $group_id) if (isset(ACCOUNTS()->tree[$group_id])) $chids_groups[$group_id]=$this->tree[$group_id]->get_list_child() ;
         $str_groups=implode(',',$chids_groups) ;
         // убираем повторы
         $arr=explode(',',$str_groups) ;
         $arr2=array_unique($arr) ;
         $str=implode(',',$arr2) ;
         return($str) ;

     }


    // возвраает массив групп для текущего пользователя с учетом его расположения
     function get_arr_groups_to_cur_account2($usl="clss=206",$options=array())
     {   $arr_groups=array() ;
         if (isset($this->tree[MEMBER()->cur_group_id]))
         {   $chids_group=$this->tree[MEMBER()->cur_group_id]->get_list_child() ;
            if ($options['return_recs']) $arr_groups=execSQL('select * from obj_site_account where '.$usl.' and pkey in ('.$chids_group.') order by parent,obj_name') ;
            else { $arr_groups=execSQL_row('select pkey,obj_name from obj_site_account where '.$usl.' and pkey in ('.$chids_group.')') ;
            asort($arr_groups) ;
          }
         }
         return($arr_groups) ;
     }


      //==========================================================================================================================================================================
      // ВЕРНУТЬ СПИСОК РАБОЧИХ ГРУПП
      //==========================================================================================================================================================================
      // есть несколько похожих функций, приводим их к единому виду
      //1	ЭСМО
	  //42	ЭСМО / al.kvzrm.ru
	  //43	ЭСМО / al.kvzrm.ru / Персонал компании
	  //44	ЭСМО / al.kvzrm.ru / Персонал компании / test

     // возвраает массив групп для текущего пользователя с учетом его расположения
    // аналог функции get_arr_groups_select_options, но по умолчнию путь выводиться от группы текущего аккаунта
     function  get_arr_groups_select_options($options=array()) {return($this->get_arr_groups_to_cur_account($options));}
     function get_arr_groups_to_cur_account($options=array())
     {   // если не передана опция full_tree, показываем дерево групп от текущей группы сотрудника
         if (!$options['full_tree']) $options['root_id']=MEMBER()->cur_group_id ;
         $arr_groups=$this->get_arr_tree_workgroups($options) ;
         return($arr_groups) ;
         }

    // вывести структуру дерева групп в виде массива
    // [ID=>путь элемента]
    // параметры
    // root_id - с какого элемента показывать дерево, по умолчанию с корня
    // small_path - выводить путь в краткой форме, по умолчанию в полной
    function get_arr_tree_workgroups($options=[])
        {
            $usl[]='clss in (1,206)';
//            if ($options['level_max']) $usl[]='level <='.$options['level_max'];
            if ($options['usl']) $usl[] = $options['usl'];
            $_usl = implode(' and ', $usl);
            $arr_groups=execSQL('select pkey,parent,obj_name from obj_site_account where '.$_usl.' order by parent,obj_name') ;
         $arr_groups2=$arr_groups ;
            //damp_array($options);
            $root=($options['root_id'])?:1 ;
            convert_list_to_tree($arr_groups2,$arr_tree,$root) ;
            //damp_array($arr_tree);
            $arr_tree_root=[] ;
            $arr_tree_root[$root]=$arr_tree ;
            if ($options['small_path']) $this->convert_tree_to_select_options_arr($arr_tree_root,$arr_groups,$arr) ;
            else convert_tree_to_select_options_arr($arr_tree_root,$arr_groups,$arr) ;
            return($arr) ;
     }

     function convert_tree_to_select_options_arr($arr_tree,&$recs,&$options_list,$level=0)
     {  $pref=($level)? str_repeat("&nbsp;&nbsp;&nbsp;&nbsp;",$level-1).'|--':"" ;
       $level++ ;
       if (_sizeof($arr_tree)) foreach ($arr_tree as $id=>$arr_childs)
       {   $options_list[$id]=$pref.$recs[$id]['obj_name'] ;
           if (_sizeof($arr_childs)) $this->convert_tree_to_select_options_arr($arr_childs,$recs,$options_list,$level) ;
       }
     }



    //==========================================================================================================================================================================
      // РАБОТА С ТЕРМИНАЛАМИ И РАБОЧИМИ МЕСТАМИ ФЕЛЬДШЕРА
      //==========================================================================================================================================================================

       function get_workgroup_by_id($id){return $this->get_group_by_id($id);}
       function get_group_by_id($id)
       { $rec=execSQL_van('select * from '.$this->table_account.' where pkey='.$id.' and clss in (1,206) and enabled=1') ;
         if ($rec['pkey']) $this->prepare_public_info_to_workgroup($rec) ;
         //damp_array($rec) ;
         return($rec) ;
       }

       function prepare_public_info_to_workgroup(&$rec)
       { if ($rec['settings']) $rec['_settings']=unserialize($rec['settings']) ;
         if ($rec['_settings']===false) $rec['_settings']=json_decode($rec['settings'],true) ; // не удалять, отсюда будут взяды данные для алкотестера
         $rec['_ext_info']=$rec['_settings'] ; // _ext_info - стардатное имя массива для храрения расширенной информации
         $rec['__href']='/window/setting/members/group/'.$rec['pkey'].'/' ;
         $rec['__href_window']='/window/setting/members/group/'.$rec['pkey'].'/' ;
         //damp_array($rec['_settings']) ;

       }

       function get_list_workgoups($options=array())
       { $usl=($options['usl'])? $options['usl']:'clss=206 and enabled=1' ;
         $recs=execSQL('select * from '.$this->table_account.' where '.$usl.' order by parent,obj_name') ;
         return($recs) ;
       }

       function ARM_create($form_data)
       {
         $form_data['ip']=trim($form_data['ip']);
         $id_exist=execSQL_value('select pkey from obj_site_account where ip="'.$form_data['ip'].'" and clss=205') ;
         if ($id_exist)  return(array('error'=>'АРМ с данным IP уже зарегистрирован в системе')) ;

         $data=array() ;
         $data['clss']=205 ;
         $data['parent']=$form_data['group_id'] ;
         $data['obj_name']=$form_data['name'] ;
         $data['ip']=$form_data['ip'] ;

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

       }

       function GROUP_create($form_data)
       { $id_exist=execSQL_value('select pkey from obj_site_account where obj_name="'.$form_data['name'].'" and clss=206') ;
         if ($id_exist)  return(array('error'=>'Рабочая группа уже зарегистрирована в системе')) ;

         $data=array() ;
         $data['clss']=206 ;
         $data['parent']=$form_data['group_id'] ;
         $data['obj_name']=$form_data['name'] ;

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

       }

       function workgroup_save($group_id,$form_data)
       { $id_exist=execSQL_value('select pkey from obj_site_account where obj_name="'.$form_data['name'].'" and clss=206') ;
         if ($id_exist)  return(array('error'=>'Рабочая группа уже зарегистрирована в системе')) ;
         $result=array() ;
         ob_start() ;
         $rec_group=$this->get_workgroup_by_id($group_id) ;
         $arr_changes=array() ; $data=array() ;
         // что за треш, $_POST передается через  $form_data
         //$form_data=$_POST['filter'] ;
         ENGINE()->check_changes('Наименование','obj_name',$rec_group,$form_data,$data,$arr_changes,array('fname_form'=>'group_name')) ;
         ENGINE()->check_changes('Родительская группа','parent',$rec_group,$form_data,$data,$arr_changes,array('fname_form'=>'parent_id','view_old_value'=>ACCOUNTS()->get_group_name($rec_group['parent'].' ['.$rec_group['parent'].']'),'view_new_value'=>ACCOUNTS()->get_group_name($form_data['parent_id'].' ['.$form_data['parent_id'].']'))) ;
         ENGINE()->check_changes('Временная зона','timezone',$rec_group,$form_data,$data,$arr_changes,array('old_value'=>$rec_group['_ext_info']['timezone'],'new_value'=>$form_data['timezone'])) ;
         ENGINE()->check_changes('Тип проводимых МО','mo_type',$rec_group,$form_data,$data,$arr_changes,array('old_value'=>$rec_group['_ext_info']['mo_type'],'new_value'=>$form_data['mo_type'])) ;
         ENGINE()->check_changes('Мед.организация группы','med_org_id',$rec_group,$form_data,$data,$arr_changes,array('old_value'=>$rec_group['med_org_id'],'new_value'=>$form_data['med_org_id'])) ;
         ENGINE()->check_changes('viewer_name','viewer_name',$rec_group,$form_data,$data,$arr_changes) ;


         $ext_info=$rec_group['_ext_info'] ;

         // для совместимости с результатами ENGINE()->check_changes
         if (isset($data['timezone'])) { $ext_info['timezone']=$data['timezone'] ; unset($data['timezone']) ;  }
         if (isset($data['mo_type'])) { $ext_info['mo_type']=$data['mo_type'] ; unset($data['mo_type']) ;  }

         if (_sizeof($ext_info)) $data['settings']=serialize($ext_info) ;

         //damp_array($arr_changes,1,-1) ;
         //damp_array($data,1,-1) ;
         if (_sizeof($data))
         {  if (isset($data['timezone'])) { $data['settings']['timezone']=$data['timezone'] ; unset($data['timezone']) ;  }
            if (isset($data['mo_type'])) { $data['settings']['mo_type']=$data['mo_type'] ; unset($data['mo_type']) ;  }
              update_rec_in_table('obj_site_account',$data,'pkey='.$group_id,array('debug'=>0)) ;
              echo '<strong>Сохранены изменения</strong><br>' ;
              damp_array($arr_changes,1,-1) ;
              $result['info']='Изменения по группе успешно сохранены' ;
              $result['id']=$group_id ;
              $result['reffer']=$rec_group['_reffer'] ;
              $result['changes']=$arr_changes ;
              LOGS()->reg_log('Конфигурация ЭСМО','Успешно',array('reffer'=>$rec_group['_reffer'],'data'=>$arr_changes)) ;
         }
         else echo '<strong>Изменений не обнаружено</strong><br>' ;
         $text=ob_get_clean() ;
         $result['text']=$text ;
         return($result) ;
       }


       // обновляем SQL вьюверов по рабочим группам
       function update_workgroups_viewers()
       {
           PERSONALS_FILTER()->update_viewer_personals('view_personals_workgroup') ;
       }

       function workgroups_onchange()
       {

       }


       function arm_save($data)
       {
         if (_sizeof($data))foreach($data as $id=>$rec)
             $res[]=update_rec_in_table('obj_site_account',array('id'=>$rec['id'],'obj_name'=>$rec['name']),'pkey='.$id) ;
       }

       /** возращает список зарегистрированных email групп */
       function get_arr_register_emails()
       {
            $recs_ATP=execSQL('select pkey,obj_name,settings from obj_site_account where clss=206') ;
                $arr_ATP_email=array() ;
                if (_sizeof($recs_ATP)) foreach($recs_ATP as $rec)
                {  $arr=unserialize($rec['settings']) ;
                   if (isset($arr['scan_email_login']) and $arr['scan_email_login']!="")
                   {   $emails=str_replace(array(';',' '),',',$arr['scan_email_login']) ;
                       $arr2=explode(',',$emails) ;
                       if (_sizeof($arr2)) foreach($arr2 as $email)
                       { $email=trim($email) ;
                         if ($email) $arr_ATP_email[$email]=$rec['pkey'] ;
                       }
                   }
                }
             return($arr_ATP_email) ;
      }



    function allow_right_rol($rol_id,$class_name)
     { $id=execSQL_value('select pkey from obj_site_permit where clss=216 and obj_name="'.$class_name.'" and rol_id="'.$rol_id.'"') ;
       if (!$id) adding_rec_to_table('obj_site_permit',array('clss'=>216,'parent'=>1,'obj_name'=>$class_name,'rol_id'=>$rol_id)) ;
     }

     function decline_right_rol($rol_id,$class_name)
     { execSQL_update('delete from obj_site_permit where clss=216 and obj_name="'.$class_name.'" and rol_id="'.$rol_id.'"') ;
     }

     function get_right_rol($rol_id,$class_name)
     { $id=execSQL_value('select pkey from obj_site_permit where clss=216 and obj_name="'.$class_name.'" and rol_id="'.$rol_id.'"') ;
       return($id) ;
     }

    function check_login($value)
    { $pkey=execSQL_value('select pkey from '.$this->table_name.' where login="'.trim($value).'"');
      return ($pkey)? $pkey:0 ;
    }

    function check_email($value)
     { $pkey=execSQL_value('select pkey from '.$this->table_name.' where email="'.trim($value).'"');
       return ($pkey)? $pkey:0 ;
     }





     // получаем имя вьювера c IDs сотрудников, которые доступны текущему аккаунту
     // вьюверу уже должны быть созданы
     // для групп они создаются при проверке настроект
     // для аккаунта - при авторизации аккаунта
     /// доделать: проверку существования вьювера, если нет у группы - view_personals_active
     function update_viewer_account($rec_account,$options=array())
     {   if ($options['use_group_id'])
         { $group_id=$rec_account['group_id'];
           echo 'Передан ID группы, в которой авторизуется аккаунта:'.$group_id.'<br>' ;
         }
         elseif ($options['check_autorize_group'] and $rec_account['group_id'])
          { $group_id=$rec_account['group_id'];
            echo 'Передан флаг проверка группы авторизации аккаунта<br>' ;
            echo 'Группы авторизации аккаунта - '.$group_id.'<br>' ;
          }
          else
          { $group_id=$rec_account['parent'] ;
            echo 'Родителськая группа аккаунта - '.$group_id.'<br>' ;
          }
         // получаем первую родительскую группу у которой есть филььоы
         list($viewer_name,$workgroup_reffer)=$this->get_workgroup_active_filter_info($group_id) ;
         // если у аккаунта есть собствееные филтры отбора сотрудников - необходимо применить их на фильтр выбранной группы
         $rec_filter=PERSONALS_FILTER()->get_personals_filter_rec_to_item($rec_account['_reffer']) ;
         $rec_filter_rol=(function_exists('PERSONALS_FILTER'))? PERSONALS_FILTER()->get_personals_filter_rec_to_item($_SESSION['ARR_roll'][$rec_account['rol']]['_reffer']):[] ;
         if ($rec_filter['pkey'] and _sizeof($rec_filter['filter_set']))
         {  echo 'У аккаунта заданы собственные фильтры отбора сотрудников<br>' ;
            // необходимо создать вьювер сотрудников аккаунта: фильтр по группе + фильтр аккаунта
            $arr_reffers=[] ;
            $arr_reffers[]=$workgroup_reffer ;
            $arr_reffers[]=$rec_account['_reffer'] ;
            // второй вариант - получаем все reffer родительских разделов с фильтрами для каскадного наложения фильтров - не используем, нет необходимости в такой сложной схеме
            //$arr_reffers=$this->get_account_parent_reffers($rec_account,['check_autorize_group'=>1]) ;

            // создаем вьювер аккаунта
            $viewer_name='view_personals_account_'.$rec_account['pkey'] ;
            ///PERSONALS_FILTER()->create_viewer_personals_by_reffers($viewer_name,$arr_reffers,['debug'=>1,'create_viewer'=>1,'check_count'=>1]) ;

           if ($viewer_name!='view_personals_active') PERSONALS_FILTER()->update_viewer_personals($viewer_name) ;


            if ($options['debug']) echo '<span class="green">Используются собственные правила отбора сотрудников, вьювер аккаунта '.$viewer_name.'</span><br>' ;
         }
         else if ($rec_filter_rol['pkey'] and _sizeof($rec_filter_rol['filter_set']))
          {  echo 'У роли аккаунта заданы собственные фильтры отбора сотрудников<br>' ;
             //damp_array($rec_filter_rol);
             $viewer_name=$rec_filter_rol['viewer_name'] ;
             //if (function_exists('PERSONALS_FILTER')) PERSONALS_FILTER()->update_viewer_personals($viewer_name) ;
             if ($options['debug']) echo '<span class="green">Используются ролевые правила отбора сотрудников, вьювер роли '.$viewer_name.'</span><br>' ;
          }
         else echo 'У аккаунта нет собственных фильтров отбора сотрудников, используем вьювер группы<br>' ;
         if (!$options['no_save_viewer_name_to_account'])
         { $this->account_save($rec_account['pkey'],['viewer_name'=>$viewer_name]) ;
           echo 'Вьювер <strong>'.$viewer_name.'</strong> сохранен в записи аккаунта<br>' ;
         }
         return($viewer_name) ;
     }


     function get_account_viewer_name($rec_account,$options=array())
     {  $viewer_name='' ;
        if (_sizeof($rec_account['_ext_info']['personals']))
        { $viewer_name=$rec_account['viewer_name'] ;
          if ($options['debug']) echo '<strong>Используются собственные правила правила отбора сотрудников</strong><br>' ;
        }
        else if ($rec_account['group_id'])
        {  $rec_group=ACCOUNTS()->get_group_by_id($rec_account['group_id']) ;
           if (_sizeof($rec_group['_ext_info']['personals'])) $viewer_name=$rec_group['viewer_name'] ;
           if ($options['debug']) echo '<strong>Используются правила правила отбора группы по авторизации</strong><br>' ;
        }
        else
        {   $rec_group=ACCOUNTS()->get_group_by_id($rec_account['parent']) ;
            if (_sizeof($rec_group['_ext_info']['personals']))
            { $viewer_name=$rec_group['viewer_name'] ;
              if ($options['debug']) echo '<strong>Используются правила правила отбора родительской группы</strong><br>' ;
            }
            else
            { $viewer_name='obj_site_personals' ;
              if ($options['debug']) echo '<strong>Правила правила сотрудников не используются</strong><br>' ;
            }
        }
        return $viewer_name ;
     }

    function get_account_parent_reffers($rec_account,$options=array())
    {
      // 1 получаем группу в которой аккаунт был авторизован или находиться
      $group_id=$rec_account['parent'] ;
      if ($options['check_autorize_group'] and $rec_account['group_id']) $group_id=$rec_account['group_id'] ;
      // получаем список reffer родительских разделов
      list($viewer_name,$workgroup_reffer)=$this->get_workgroup_active_filter_info($group_id) ;
      $arr_reffers[]=$workgroup_reffer ;
      // получаем все reffer родительских разделов с фильтрами для каскадного наложения фильтров - не используем, нет необходимости в такой сложной схеме
      //$arr_reffers=$this->get_group_parent_reffers($group_id) ;
      return($arr_reffers) ;
}

 function get_group_parent_reffers($group_id)
    { $rec_group=execSQL_van('select * from obj_site_account where pkey='.$group_id) ;
      for($i=1;$i<=9;$i++) if ($rec_group['parent'.$i]) $arr_reffers[]=$rec_group['parent'.$i].'.'.$rec_group['tkey'] ;
      $arr_reffers[]=$rec_group['_reffer'] ;
      return($arr_reffers) ;

    }

      // получаем имя вьювера сотрудников рабочей группы
    // если для рабочей группы не заданы правила отбора, будет использованы правила отбора первой родительской группы, у который есть такие правила
    // если такой группы нет, используется вьювер view_personals_active
    function get_workgroup_active_filter_info($group_id)
     {   $reffer='' ;
         $arr_reffers=$this->get_group_parent_reffers($group_id) ;
         $recs=PERSONALS_FILTER()->get_personals_filter_recs_to_items($arr_reffers) ;
         $arr_reffers=array_reverse($arr_reffers) ;
         $viewer_name='view_personals_active' ;
         foreach($arr_reffers as $reffer)  if ($recs[$reffer]['viewer_name']) { $viewer_name=$recs[$reffer]['viewer_name'] ;  break ; }
         //echo 'get_workgroup_active_filter_info='.$viewer_name.'<br>' ;
         return([$viewer_name,$reffer]) ;
     }


}

function is_member_right()
{  if (MEMBER()->info['rol']==1 or  MEMBER()->info['rol']==2 or MEMBER()->info['rol']==3) return(1) ;
   return(1) ;
    //if (is_object($_SESSION['member'])) return($_SESSION['member']->right[$name]) ; else return(0) ;

}

// аккаунт
include_once(_DIR_TO_ENGINE.'/class/clss_0.php') ;
class clss_210 extends clss_0
{  // вносим в объект $member инфомацию из массива $rec
   function update_member_info(&$member,$rec)
   {   //trace() ;
       $member->info=$rec ;
       $member->id=$rec['pkey'] ;
       $member->reffer=$rec['_reffer'];
       $member->parent=$rec['parent'] ;
       $member->login=$rec['login'] ;
       $member->name=$rec['obj_name'];

       $group_setting=array() ;
       if ($member->cur_group_id and isset(ACCOUNTS()->tree[$member->cur_group_id]))
       { $member->cur_groups_visible=ACCOUNTS()->tree[$member->cur_group_id]->get_list_child() ;
         $group_setting=unserialize(execSQL_value('select settings from obj_site_account where pkey="'.MEMBER()->cur_group_id.'"')) ;
       }
       //damp_array($group_setting) ;
       $member->timezone=($group_setting['timezone'])? $group_setting['timezone']:'Europe/Moscow' ;
       date_default_timezone_set($member->timezone) ;
       //LOGS()->reg_log('timezone','clss:210->update_member_info - '.$member->timezone.' ['.date('d.m.Y H:i:s').'] '._CUR_PAGE_DIR) ;


       // 1. фильтрация персонала по сопоставлению организация - группа
       if ($member->cur_group_id)
       { $org_ids=execSQL_line('select pkey from obj_site_personals where clss=207 and group_id='.$member->cur_group_id) ;
       //print_r($org_ids) ;
       if (_sizeof($org_ids))
       {
         $member->setting['personal']['usl_select']='clss=211 and enabled=1 and (ext=0 or ext is null) and parent2 in ('.implode(',',$org_ids).')' ;
         $member->setting['personal']['name']='Фильтр сопоставления организация - группа ЭСМО' ;
       }
       }
       // сохраняем в аккаунте настройки по фильтрации персонала
       // 2. фильтрация персонала от группам
       if (isset($group_setting['personal']) and $group_setting['personal']['usl_select'])
       { $member->setting['personal']=$group_setting['personal'] ;
         $member->setting['personal']['name']='Фильтр группы' ;
       }
       // 3. фильтрация персонала от аккаунта
       if (isset($rec['_ext_info']['personal']) and $rec['_ext_info']['personal']['usl_select'])
       { $member->setting['personal']=$rec['_ext_info']['personal'] ;
         $member->setting['personal']['name']='Фильтр аккаунта' ;
       }

       // aspmo
       $member->rol=$rec['rol'];
       $member->working=$rec['_rol_name'];
       $member->use_auch_as_smena=$_SESSION['ARR_roll'][$rec['rol']]['use_auch_as_smena']   ;
       $member->smena_monopole_mode=$_SESSION['ARR_roll'][$rec['rol']]['smena_monopole_mode']   ;
       $member->autologout=$_SESSION['ARR_roll'][$rec['rol']]['autologout']   ;

       //$member->right=$rec['_right'] ;

       if ($rec['smena_in']) $member->_smena_in=date('d.m.Y H:i',$rec['smena_in']) ;
       if ($rec['smena_out']) $member->_smena_out=date('d.m.Y H:i',$rec['smena_out']) ;

       // учет ситуации, когда фельдшер авторизуется при незавершенной смене
       if ($rec['smena']==4 and $rec['smena_in'] and !$rec['smena_out'])  $rec['smena']=2 ;
       $member->_smena_status=$_SESSION['ARR_smena_status'][$rec['smena']] ;

       $member->certificate=$rec['_ext_info']['certificate'] ;
       $member->cryptopro=$rec['_ext_info']['cryptopro'] ;
       /// временно для совместимости данных
       if (!$member->certificate['SerialNumber'] and $rec['sert_id']) $member->certificate['SerialNumber']=$rec['sert_id'] ;
       if (!$member->certificate['SubjectName'] and $rec['sert_name']) $member->certificate['SubjectName']=$rec['sert_name'] ;
       if (!$member->certificate['IssuerName'] and $rec['sert_ud']) $member->certificate['IssuerName']=$rec['sert_ud'] ;
       if (!$member->certificate['ValidFromDate'] and $rec['sert_from']) $member->certificate['ValidFromDate']=date('d.m.Y H:i:s',$rec['sert_from']) ;
       if (!$member->certificate['ValidToDate'] and $rec['sert_to']) $member->certificate['ValidToDate']=date('d.m.Y H:i:s',$rec['sert_to']) ;

       //damp_array($member,1,-1) ;
   }

    // после создания объекта создаем для него расчетный счет
    // что-то не работает
    function on_create_event($obj_info)
    { if (is_object($_SESSION['esmo_billing_system'])) $_SESSION['esmo_billing_system']->clss_210_on_create_event($obj_info)  ;
    }

    function on_change_event($tkey,$pkey,$fname,&$fvalue)
    {   // при сохранении пароля переводим его в хеш
        if ($fname=='password')
        {
            $login=execSQL_value('select login from '._DOT($tkey)->table_name.' where pkey='.$pkey) ;
            $fvalue=ACCOUNTS()->get_pass_hash($login,$fvalue) ;

        }
        return parent::on_change_event($tkey,$pkey,$fname,$fvalue); // TODO: Change the autogenerated stub
    }
}



?>
