<?php
$__functions['init'][]='_daily_briefing_site_vars' ;
$__functions['boot_site'][]='_daily_briefing_site_boot' ;

function DAILY_BRIEFING()
{
    if (is_object($_SESSION['daily_briefing_system'])) return($_SESSION['daily_briefing_system']);
    $_SESSION['daily_briefing_system']=new c_daily_briefing_system();
    return($_SESSION['daily_briefing_system']);
}

function _daily_briefing_site_vars()
{
    $_SESSION['ARR_daily_briefing_types']=array(
        'technician_instruction'=>'Инструктаж техника'
    ) ;

    $_SESSION['ARR_daily_briefing_pass_status']=array(
        1=>'Прибыл на инструктаж',
        2=>'Инструктаж пройден'
    ) ;

    $_SESSION['init_options']['daily_briefing']['debug']=0 ;
}

function _daily_briefing_site_boot($options)
{
    create_system_modul_obj('daily_briefing',$options) ;
}

class c_daily_briefing_system
{
    public $table_list='daily_briefing_list' ;
    public $table_pass='daily_briefing_pass' ;
    public $sign_dir='/public/daily_briefing_sign/' ;
    public $sign_data_dir='/public/daily_briefing_sign_data/' ;

    function __construct($create_options=array())
       { ENGINE()->reg_ext('daily_briefing','Ежедневные инструктажи') ;
       }

    function declare_menu_items_2($page)
    {
        $page->menu['/cab/daily_briefing/']=array('title'=>'Ежедневные инструктажи',
                                                  'class'=>'fa fa-list-alt',
                                                  'allow_access_to_rol'=>9,
                                                  'items'=>array('/cab/daily_briefing/'=>'Рабочее место техника')
        ) ;
    }

    function get_briefing_by_id($id)
    {
        $rec=execSQL_van('select * from '.$this->table_list.' where pkey='.(int)$id);
        if ($rec['pkey']) $rec=$this->prepare_briefing_rec($rec);
        return $rec;
    }

    function get_briefings($options=array())
    {
        $usl=array('enabled=1');
        //if (!$options['all_groups']) $usl[]='group_id='.(int)MEMBER()->cur_group_id;
        if ($options['briefing_type']) $usl[]='briefing_type="'.addslashes($options['briefing_type']).'"';
        $sql='select * from '.$this->table_list.' where '.implode(' and ',$usl).' order by pkey desc';
        $recs=execSQL($sql,0,1);
        if (_sizeof($recs)) foreach($recs as $id=>$rec) $recs[$id]=$this->prepare_briefing_rec($rec);
        return $recs;
    }

    function prepare_briefing_rec($rec)
    {
        $rec['__href']='/cab/daily_briefing/card/'.$rec['pkey'].'/';
        $rec['_briefing_type_name']=$_SESSION['ARR_daily_briefing_types'][$rec['briefing_type']];
        return $rec;
    }

    function create_briefing($name,$options=array())
    {
        $name=trim($name);
        if (!$name) return 0;

        $data=array(
            'clss'=>269,
            'parent'=>1,
            'obj_name'=>$name,
            'briefing_type'=>($options['briefing_type'])?$options['briefing_type']:'technician_instruction',
            'account_create_id'=>MEMBER()->id,
            'group_id'=>MEMBER()->cur_group_id,
            'enabled'=>1
        );

        return adding_rec_to_table($this->table_list,$data,array('no_auto_indx'=>1));
    }

    function update_briefing_name($id,$name)
    {
        $id=(int)$id;
        $name=trim((string)$name);
        if (!$id || $name==='') return false;
        $rec=$this->get_briefing_by_id($id);
        if (!$rec['pkey']) return false;
        update_rec_in_table($this->table_list,array('obj_name'=>$name),'pkey='.$id,array('debug'=>0));
        return true;
    }

    function delete_briefing($id)
    {
        $id=(int)$id;
        if (!$id) return false;
        $rec=$this->get_briefing_by_id($id);
        if (!$rec['pkey']) return false;
        update_rec_in_table($this->table_list,array('enabled'=>0),'pkey='.$id,array('debug'=>0));
        return true;
    }

    function normalize_pass_number($pass)
    {
        return trim(str_replace(array("'",'"','(',')',' ',"\n","\r","\t"),'',$pass));
    }

    function find_personal_by_pass($pass)
    {
        $pass=$this->normalize_pass_number($pass);
        if (!$pass) return array();

        $rec=PERSONAL()->get_personal_by_propusk($pass);
        if (!$rec['pkey']) {
            $pass_en=ENGINE()->translit3($pass);
            if ($pass_en!=$pass) $rec=PERSONAL()->get_personal_by_propusk($pass_en);
        }
        return $rec;
    }

    function get_day_range($time=0)
    {
        if (!$time) $time=time();
        $date=getdate($time);
        $time_from=mktime(0,0,0,$date['mon'],$date['mday'],$date['year']);
        $time_to=mktime(23,59,59,$date['mon'],$date['mday'],$date['year']);
        return array($time_from,$time_to);
    }

    function get_today_pass_by_person($briefing_id,$personal_id,$time=0)
    {
        list($time_from,$time_to)=$this->get_day_range($time);
        return execSQL_van('select * from '.$this->table_pass.'
                            where briefing_id='.(int)$briefing_id.' and personal_id='.(int)$personal_id.'
                              and c_data>='.(int)$time_from.' and c_data<='.(int)$time_to.'
                            order by pkey desc limit 1');
    }

    function register_arrive($briefing_id,$propusk,$options=array())
    {
        $briefing_id=(int)$briefing_id;
        $rec_briefing=$this->get_briefing_by_id($briefing_id);
        if (!$rec_briefing['pkey']) return array('error'=>'Инструктаж не найден');

        $propusk=$this->normalize_pass_number($propusk);
        if (!$propusk) return array('error'=>'Не указан пропуск');

        $rec_personal=$this->find_personal_by_pass($propusk);
        if (!$rec_personal['pkey']) return array('error'=>'Пропуск "'.htmlspecialchars($propusk).'" не найден');

        $rec_pass=$this->get_today_pass_by_person($briefing_id,$rec_personal['pkey']);
        if ($rec_pass['pkey']) {
            if ($rec_pass['status']==1) $result_text='Сотрудник уже прибыл на инструктаж';
            elseif ($rec_pass['status']==2) $result_text='Сотрудник уже прошел инструктаж сегодня';
            else $result_text='Запись по сотруднику уже существует';

            $rec_pass=$this->get_pass_by_id($rec_pass['pkey']);
            return array('briefing'=>$rec_briefing,'personal'=>$rec_personal,'pass'=>$rec_pass,'message'=>$result_text,'already_exists'=>1);
        }

        $data=array(
            'clss'=>270,
            'parent'=>$briefing_id,
            'briefing_id'=>$briefing_id,
            'personal_id'=>$rec_personal['pkey'],
            'propusk'=>$propusk,
            'status'=>1,
            'account_arrive_id'=>($options['account_id'])?(int)$options['account_id']:(int)MEMBER()->id,
            'arrive_time'=>time(),
            'group_id'=>($options['group_id'])?(int)$options['group_id']:(int)MEMBER()->cur_group_id
        );
        $pass_id=adding_rec_to_table($this->table_pass,$data,array('no_auto_indx'=>1));
        $rec_pass=$this->get_pass_by_id($pass_id);

        return array('briefing'=>$rec_briefing,'personal'=>$rec_personal,'pass'=>$rec_pass,'message'=>'Сотрудник зарегистрирован на инструктаж','already_exists'=>0);
    }

    function get_pass_by_id($id)
    {
        $rec=execSQL_van('select * from '.$this->table_pass.' where pkey='.(int)$id);
        if ($rec['pkey']) $rec=$this->prepare_pass_rec($rec);
        return $rec;
    }

    function prepare_pass_rec($rec)
    {
        $rec['_status_name']=$_SESSION['ARR_daily_briefing_pass_status'][$rec['status']];
        $rec['__sign_src']=($rec['sign_fname'])?$this->sign_dir.$rec['sign_fname']:'';
        $rec['__sign_data_src']=($rec['sign_data_fname'])?$this->sign_data_dir.$rec['sign_data_fname']:'';
        return $rec;
    }

    function save_signature($pass_id,$image,$sign_data='',$options=array())
    {
        $pass_id=(int)$pass_id;
        $rec_pass=$this->get_pass_by_id($pass_id);
        if (!$rec_pass['pkey']) return array('error'=>'Запись инструктажа не найдена');
        if (!$rec_pass['personal_id']) return array('error'=>'Не указан сотрудник');
        if (!$image) return array('error'=>'Не передана подпись');

        $this->check_storage_dirs();

        $fname='daily_briefing_'.$rec_pass['briefing_id'].'_'.$rec_pass['personal_id'].'_'.$rec_pass['pkey'].'.png';
        $data_fname='daily_briefing_'.$rec_pass['briefing_id'].'_'.$rec_pass['personal_id'].'_'.$rec_pass['pkey'].'.json';

        $result=$this->save_base64_image($image,_DIR_TO_ROOT.$this->sign_dir.$fname);
        if (!$result) return array('error'=>'Не удалось сохранить файл подписи');

        if (!$this->save_text_file($sign_data,_DIR_TO_ROOT.$this->sign_data_dir.$data_fname)) {
            return array('error'=>'Не удалось сохранить цифровой слепок подписи');
        }

        update_rec_in_table($this->table_pass,array(
            'status'=>2,
            'sign_fname'=>$fname,
            'sign_data_fname'=>$data_fname,
            'account_sign_id'=>($options['account_id'])?(int)$options['account_id']:(int)MEMBER()->id,
            'sign_time'=>time()
        ),'pkey='.$rec_pass['pkey'],array('debug'=>0));

        return array('pass'=>$this->get_pass_by_id($rec_pass['pkey']));
    }

    function check_storage_dirs()
    {
        if (!is_dir(_DIR_TO_ROOT.$this->sign_dir)) @mkdir(_DIR_TO_ROOT.$this->sign_dir,_CREATE_DIR_PERMS);
        if (!is_dir(_DIR_TO_ROOT.$this->sign_data_dir)) @mkdir(_DIR_TO_ROOT.$this->sign_data_dir,_CREATE_DIR_PERMS);
    }

    function save_base64_image($data,$abs_fname)
    {
        $data=trim($data);
        if (!$data) return false;
        $data=preg_replace('/^data:image\/[a-zA-Z0-9\+\-]+;base64,/', '', $data);
        $img_string=base64_decode($data);
        if ($img_string===false) return false;
        if (file_exists($abs_fname)) unlink($abs_fname);
        return (bool)file_put_contents($abs_fname,$img_string);
    }

    function save_text_file($text,$abs_fname)
    {
        if (file_exists($abs_fname)) unlink($abs_fname);
        return (bool)file_put_contents($abs_fname,(string)$text);
    }

    function count_passes($briefing_id,$time_from,$time_to,$options=array())
    {
        $usl=array('briefing_id='.(int)$briefing_id);
        $time_field=($options['time_field'])?$options['time_field']:'arrive_time';
        $usl[]=$time_field.'>='.(int)$time_from;
        $usl[]=$time_field.'<='.(int)$time_to;
        if ($options['status']) $usl[]='status='.(int)$options['status'];
        if ($options['account_arrive_id']) $usl[]='account_arrive_id='.(int)$options['account_arrive_id'];
        if ($options['account_sign_id']) $usl[]='account_sign_id='.(int)$options['account_sign_id'];
        return (int)execSQL_value('select count(pkey) from '.$this->table_pass.' where '.implode(' and ',$usl));
    }

    function get_stats($briefing_id)
    {
        list($today_from,$today_to)=$this->get_day_range();
        list($yesterday_from,$yesterday_to)=$this->get_day_range($today_from-3600);
        $week_from=$today_from-6*86400;
        $week_to=$today_to;

        $opt_arrive=array();
        $opt_sign=array();
        if ((int)MEMBER()->rol===9) {
            $mid=(int)MEMBER()->id;
            $opt_arrive=array('account_arrive_id'=>$mid);
            $opt_sign=array('account_sign_id'=>$mid);
        }

        return array(
            'yesterday'=>array(
                'arrived'=>$this->count_passes($briefing_id,$yesterday_from,$yesterday_to,array_merge(array('time_field'=>'arrive_time'),$opt_arrive)),
                'completed'=>$this->count_passes($briefing_id,$yesterday_from,$yesterday_to,array_merge(array('time_field'=>'sign_time','status'=>2),$opt_sign))
            ),
            'today'=>array(
                'arrived'=>$this->count_passes($briefing_id,$today_from,$today_to,array_merge(array('time_field'=>'arrive_time'),$opt_arrive)),
                'completed'=>$this->count_passes($briefing_id,$today_from,$today_to,array_merge(array('time_field'=>'sign_time','status'=>2),$opt_sign))
            ),
            'week'=>array(
                'arrived'=>$this->count_passes($briefing_id,$week_from,$week_to,array_merge(array('time_field'=>'arrive_time'),$opt_arrive)),
                'completed'=>$this->count_passes($briefing_id,$week_from,$week_to,array_merge(array('time_field'=>'sign_time','status'=>2),$opt_sign))
            )
        );
    }

    /**
     * Статистика по инструкторам (прибытие — account_arrive_id, завершение с подписью — account_sign_id).
     * Для роли 9 — только текущий пользователь (как в get_stats).
     */
    function get_stats_by_instructors($briefing_id)
    {
        $bid=(int)$briefing_id;
        if (!$bid) {
            return array();
        }

        list($today_from,$today_to)=$this->get_day_range();
        list($yesterday_from,$yesterday_to)=$this->get_day_range($today_from-3600);
        $week_from=$today_from-6*86400;
        $week_to=$today_to;

        $extra_arrive='';
        $extra_sign='';
        if ((int)MEMBER()->rol===9) {
            $mid=(int)MEMBER()->id;
            $extra_arrive=' and account_arrive_id='.$mid;
            $extra_sign=' and account_sign_id='.$mid;
        }

        $tbl=$this->table_pass;

        $map_grouped=function($rows) {
            $out=array();
            if (_sizeof($rows)) {
                foreach($rows as $r) {
                    $aid=(int)$r['aid'];
                    if ($aid) {
                        $out[$aid]=(int)$r['cnt'];
                    }
                }
            }
            return $out;
        };

        $q_arrive=function($from,$to,$extra) use ($tbl,$bid,$map_grouped) {
            $sql='select account_arrive_id as aid, count(pkey) as cnt from '.$tbl.'
                  where briefing_id='.$bid.' and arrive_time>='.(int)$from.' and arrive_time<='.(int)$to.'
                    and account_arrive_id>0 '.$extra.' group by account_arrive_id';
            return $map_grouped(execSQL($sql,0,1));
        };

        $q_sign=function($from,$to,$extra) use ($tbl,$bid,$map_grouped) {
            $sql='select account_sign_id as aid, count(pkey) as cnt from '.$tbl.'
                  where briefing_id='.$bid.' and sign_time>='.(int)$from.' and sign_time<='.(int)$to.'
                    and status=2 and account_sign_id>0 '.$extra.' group by account_sign_id';
            return $map_grouped(execSQL($sql,0,1));
        };

        $today_a=$q_arrive($today_from,$today_to,$extra_arrive);
        $today_s=$q_sign($today_from,$today_to,$extra_sign);
        $yesterday_a=$q_arrive($yesterday_from,$yesterday_to,$extra_arrive);
        $yesterday_s=$q_sign($yesterday_from,$yesterday_to,$extra_sign);
        $week_a=$q_arrive($week_from,$week_to,$extra_arrive);
        $week_s=$q_sign($week_from,$week_to,$extra_sign);

        $ids=array_keys($today_a+$today_s+$yesterday_a+$yesterday_s+$week_a+$week_s);
        if (!_sizeof($ids)) {
            return array();
        }

        sort($ids,SORT_NUMERIC);
        $names_map=ACCOUNTS()->get_names_by_ids($ids);

        $rows=array();
        foreach($ids as $aid) {
            $name=(isset($names_map[$aid]) && $names_map[$aid]!=='')?$names_map[$aid]:('Аккаунт #'.$aid);
            $rows[]=array(
                'account_id'=>$aid,
                'name'=>$name,
                'today'=>array(
                    'arrived'=>isset($today_a[$aid])?$today_a[$aid]:0,
                    'completed'=>isset($today_s[$aid])?$today_s[$aid]:0
                ),
                'yesterday'=>array(
                    'arrived'=>isset($yesterday_a[$aid])?$yesterday_a[$aid]:0,
                    'completed'=>isset($yesterday_s[$aid])?$yesterday_s[$aid]:0
                ),
                'week'=>array(
                    'arrived'=>isset($week_a[$aid])?$week_a[$aid]:0,
                    'completed'=>isset($week_s[$aid])?$week_s[$aid]:0
                )
            );
        }

        usort($rows,function($a,$b) {
            return strcmp($a['name'],$b['name']);
        });

        return $rows;
    }

    function get_today_completed_count($briefing_id)
    {
        list($today_from,$today_to)=$this->get_day_range();
        $opt=array('time_field'=>'sign_time','status'=>2);
        if ((int)MEMBER()->rol===9) $opt['account_sign_id']=(int)MEMBER()->id;
        return $this->count_passes($briefing_id,$today_from,$today_to,$opt);
    }

    function get_today_waiting_sign_count($briefing_id)
    {
        list($today_from,$today_to)=$this->get_day_range();
        $opt=array('time_field'=>'arrive_time','status'=>1);
        if ((int)MEMBER()->rol===9) $opt['account_arrive_id']=(int)MEMBER()->id;
        return $this->count_passes($briefing_id,$today_from,$today_to,$opt);
    }

    function get_passes($options=array())
    {
        $usl=array('1=1');
        if ($options['briefing_id']) $usl[]='briefing_id='.(int)$options['briefing_id'];
        if ($options['personal_id']) $usl[]='personal_id='.(int)$options['personal_id'];
        if ($options['status']) $usl[]='status='.(int)$options['status'];
        if (!$options['all_groups']) $usl[]='group_id='.(int)MEMBER()->cur_group_id;
        if ($options['account_arrive_id']) $usl[]='account_arrive_id='.(int)$options['account_arrive_id'];
        if ($options['account_sign_id']) $usl[]='account_sign_id='.(int)$options['account_sign_id'];
        if ($options['for_instructor_journal'] && (int)MEMBER()->rol===9) {
            $mid=(int)MEMBER()->id;
            $usl[]='(account_arrive_id='.$mid.' or account_sign_id='.$mid.')';
        }

        $time_field=($options['time_field'])?$options['time_field']:'arrive_time';
        if ($options['date_from']) $usl[]=$time_field.'>='.(int)strtotime($options['date_from'].' 00:00:00');
        if ($options['date_to']) $usl[]=$time_field.'<='.(int)strtotime($options['date_to'].' 23:59:59');

        $sql='select * from '.$this->table_pass.' where '.implode(' and ',$usl);
        $sql.=' order by '.(($options['order'])?$options['order']:'pkey desc');
        if ($options['limit']) $sql.=' limit '.(int)$options['limit'];

        $recs=execSQL($sql,0,1);
        if (_sizeof($recs)) foreach($recs as $id=>$rec) $recs[$id]=$this->prepare_pass_rec($rec);
        return $recs;
    }
}
?>
