['project'=>[],'total'=>[],'absence'=>[],'title'=>Merakomis::getMonth(date('m')).' '.date('Y').' г.'], 'year' =>['project'=>[],'total'=>[],'absence'=>[],'title'=>date('Y').' г.'], ]; $period = [ 'month'=>[date('Y-m-01'),date('Y-m-d')], 'year' =>[date('Y-01-01'),date('Y-m-d')], ]; $data = []; $projects = []; $absence = []; foreach ($period as $type=>$p){ $begin = $p[0]; $end = $p[1]; $r = Time::select($q = [ \Query::TABLES => [self::$table_name], \Query::SELECT => [ Project::$ID, Project::$NAME, Project::$CODE, Project::$STEP, 'SUM('.self::$DURATION.') as dur', self::$IS_OVER, ], \Query::LEFT_JOINS => [ [Project::$table_name,Project::$ID,self::$PROJECT], ], \Query::WHERE => new \Where(\Where::_and([ \Where::_operator(self::$EMP,'=',$emp_id), \Where::_between(self::$DATE,$begin,$end), ])), \Query::GROUP_BY => [self::$PROJECT,self::$IS_OVER], ]); while($l = \DB::fetch($r)){ $pid = $l[Project::$ID]; $projects[$pid] = $l; $isOver = boolval($l[self::$IS_OVER]); $data[$type]['project'][$pid]+= $l['dur']; $data[$type]['hours'] += $isOver ? 0 : $l['dur']; $data[$type]['over'] += $isOver ? $l['dur'] : 0; } $r = Absence::select([ \Query::LEFT_JOINS => [ [DAbsence::$table_name,DAbsence::$ID,Absence::$ABSENCE] ], \Query::SELECT => [ DAbsence::$NAME, DAbsence::$CODE, DAbsence::$ID, 'COUNT('.Absence::$ID.') as c', ], \Query::WHERE => new \Where(\Where::_and([ \Where::_operator(Absence::$EMP,'=',$emp_id), \Where::_between(Absence::$DATE,$begin,$end), ])), \Query::GROUP_BY=>[Absence::$ABSENCE], ]); while($l = \DB::fetch($r)){ $id = $l[DAbsence::$ID]; if($id) { $absence[$id] = $l; $data[$type]['absence'][$id] += $l['c']; } } } foreach ($data as $type=>$d){ $class0 = 1; $class1 = 1; $res[$type]['total'][] = ['title'=>'Раб.','value'=>$d['hours'],'class'=>'color-green']; $res[$type]['total'][] = ['title'=>'Сверх.','value'=>$d['over'],'class'=>'color-brown']; foreach ($d['project'] as $pid=>$value) { $res[$type]['project'][] = ['title'=>Project::getCodeName($projects[$pid]),'value'=>$value,'class'=>'chart-color'.($class0++)]; } foreach ($d['absence'] as $pid=>$value) { $res[$type]['absence'][] = ['title'=>DAbsence::getCode($absence[$pid]),'value'=>$value,'class'=>'chart-color'.($class1++)]; } } Merakomis::graphClass($res['month']['project'],true,true); Merakomis::graphClass($res['year']['project'],true,true); $res['text'] = Merakomis::$MY_TABLE_3; return $res; } public function _insert(array $values, array $options = array()) { $options[\Query::ON_DUPLICATE_KEY_UPDATE] = [ self::$DURATION => $values[self::$DURATION], ]; $res = parent::_insert($values, $options); // TODO: Change the autogenerated stub $C = self::getByID($res->id); if(!$values[self::$DURATION]){ self::deleteByID($res->id); } Cache::removeRows($C[self::$DATE],$C[self::$EMP],$C[self::$PROJECT]); return $res; } static function getTimeTable($project_id,$emp_id,$year=null,$month=null) { $absence_options = []; $project_id = intval($project_id); $emp_id = intval($emp_id); $graph1 = []; $graph2 = []; $events = []; $totals = []; $r = Time::select([ \Query::SELECT => [ self::$DATE, self::$IS_OVER, self::$DURATION, Project::$ID, Project::$NAME, Project::$CODE, Project::$STEP, ], \Query::LEFT_JOINS => [ [Project::$table_name,Project::$ID,Time::$PROJECT], ], \Query::WHERE => new \Where(\Where::_and([ \Where::_operator(self::$DURATION,'>',0), $project_id ? \Where::_operator(self::$PROJECT,'=',$project_id) : null, \Where::_operator(self::$EMP,'=',$emp_id), ])) ]); $dates = []; $period = date(implode("-",[$year?:date('Y'),$month?:date('m')])); $total = []; $months = []; while($l = \DB::fetch($r)){ $dur = cfloatval($l[self::$DURATION]); $key = $l[self::$IS_OVER]?'over':'hours'; $dates[$l[self::$DATE]][$key] += $dur; $time = strtotime($l[self::$DATE]); $y = intval(date('Y',$time)); $m = intval(date('m',$time)); $months[$y][$m][$key] += $dur; $months[$y][$m]['total'] += $dur; $total[$key] += $dur; $total['total'] += $dur; $pid = intval($l[Project::$ID]); //$project_code = $l[Project::$CODE]; $project_code = Project::getCodeName($l); $totals[$l[self::$DATE]][$key][$project_code] += $dur; if($dur) { //$graph1[$y][$m][$pid]['title'] = Project::getCode($l); $graph1[$y][$m][$pid]['title'] = Project::getCodeName($l); $graph1[$y][$m][$pid]['value'] += $dur; } } foreach ($graph1 as $k=>&$v){ $v['value'] = round( ($total['total'] ? $v['value'] / $total['total'] : 0)*100,0 ); } unset($v); //$graph1 = array_values($graph1); //Merakomis::graphClass($graph1,true,true,true); $absence = []; $absence_stat = []; $r = Absence::select([ \Query::LEFT_JOINS => [ [DAbsence::$table_name,DAbsence::$ID,Absence::$ABSENCE] ], \Query::WHERE=> new \Where(\Where::_and([ \Where::_operator(Absence::$EMP,'=',$emp_id), \Where::_operator(Absence::$ABSENCE,'<>',0), ])) ]); $total_absence = 0; while($l = \DB::fetch($r)){ $absence[$l[Absence::$DATE]] =$d = [ 'id'=>intval($l[Absence::$ID]), 'title'=>$title = DAbsence::getName($l), 'code'=>$l[DAbsence::$CODE], 'absence_id'=>$absence_id = intval($l[DAbsence::$ID]), ]; $time = strtotime($l[Absence::$DATE]); $y = intval(date('Y',$time)); $m = intval(date('m',$time)); $absence_stat[$y][$m]++; $graph2[$y][$m][$absence_id]['title'] = $l[DAbsence::$CODE]; $graph2[$y][$m][$absence_id]['value']++; $total_absence++; } /* foreach ($graph2 as $k=>&$v){ $v['value'] = round( ($total_absence ? $v['value'] / $total_absence : 0)*100,0 ); } unset($v); */ foreach ($graph1 as $y=>$ms){ foreach ($ms as $m=>$v) { $graph1[$y][$m] = array_values($graph1[$y][$m]); //Merakomis::graphClass($graph1[$y][$m], true, true); $t = 0; foreach ($graph1[$y][$m] as $vv){ $t += $vv['value']; } foreach ($graph1[$y][$m] as $k=>$vv){ $graph1[$y][$m][$k]['value'] = floor(($t ? $vv['value']/$t : 0) * 100); } Merakomis::graphClass($graph1[$y][$m],true,true,true); } } foreach ($graph2 as $y=>$ms){ foreach ($ms as $m=>$v) { $graph2[$y][$m] = array_values($graph2[$y][$m]); Merakomis::graphClass($graph2[$y][$m], true, true); } } if($project_id) { $project = Project::getByID($project_id); $member = Member::getByEmpAndProject($emp_id, $project_id); $isCanEdit = (boolval($member[Member::$ACTIVE]) and $member[Member::$EMP] == Emp::$AUTH_ID and !$project[Project::$ARCHIVE]) || Rules::isWriteOtherTableWrite($emp_id) //|| $project[Project::$DIRECTOR] == Emp::$AUTH_ID //|| Emp::isSuperView(); ; $days = Day::getByRangeFormatted($day_begin = $project[Project::$DATE] ? : '2000-01-01',$day_end = date('Y-m-d')); } else { $project = null; $isCanEdit = false; $days = Day::getByRangeFormatted( '2000-01-01',$day_end = date('Y-m-d')); } $a = Day::getAll(); foreach ($a as $v){ $events[$v[Day::$DATE]][] = $v[Day::$TEXT]; } /* $a = Event::getAll(); foreach ($a as $v){ $events[$v[Event::$DATE]][] = $v[Event::$NAME]; } */ $base = []; $r = Time::select([ \Query::SELECT => [ self::$DATE,self::$IS_OVER,'SUM('.self::$DURATION.') as cc', ], \Query::WHERE => \Where::_operator(self::$EMP,'=',$emp_id), \Query::GROUP_BY => [ self::$DATE,self::$IS_OVER ], ]); while($l = \DB::fetch($r)){ $base[$l[self::$DATE]][ $l[self::$IS_OVER] ? 'over' : 'hours'] += intval($l['cc']); } $_absence_options = DAbsence::getNameList(([ 'zero'=>true, \Query::WHERE => new \Where(\Where::_or([ \Where::_operator(DAbsence::$VIS,'=',1), ])) ])); $absence_options = []; foreach ($_absence_options as $k=>$v){ $absence_options[] = ['id'=>$k,'title'=>$v]; } foreach ($totals as $date=>$keys){ foreach ($keys as $key=>$p){ $x = []; foreach ($p as $k=>$v){ $x[] = $k.": ".$v; } $totals[$date][$key] = implode("
",$x); } } $isModal = $_POST['is_modal']; // 'Обратите внимание, изменился способ указания нерабочих дней. Теперь для указания причины отсутствия на рабочем месте необходимо выбрать один или несколько дней, включив чек-бокс на ячейке календаря. После этого в выпадающем меню «Активность» выберите причину отсутствия. ' // 'Сводный табель предназначен для демонстрации суммы часов, которые вы ввели за день. Для ввода потраченных на проект выберите соответствующий проект в сайдбаре слева.' //$isCanEdit = false; $res = [ //'ggg'=>$ggg, 'can_edit' => $isCanEdit, 'cant_edit' => !$isCanEdit, 'dates' => $dates, 'days' => $days, 'day_begin' => $day_begin, 'day_end' => $day_end, 'name' => $emp_name = Emp::getName( Emp::getByID($emp_id) ), 'project' => $project ? Project::getCode( $project ) : ($isModal ? $emp_name : 'Сводный табель'), 'text' => $project ? Merakomis::$MY_TABLE_2 : Merakomis::$MY_TABLE_1, 'archive' => !boolval($member[Member::$ACTIVE]), 'month' => $months, 'absence' => $absence, 'absence_stat' => $absence_stat, 'absence_options' => $absence_options, 'project_date' => $project[Project::$DATE], 'events' => $events, 'base' => $base, 'graph1' => $graph1, 'graph2' => $graph2, 'totals' => $totals, 'total'=>[ 'hours' => cfloatval($total['hours']).' час.', 'over' => cfloatval($total['over']).' час.', 'total' => cfloatval($total['total']).' час.', ], //'cant_edit'=>Emp::isMeTopManager() && $emp_id!=Emp::$AUTH_ID, ]; return $res; } static $CACHE = []; static $CACHE_PERIOD = []; static function getPeriod($begin,$end) { $key = md5((string)$begin.(string)$end); if(isset(self::$CACHE_PERIOD[$key])){ return self::$CACHE_PERIOD[$key]; } $d1 = strtotime($begin); $d2 = strtotime($end); $y1 = intval(date('Y',$d1)); $y2 = intval(date('Y',$d2)); $res = []; for($y=$y1;$y<=$y2;$y++){ $minMonth = $y==$y1 ? intval(date('m',$d1)) : 1; $maxMonth = $y==$y2 ? intval(date('m',$d2)) : 12; for($m=$minMonth;$m<=$maxMonth;$m++){ $res[] = [$y,$m]; } } return self::$CACHE_PERIOD[$key] = $res; } static $CACHE_PERIOD_WITH_DAYS = []; static function getPeriodWithDays($begin,$end) { $key = md5((string)$begin.(string)$end); if(isset(self::$CACHE_PERIOD_WITH_DAYS[$key])){ return self::$CACHE_PERIOD_WITH_DAYS[$key]; } $d1 = strtotime($begin); $d2 = strtotime($end); $y1 = intval(date('Y',$d1)); $y2 = intval(date('Y',$d2)); $res = []; for($y=$y1;$y<=$y2;$y++){ $minMonth = $y==$y1 ? intval(date('m',$d1)) : 1; $maxMonth = $y==$y2 ? intval(date('m',$d2)) : 12; for($m=$minMonth;$m<=$maxMonth;$m++){ $bd = $y==$y1 && $m==$minMonth ? date('d',strtotime($begin)) : '01'; $ed = $y==$y2 && $m==$maxMonth ? date('d',strtotime($end)) : date('d',strtotime($y.'-'.$m.'-01 +1 month -1 day')); $res[] = [ $y.'-'.($m<10?'0':'').$m.'-'.$bd, $y.'-'.($m<10?'0':'').$m.'-'.$ed, ]; } } return self::$CACHE_PERIOD_WITH_DAYS[$key] = $res; } static $CACHE_TIMES_WITH_FOT = []; static function getEmpsTimeWithFot($begin,$end,$_emp_id,$_project_id = null){ $key = md5($begin.":".$end.":".$_emp_id.":".$_project_id); if(isset(self::$CACHE_TIMES_WITH_FOT[$key])){ return self::$CACHE_TIMES_WITH_FOT[$key]; } $res = []; $period = self::getPeriod($begin,$end); //$res['period'] = $period; $res = [ 'hours'=>0, 'over' =>0, 'over1'=>0, 'over2'=>0, 'total'=>0, 'fot'=>[], 'money'=>0, 'money_hours'=>0, 'money_over1'=>0, 'money_over2'=>0, 'period'=>[], 'money_period'=>[], //'q'=>(string)new \Query($q), ]; $variables = Variable::getAllVariables(); $beginYear = date('Y',strtotime($begin)); $beginMonth = date('n',strtotime($begin)); $dayBegin = date('d',strtotime($begin)); $endYear = date('Y',strtotime($end)); $endMonth = date('n',strtotime($end)); foreach ($period as $p){ $year = $p[0]; $month = $p[1]; $isBegin = $year==$beginYear && $month==$beginMonth; $isEnd = $year==$endYear && $month==$endMonth; $b = $isBegin ? $begin : date('Y-m-d',strtotime($p[0].'-'.$p[1].'-01')); $e = $isEnd ? $end : date('Y-m-d', strtotime(($p[0].'-'.$p[1].'-01') . ' +1 month -1 day')); //$res['period'][$p[0]][$p[1]] = [$b,$e]; //$per_dur = $dur * self::$PER_HOUR; $fot = Fot::getForEmp($_emp_id, $year, $month); $per_hour = $fot ? cfloatval($fot[Fot::$PER_HOUR]) : 0; $res['fot'][$year][$month] = $per_hour; //$time_and = \Where::_between(self::$DATE,$b,$e); $info = self::getEmpsTime($b,$e,$_emp_id,$_project_id); $res['info'][$year][$month] = $info; $vars = $variables[$year]; $per_hour1 = $per_hour * (( $vars ? cfloatval($vars[Variable::$K1]) : 1 )); $per_hour2 = $per_hour * (( $vars ? cfloatval($vars[Variable::$K2]) : 1 )); foreach ($info as $k=>$v){ if($k=='period'){ foreach ($v as $y=>$mm){ foreach ($mm as $m=>$vals) { foreach ($vals as $kk=>$vv) { $res['period'][$y][$m][$kk] += $vv; //$res['money_period'][$y][$m][$kk] += $vv*$per_hour; } $res['money_period'][$y][$m]['hours'] += $vals['hours']*$per_hour; $res['money_period'][$y][$m]['over1'] += $vals['over1']*$per_hour1; $res['money_period'][$y][$m]['over2'] += $vals['over2']*$per_hour2; $res['money_period'][$y][$m]['over'] += ( $res['money_period'][$y][$m]['over1'] + $res['money_period'][$y][$m]['over2']); $res['money_period'][$y][$m]['total'] += ( $res['money_period'][$y][$m]['hours'] + $res['money_period'][$y][$m]['over']); } } } else { $res[$k] += $v; } } $res['money_hours'] += $per_hour*$info['hours']; $res['money_over1'] += $per_hour1*$info['over1']; $res['money_over2'] += $per_hour2*$info['over2']; //if( $per_hour) $perDurArray[$emp_id.':'.$year.':'.$m] = $per_hour; } $res['money_over'] = ($res['money_over1'] + $res['money_over2']); $res['money'] = ($res['money_hours'] + $res['money_over']); $res['xx'][] = [$res['money_hours'],$res['money_over'],$res['money'] ,$res['hours']]; return self::$CACHE_TIMES_WITH_FOT[$key] = $res; } static $CACHE_ABSENCES; static function getAllAbsences(){ if(isset(self::$CACHE_ABSENCES)){ return self::$CACHE_ABSENCES;}; $absences = []; $r = Absence::getAll([ /* \Query::WHERE=>new \where(\Where::_and([ \Where::_operator(Absence::$EMP,'=',$emp_id), ])) */ ]); while($l = \DB::fetch($r)){ $absences[$l[Absence::$EMP]][] = $l[Absence::$DATE]; } return self::$CACHE_ABSENCES = $absences; } static function getEmpsTime($begin,$end,$_emp_id,$_project_id){ if(!$end) $end = $begin; // Merakomis::addLog("getEmpsTime:$key $_emp_id $_project_id"); $absences = self::getAllAbsences(); /* $r = Absence::getAll([ ]); while($l = \DB::fetch($r)){ $absences[$l[Absence::$EMP]][] = $l[Absence::$DATE]; } */ $res = []; $periods = self::getPeriodWithDays($begin,$end); foreach ($periods as $p) { $beginDate = $p[0]; $endDate = $p[1]; $beginTime = strtotime($beginDate); $year = date('Y', $beginTime); $month = date('m', $beginTime); $cache= Cache::getData($beginDate,$endDate,$_emp_id,$_project_id); if($cache && !$cache['empty']) { foreach ($cache as $k=>$v){ $res[$k] += $v; $res['period'][$year][$month][$k] += $v; } } else { $periodRes = []; $emp_and = [ \Where::_between(self::$DATE, $beginDate, $endDate), \Where::_operator(Time::$EMP, '=', $_emp_id), $_project_id ? \Where::_operator(Time::$PROJECT, '=', $_project_id) : null ]; $tr = Time::select($q = [ \Query::TABLES => [Time::$table_name], \Query::SELECT => [ //'SUM('.Time::$DURATION.') as cc', Time::$DURATION . ' as cc', Time::$IS_OVER, Time::$DATE, //Time::$EMP, //Time::$PROJECT, ], \Query::WHERE => new \Where(\Where::_and($emp_and)), /* \Query::GROUP_BY => [ Time::$IS_OVER, Time::$DATE, ], */ ]); Merakomis::addLog((string)new \Query($q)); // Merakomis::addLog(je($absences)); while ($l = \DB::fetch($tr)) { $emp_id = $l[Time::$EMP]; $project_id = $l[Time::$PROJECT]; $hours = 0; $over = 0; $over1 = 0; $over2 = 0; if ($l[Time::$IS_OVER]) { $cc = cfloatval($l['cc']); $over = $cc; if (Day::isNoWorkDay($l[Time::$DATE]) || in_array($l[Time::$DATE], $absences[$emp_id] ?? [])) { $over2 = $cc; } else { $over1 = $cc; } } else { $hours = cfloatval($l['cc']); } $periodRes['hours'] += $hours; $periodRes['over'] += $over; $periodRes['over1'] += $over1; $periodRes['over2'] += $over2; $periodRes['total'] += ($hours + $over); /* self::$CACHE[$key][$emp_id][0]['hours'] += $hours; self::$CACHE[$key][$emp_id][0]['over'] += $over; self::$CACHE[$key][$emp_id][0]['over1'] += $over1; self::$CACHE[$key][$emp_id][0]['over2'] += $over2; self::$CACHE[$key][$emp_id][0]['total'] += ($hours+$over); self::$CACHE[$key][$emp_id][$project_id]['hours'] += $hours; self::$CACHE[$key][$emp_id][$project_id]['over'] += $over; self::$CACHE[$key][$emp_id][$project_id]['over1'] += $over1; self::$CACHE[$key][$emp_id][$project_id]['over2'] += $over2; self::$CACHE[$key][$emp_id][$project_id]['total'] += ($hours+$over); */ } foreach ($periodRes as $k=>$v){ $res[$k] += $v; $res['period'][$year][$month][$k] += $v; } $x = Cache::add($beginDate, $endDate, $_emp_id, $_project_id, $periodRes); } } return $res; Merakomis::addLog(je(self::$CACHE)); return self::$CACHE[$key][$_emp_id][$_project_id]; return [ 'hours'=>$hours, 'over' =>$over, 'over1'=>$over1, 'over2'=>$over2, 'total'=>$hours+$over, //'q'=>(string)new \Query($q), ]; } static function getEmpTime($begin,$end,$emp_id,$project_id){ return self::getEmpsTime($begin,$end,$emp_id,$project_id); $absences = []; $r = Absence::select([ \Query::WHERE=>new \where(\Where::_and([ \Where::_operator(Absence::$EMP,'=',$emp_id), ])) ]); while($l = \DB::fetch($r)){ $absences[] = $l[Absence::$DATE]; } $emp_and = $time_and; $emp_and[] = \Where::_operator(Time::$EMP,'=',$emp_id); if($project_id) $emp_and[] = \Where::_operator(Time::$PROJECT,'=',$project_id); $tr = Time::select($q =[ \Query::TABLES => [Time::$table_name], \Query::SELECT => [ //'SUM('.Time::$DURATION.') as cc', Time::$DURATION.' as cc', Time::$IS_OVER, Time::$DATE, ], \Query::WHERE => new \Where(\Where::_and($emp_and)), /* \Query::GROUP_BY => [ Time::$IS_OVER, Time::$DATE, ], */ ]); // Merakomis::addLog((string)new \Query($q)); $hours = 0; $over = 0; $over1 = 0; $over2 = 0; while($l = \DB::fetch($tr)){ if($l[Time::$IS_OVER]){ $cc = cfloatval($l['cc']); $over += $cc; if(Day::isNoWorkDay($l[Time::$DATE]) || in_array($l[Time::$DATE],$absences)){ $over2 += $cc; } else { $over1 += $cc; } } else { $hours += cfloatval($l['cc']); } } return [ 'hours'=>$hours, 'over' =>$over, 'over1'=>$over1, 'over2'=>$over2, 'total'=>$hours+$over, //'q'=>(string)new \Query($q), ]; } static function getProjectStat($project_and,$and,$time_and,&$absence_and,$emp_id) { $emp_data = Emp::getByID( $emp_id ); $res = [ 'data'=>[], 'emp'=>Emp::getName( $emp_data ), 'hours'=>0, 'over'=>0, 'total'=>0, 'project_graph'=>[], 'time_graph'=>[], 'absence_graph'=>[], 'code_title'=>'', 'absence'=>[], ]; if(!Rules::isReadAnalysisTableEmp($emp_id)){ $res['decline'] = true; return $res; } $absence_and[] = \Where::_operator(Absence::$EMP,'=',$emp_id); //$and[] = \Where::_operator(Time::$EMP,'=',$emp_id); $and[] = \Where::_operator(Member::$EMP,'=',$emp_id); $and[] = \Where::_operatorForce(Project::$TEAM,'=',Member::$TEAM); if($project_and){ $and = array_merge($and,$project_and); } if($time_and){ //$and = array_merge($and,$time_and); } /* $r = Time::select($q = [ \Query::LEFT_JOINS => [ [Project::$table_name,Project::$ID,self::$PROJECT], [Member::$table_name,Member::$EMP,Time::$EMP], [Section::$table_name,Section::$ID,Member::$SECTION], ], \Query::SELECT => [ 'SUM('.self::$DURATION.') as cc', Project::$NAME.' as name', Project::$NAME, Project::$STEP, Project::$CODE, Project::$NAME, Project::$STATUS.' as status', Project::$TEAM.' as team', Project::$ID.' as id', Project::$ARCHIVE.' as archive', Time::$IS_OVER.' as is_over', Section::$NAME.' as section', Member::$ROLE.' as role_id', Member::$ACTIVE.' as active', ], \Query::WHERE => $and ? new \Where(\Where::_and($and)) : null, \Query::GROUP_BY => [self::$PROJECT,Time::$IS_OVER], \Query::SORT=>[ Project::$CODE => 'ASC', ] ]); */ $r = Project::select($q = [ \Query::TABLES => [Project::$table_name], \Query::LEFT_JOINS => [ //[Project::$table_name,Project::$ID,self::$PROJECT], [Member::$table_name,Member::$TEAM,Project::$TEAM], [Section::$table_name,Section::$ID,Member::$SECTION], ], \Query::SELECT => [ // 'SUM('.self::$DURATION.') as cc', Project::$NAME.' as name', Project::$NAME, Project::$STEP, Project::$CODE, Project::$NAME, Project::$STATUS.' as status', Project::$TEAM.' as team', Project::$ID.' as id', Project::$ARCHIVE.' as archive', // Time::$IS_OVER.' as is_over', Section::$NAME.' as section', Member::$ROLE.' as role_id', Member::$ACTIVE.' as active', ],/* \Query::WHERE => new \Where(\Where::_and([ \Where::_operator(Member::$EMP,'=',1), \Where::_operatorForce(Project::$TEAM,'=',Member::$TEAM) ])),*/ \Query::WHERE => new \Where(\Where::_and($and)), // \Query::GROUP_BY => [self::$PROJECT], ]); $res['q'] = (string)new \Query($q); $total_hours = 0; $pids = []; while($l = \DB::fetch($r)){ $res['aaa'][]= $l; $l['role'] = Member\structure\eMemberRole::getName($l['role_id']); $l['code'] = $l[Project::$CODE]; $l['code_name'] = Project::getCodeName($l); $l['code_step'] = Project::getCode($l); $l[$l['is_over']?'over':'hours'] = number_format($l['cc'],2,".",""); $l['status'] = eStatus::getName($l['status']); $id = $l['id']; if($res['data'][$id]) $l+=$res['data'][$id]; $res['data'][$id] = $l; $pids[] = $id; } if($pids) { $time_and[] = \Where::_operator(Time::$EMP,'=',$emp_id); $time_and[] = \Where::_in(Time::$PROJECT,$pids); $r = Time::select([ \Query::SELECT => [ 'SUM('.Time::$DURATION.') as cc', Time::$IS_OVER.' as is_over', Time::$PROJECT, ], \Query::WHERE => new \Where(\Where::_and($time_and)), \Query::GROUP_BY =>[Time::$PROJECT,Time::$IS_OVER], ]); while($l = \DB::fetch($r)){ $l['cc'] = cfloatval($l['cc']); $pid = $l[Time::$PROJECT]; $res['data'][$pid][$l['is_over']?'over':'hours'] = number_format($l['cc'],2,".",""); $res['data'][$pid]['cc'] = $l['cc']; $total_hours += $l['cc']; } } $res['data'] = array_values($res['data']); foreach ($res['data'] as $k=>$v){ $res['data'][$k]['over'] = cfloatval($res['data'][$k]['over']); $res['data'][$k]['hours'] = cfloatval($res['data'][$k]['hours']); $res['data'][$k]['total'] = $res['data'][$k]['over'] + $res['data'][$k]['hours']; $res['over'] +=$res['data'][$k]['over']; $res['hours']+=$res['data'][$k]['hours']; $res['total']+=$res['data'][$k]['total']; $res['project_graph'][$k]['title'] = $v['code_name']; $res['project_graph'][$k]['value'] = $total_hours ? round($res['data'][$k]['total']/$total_hours*100) : 0; } $res['time_graph'][] = ['title'=>'Рабочие','value'=>$res['hours'],'class'=>Merakomis::getGraphClasses()[0]]; $res['time_graph'][] = ['title'=>'Сверхурочные','value'=>$res['over'],'class'=>Merakomis::getGraphClasses()[1]]; Merakomis::graphClass($res['project_graph'],true,true,true); $r = Absence::select($q = [ \Query::SELECT => [ 'COUNT(*) as cc', DAbsence::$CODE, DAbsence::$NAME, Absence::$ID, Absence::$ABSENCE, ], \Query::TABLES => [Absence::$table_name], \Query::LEFT_JOINS => [ [Emp::$table_name,Emp::$ID,Absence::$EMP], [DAbsence::$table_name,Absence::$ABSENCE,DAbsence::$ID], ], \Query::WHERE => new \Where(\Where::_and($absence_and)), \Query::GROUP_BY => [ Absence::$ABSENCE, ], ]); $res['absence_q'] = (string)new \Query($q); $res['absence'] = []; $res['absence_total'] = 0; while($l = \DB::fetch($r)){ $res['absence_total'] += $count = intval($l['cc']); $res['absence'][] = [ 'code'=>$l[DAbsence::$CODE], 'title'=>$l[DAbsence::$NAME], 'count'=>$count, 'id'=>$l[Absence::$ID], 'id2'=>$l[Absence::$ABSENCE], ]; } foreach ($res['absence'] as $v){ $res['absence_graph'][] = [ 'title'=>$v['code'], // 'value'=> $res['absence_total'] ? round( $v['count'] / $res['absence_total'] * 100) : 0 'value'=> $v['count'] ]; } Merakomis::graphClass($res['absence_graph']); return $res; } static function getDepartmentEmpsfunction($pid,$structure,&$res,$dep_begin,$dep_end,$only_emp_ids = []){ foreach ($structure[$pid] as $did) { $emp_ids = $only_emp_ids ? array_intersect($structure['base'][$did]['emp_ids'],$only_emp_ids) : $structure['base'][$did]['emp_ids']; $res['dids'][$did]['emp_ids'] = $emp_ids; //$res['dids'][$did]['title'] = $structure['base'][$did]['title']; $path = Department::getPath($did); $title = []; foreach ($path as $did_path ){ $title[] = $structure['base'][$did_path]['title']; } $res['dids'][$did]['title'] = implode(" → ",$title); if($emp_ids){ $r = Time::select([ \Query::SELECT => [ 'SUM('.Time::$DURATION.') as cc', Time::$IS_OVER, Time::$EMP, ], \Query::WHERE => new \Where(\Where::_and([ \Where::_in(Time::$EMP,$emp_ids), \Where::_between(Time::$DATE,$dep_begin,$dep_end) ])), \Query::GROUP_BY=> [ Time::$EMP,Time::$IS_OVER, ], ]); while($l = \DB::fetch($r)){ $dur = cfloatval($l['cc']); $isOver = boolval($l[Time::$IS_OVER]); $emp_id = $l[Time::$EMP]; $res['dids'][$did]['hours'] += $isOver ? 0 : $dur; $res['dids'][$did]['over'] += $isOver ? $dur : 0; $res['dids'][$did]['total'] += $dur; $res['dids'][$did]['emps'][$emp_id]['total'] += $dur; } } if($structure[$did]) { self::getDepartmentEmpsfunction($did,$structure,$res,$dep_begin,$dep_end,$only_emp_ids); $res['dids'][$did]['child'] = $structure[$did]; foreach ($structure[$did] as $did2) { $res['dids'][$did]['hours'] += $res['dids'][$did2]['hours']; $res['dids'][$did]['over'] += $res['dids'][$did2]['over']; $res['dids'][$did]['total'] += $res['dids'][$did2]['total']; $res['dids'][$did]['emp_ids'] = array_merge( $res['dids'][$did]['emp_ids'] , $res['dids'][$did2]['emp_ids']); $res['dids'][$did]['emp_ids'] = array_unique($res['dids'][$did]['emp_ids']); $res['dids'][$did]['emp_active'] = array_merge( $res['dids'][$did]['emp_active'] , $res['dids'][$did2]['emp_active']); $res['dids'][$did]['emp_active'] = array_unique($res['dids'][$did]['emp_active']); if($res['dids'][$did]['emps'] && $res['dids'][$did2]['emps']) { $res['dids'][$did]['emps'] += $res['dids'][$did2]['emps']; } else if($res['dids'][$did2]['emps']){ $res['dids'][$did]['emps'] = $res['dids'][$did2]['emps']; } } } } } static function convertMoney($x,$options = []){ //return number_format($x ,isset($options['round'])?$options['round']:1,".",""); return number_format($x / 1000000,isset($options['round'])?$options['round']:3,".",""); } static function getProjectYearStat($year) { $time = []; $money = []; $begin = date($year.'-01-01'); $end = date($year.'-12-31'); $graph1 = []; $graph2 = []; $perDurArray = []; $pids = []; $isNeedPids = true; if(Rules::isAdmin() || Rules::isGroupProjectViewer()){ $isNeedPids = false; } else { $projects = Project::getListForAnalysis(); foreach ($projects as $pid=>$project){ $pids[] = $pid; } } $isAdmin = Rules::isAdmin(); //$isAdmin = true; $myMoneyProjectIds = []; if(!$isAdmin){ $myMoneyProjectIds = Project::getListForMoney(); } $r = Project::select($q = [ \Query::TABLES => [Project::$table_name], /* \Query::LEFT_JOINS => [ [Time::$table_name,[ Time::$PROJECT=>Project::$ID, \Where::_between(Time::$DATE,$begin,$end) ]], ], */ \Query::SELECT => [ //'SUM('.Time::$DURATION.') as cc', // 'MONTH('.Time::$DATE.') as mm', Project::$ID, Project::$NAME, Project::$CODE, Project::$STEP, Project::$STATUS, Project::$DIRECTOR, Project::$ARCHIVE, ], \Query::WHERE => $PROJECT_WHERE = new \Where(\Where::_and([ \Where::_or([ \Where::_operator(Project::$DATE,"<=",$end), \Where::_operatorForce(Project::$DATE," is ",'null'), ]), \Where::_or([ \Where::_operator(Project::$ARCHIVE_DATE,">=",$begin), \Where::_operatorForce(Project::$ARCHIVE_DATE," is ",'null'), ]), $isNeedPids ? \Where::_in(Project::$ID,$pids) : null, //\Where::_between(Time::$DATE,$begin,$end) ]), ), // \Query::GROUP_BY => [ 'mm',Time::$PROJECT ], ]); $qq = (string)new \Query($q); $pids = []; while($l = \DB::fetch($r)) { $pid = $l[Project::$ID]; $project = [ 'id' => $pid, 'name' => Project::getName($l), 'archive' => boolval($l[Project::$ARCHIVE]), 'code' => $l[Project::$CODE], 'code_name' => Project::getCodeName($l), 'step' => (($c = intval($l[Project::$STEP])) ? Step::getName(Step::getByID($c)) : ''), 'director' => $l[Project::$DIRECTOR], 'director_name' => (($c = intval($l[Project::$DIRECTOR])) ? Emp::SurnameIO(Emp::getByID($c)) : ''), ]; $time['project'][$pid]['time'] = []; $time['project'][$pid]['data'] = $project; $time['project'][$pid]['total'] = 0; $time['project'][$pid]['max'] = 0; $money['project'][$pid]['time'] = []; $money['project'][$pid]['data'] = $project; $money['project'][$pid]['total'] = 0; $money['project'][$pid]['max'] = 0; $pids[] = $pid; if(!$isAdmin && !in_array($pid,$myMoneyProjectIds)){ $money['project'][$pid]['no_money'] = true; } } $isSubEmps = Rules::isAnalysysYearBySubEmps(); $subemps = null; if($isSubEmps){ $subemps = Rules::getSubEmps(); } $r = Project::select($q = [ \Query::TABLES => [Project::$table_name], \Query::LEFT_JOINS => [ [Time::$table_name,[ Time::$PROJECT=>Project::$ID, \Where::_between(Time::$DATE,$begin,$end) ]], ], \Query::SELECT => [ 'SUM('.Time::$DURATION.') as cc', 'MONTH('.Time::$DATE.') as mm', Time::$EMP, Project::$ID, ], \Query::WHERE => new \Where(\Where::_and([ \Where::_in(Project::$ID,$pids), \Where::_between(Time::$DATE,$begin,$end), // $subemps===null ? null : \Where::_in(Time::$EMP,$subemps), ]), ), \Query::GROUP_BY => [ 'mm', Time::$PROJECT, Time::$EMP, ], ]); $xxx = []; while($l = \DB::fetch($r)) { $pid = $l[Project::$ID]; $m = $l['mm']; $dur = $l['cc']; $emp_id = $l[Time::$EMP]; if($isSubEmps) { $isMeDirector = Rules::isMeDirector($pid); if(!$isMeDirector){ if(!in_array($emp_id,$subemps)){ continue; } } } $time['project'][$pid]['time'][$m]['value'] += $dur; $time['project'][$pid]['total'] += $dur; //$time['project'][$pid]['max'] = max($time['project'][$pid]['max'],$dur); $time['total'] += $dur; $time['max'] = max($time['max'],$time['project'][$pid]['total']); $time['month'][$m]['value'] += $dur; $time['month_max'] = max($time['month_max'],$time['month'][$m]['value']); $fot = Fot::getForEmp($emp_id, $year, $m); //$per_dur = $dur * self::$PER_HOUR; $per_hour = $fot ? cfloatval($fot[Fot::$PER_HOUR]) : 0; $per_dur = $dur * $per_hour; $beginMonth = date($year.'-'.$m.'-01'); $endMonth = date($year.'-'.$m.'-'.date('t',strtotime($beginMonth))); $info = self::getEmpsTimeWithFot($beginMonth,$endMonth,$emp_id,$pid); $per_dur = $info['money']; if( $per_hour) $perDurArray[$emp_id.':'.$year.':'.$m] = $per_hour; if($money['project'][$pid]['no_money']){ $per_dur = 0; } $money['project'][$pid]['time'][$m]['value'] += $per_dur; $money['project'][$pid]['total'] += $per_dur; //$money['project'][$pid]['max'] = max($money['project'][$pid]['max'],$per_dur); $money['total'] += $per_dur; $money['max'] = max($money['max'],$money['project'][$pid]['total']); $money['month'][$m]['value'] += $per_dur; $money['month_max'] = max($money['month_max'],$money['month'][$m]['value']); } foreach ($time['project'] as $pid=>&$v){ foreach ($v['time'] as $m=>$vv) { $v['max'] = max($v['max'],$vv['value']); } } unset($v); foreach ($money['project'] as $pid=>&$v){ foreach ($v['time'] as $m=>$vv) { $v['max'] = max($v['max'],$vv['value']); } } unset($v); $convertTime = function($x){ return number_format($x,1,".",""); }; $convertPerc = function($x,$max){ $max = cfloatval($max); return number_format(($max ? $x/$max:0)*100,2); }; foreach ($time['project'] as $pid=>$project){ $total = $project['total']; $max = cfloatval($project['max']); foreach ($project['time'] as $m=>$v){ $time['project'][$pid]['time'][$m]['percent'] = $convertPerc($v['value'],$max); $time['project'][$pid]['time'][$m]['value'] = $convertTime($v['value']); } $time['project'][$pid]['percent'] = $convertPerc($total,$time['max']); $graph1[] = [ 'value'=>round(($time['total'] ? $total / $time['total'] : 0) * 100), 'title'=>$project['data']['code_name'], ]; } foreach ($time['month'] as $m=>$v){ $time['month'][$m]['percent'] = $convertPerc($v['value'],$time['month_max']); $graph2[] = [ 'value'=>round(($time['total'] ? $v['value'] / $time['total'] : 0) * 100), 'title'=>Merakomis::getMonth($m), ]; } //-- Расчёт денег foreach ($money['project'] as $pid=>$project){ $total = $project['total']; $max = cfloatval($project['max']); foreach ($project['time'] as $m=>$v){ $money['project'][$pid]['time'][$m]['percent'] = $convertPerc($v['value'],$max); $money['project'][$pid]['time'][$m]['value'] = self::convertMoney($v['value'],['round'=>3]); } $money['project'][$pid]['total'] = self::convertMoney($project['total'],['round'=>3]); $money['project'][$pid]['percent'] = $convertPerc($total,$money['max']); } foreach ($money['month'] as $m=>$v){ $max = cfloatval($money['month_max']); $money['month'][$m]['percent'] = $convertPerc($v['value'],$max); } $money['total'] = self::convertMoney($money['total'],['round'=>3]); foreach ($money['month'] as $k=>$v){ $money['month'][$k]['value'] = self::convertMoney($v['value'],['round'=>3]); } $totals = [ 'title'=>'Время, ч.', 'titles'=>[], 'labels'=>[ 'Янв','Фев','Мар','Апр','Май','Июн','Июл','Авг','Сен','Окт','Ноя','Дек', ], 'datasets'=>[ ] ]; $totals2 = [ 'title'=>'Бюджет, млн. '.Merakomis::CURRENCY, 'titles'=>[], 'labels'=>[ 'Янв','Фев','Мар','Апр','Май','Июн','Июл','Авг','Сен','Окт','Ноя','Дек', ], 'datasets'=>[ ] ]; $counter = 0; $moneyProjectIds = array_intersect($pids,$myMoneyProjectIds); for($y=$year-2;$y<=$year;$y++){ $beginYear = date($y.'-01-01'); $endYear = date($y.'-12-31'); $totals['titles'][] = $y; $totals2['titles'][] = $y; $totals['datasets'][$y] = [ 'borderColor'=>Merakomis::getChartColor($counter), ]; $totals2['datasets'][$y] = [ 'borderColor'=>Merakomis::getChartColor($counter++), ]; for($i=1;$i<=12;$i++){ $totals['datasets'][$y]['data'][$i] = 0; $totals2['datasets'][$y]['data'][$i] = 0; } $r = Project::select($q = [ \Query::TABLES => [Project::$table_name], \Query::LEFT_JOINS => [ [Time::$table_name,[ Time::$PROJECT=>Project::$ID, \Where::_between(Time::$DATE,$beginYear,$endYear) ]], ], \Query::SELECT => [ 'SUM('.Time::$DURATION.') as cc', 'MONTH('.Time::$DATE.') as mm', Time::$EMP, Project::$ID, ], \Query::WHERE => new \Where(\Where::_and([ //\Where::_in(Project::$ID,$pids), \Where::_between(Time::$DATE,$beginYear,$endYear), \Where::_and([ \Where::_or([ \Where::_operator(Project::$DATE,"<=",$endYear), \Where::_operatorForce(Project::$DATE," is ",'null'), ]), \Where::_or([ \Where::_operator(Project::$ARCHIVE_DATE,">=",$beginYear), \Where::_operatorForce(Project::$ARCHIVE_DATE," is ",'null'), ]), //\Where::_between(Time::$DATE,$begin,$end) ]), //$isAdmin ? null : \Where::_in(Project::$ID,array_intersect($pids,$myMoneyProjectIds)), //$isAdmin ? null : \Where::_in(Project::$ID,$myMoneyProjectIds), ]),), \Query::GROUP_BY => [ 'mm',Time::$EMP,Project::$ID ], ]); $totals[$y]['q'] = (string)new \Query($q); while($l = \DB::fetch($r)) { $dur = cfloatval($l['cc']); $m = $l['mm']; //$fot = Fot::getForEmp($l[Time::$EMP], $y, $l['mm']); //$per_dur = $dur * cfloatval($fot[Fot::$PER_HOUR]); $emp_id = $l[Time::$EMP]; $beginMonth = date($y.'-'.$m.'-01'); $endMonth = date($y.'-'.$m.'-'.date('t',strtotime($beginMonth))); $pid = $l[Project::$ID]; $info = self::getEmpsTimeWithFot($beginMonth,$endMonth,$l[Time::$EMP],$pid); $per_dur = $info['money']; if(!$isAdmin) { $isMeDirector = Rules::isMeDirector($pid); if($isSubEmps) { if(!$isMeDirector){ if(!in_array($emp_id,$subemps)){ continue; } } } else { if(!Rules::isGroupProjectViewer()){ if(!in_array($pid,$pids)) continue; } } if(!in_array($pid,$moneyProjectIds)) $per_dur = 0; } $totals['datasets'][$y]['data'][$l['mm']] += $dur; $totals2['datasets'][$y]['data'][$l['mm']] += $per_dur; } } $totals['datasets'] = array_values($totals['datasets']); $totals2['datasets'] = array_values($totals2['datasets']); foreach ($totals['datasets'] as &$v){ $v['data'] = array_values($v['data']); } unset($v); foreach ($totals2['datasets'] as &$v){ foreach ($v['data'] as &$vv){ $vv = self::convertMoney($vv); } $v['data'] = array_values($v['data']); } unset($v); $work_hours = Day::getWorkHours($begin,$end); Merakomis::graphClass($graph1,true,true,true); //Merakomis::graphClass($graph2,true,true,true); Merakomis::graphClass($graph2,false,false,true); $perDurArrayAvg = $perDurArray ? array_sum($perDurArray) / count($perDurArray) : 0; $perHour = Merakomis::fprice($perDurArrayAvg).'/ч.'; if(!Rules::isAnalysisProjectsShowMoney()){ $perHour = '- '.Merakomis::CURRENCY.'/ч.'; } $res = [ 'qq' => $qq, 'year' => $year, 'time' => $time, 'money' => $money, 'graph1' => $graph1, 'graph2' => $graph2, 'totals' => $totals, 'totals2' => $totals2, '$isSubEmps' => $isSubEmps, 'total' => [ 'projects'=>count($time['project']).' шт.', //'per_hour'=>self::$PER_HOUR.' '.Merakomis::CURRENCY.'/ч.', 'per_hour'=>$perHour, 'work_hours'=>$work_hours.' ч.', 'hours'=>$time['total'].' ч.', 'total'=>$money['total'].' млн. '.Merakomis::CURRENCY, ], ]; $res['$perDurArray'] = $perDurArray; $res['$xxx'] = $xxx; $res['is_money'] = Rules::isAnalysisProjectsFinance(); return $res; } static function getCompanyStat($project_and,$and,$time_and,&$absence_and,$begin,$end,$emp_and,$type) { Merakomis::addLog('getCompanyStat'); if(Rules::isAdmin() || Rules::isGroupCompany() || Rules::isGroupStaff()) { // ничего не делаем //$_POST['location'] = []; //$_POST['department'] = []; } else { $locationGroups = []; if (Rules::isAnalysisMoscow()) $locationGroups[] = eEmpGroup::OFFICE_MOSCOW; if (Rules::isAnalysisIvanovo()) $locationGroups[] = eEmpGroup::OFFICE_IVANOVO; if (Rules::isAnalysisNovosibirsk()) $locationGroups[] = eEmpGroup::OFFICE_NOVOSIBORSK; if (Rules::isAnalysisKrasnodar()) $locationGroups[] = eEmpGroup::OFFICE_KRASNODAR; if (Rules::isAnalysisSemei()) $locationGroups[] = eEmpGroup::OFFICE_SEMEI; if ($locationGroups) { $arr = City::select([ \Query::WHERE => new \Where(\Where::_in(City::$GROUP, $locationGroups)), ]); $_POST['location'] = []; foreach ($arr as $l) { $_POST['location'][] = $l[City::$ID]; } } if(Emp::isMeAnyDepartmentDirector()){ $empDids = []; $r = Post::select([ \Query::WHERE => new \Where(\WHere::_and([ \Where::_operator(Post::$EMP,'=',Emp::$AUTH_ID), \Where::_operator(Post::$IS_DIRECTOR,'=',1), ])), ]); while($l = \DB::fetch($r)){ $empDids[] = $l[Post::$DEPARTMENT]; } $_POST['department'] = $empDids; } } $isCompany = $type==7; $isDepartment = $type==2; $isOffice = (!$isCompany && !$isDepartment); $EMP_ABSENCES = Emp::getAbsencesToday(); $res = [ 'data'=>[], 'absence'=>[], 'sections'=>[], 'projects'=>0, 'emps'=>0, 'graph1'=>[], 'graph2'=>[ ['title'=>'Рабочие','value'=>0], ['title'=>'Сверхурочные','value'=>0], ], 'graph3'=>[], 'work_days' => 1, 'work_hours' => 0, 'workload'=>[], 'deps'=>[], 'depnom'=>[], 'pro_nom'=>[], 'contract'=>[], '$locationGroups'=>$locationGroups, '$empDids'=>$empDids, 'is_show_emp_3'=>Rules::isAnalysisCompanyEmp3(), ]; $emp_ids = []; $DEP_IDS = []; $depReportData = []; $depReport = []; $depReportIds = []; $struct = Department::getStructure(); foreach ($struct[0] as $dep_id){ $dep = $struct['base'][$dep_id]; if($dep[Department::$IS_COMPANY_REPORT]){ $depReportIds[] = $dep_id; $depReport[$dep_id]['data'] = [ 'id'=>$dep_id, 'name'=>$dep[Department::$NAME], 'short'=>$dep[Department::$SHORT], 'a'=>[], ]; if($struct[$dep_id]){ foreach ($struct[$dep_id] as $dep_id2){ $depReportIds[] = $dep_id2; $dep2 = $struct['base'][$dep_id2]; $depReport[$dep_id]['a'][] = [ 'id'=>$dep_id2, 'name'=>$dep2[Department::$NAME], 'short'=>$dep2[Department::$SHORT], ]; } } } } Merakomis::addLog('Department Structure'); if($isOffice){ $group_id = 0; switch ($type) { case 3: $group_id = eEmpGroup::OFFICE_MOSCOW; break; case 4: $group_id = eEmpGroup::OFFICE_IVANOVO; break; case 5: $group_id = eEmpGroup::OFFICE_NOVOSIBORSK; break; case 6: $group_id = eEmpGroup::OFFICE_KRASNODAR; break; case 10: $group_id = eEmpGroup::OFFICE_SEMEI; break; } $officeName = eEmpGroup::getCityName($group_id); if($group_id) { $r = City::select([ \Query::WHERE => \Where::_operator(City::$GROUP, '=', $group_id), ]); $citi_ids = []; while($l = \DB::fetch($r)){ $citi_ids[] = $l[City::$ID]; } if($citi_ids) { $project_and[] = \Where::_in(Emp::$CITY, $citi_ids); $r = Emp::select([ \Query::WHERE => \Where::_in(Emp::$CITY,$citi_ids), ]); while($l = \DB::fetch($r)){ $emp_ids[] = $l[Emp::$ID]; } } } } if(($_POST['department'])){ $dep_ids = []; $eids = []; $s = Department::getStructure(); foreach ($_POST['department'] as $did) { // $dep_ids = array_merge(Emp::getIdsForSubEmps($did)); $dep_ids[] = $did; $dep = $s['base'][$did]; $eids = array_merge($eids,$dep['emp_ids']); foreach ($s[$did] as $sub_id){ $dep_ids[] = $sub_id; $sub_dep = $s['base'][$sub_id]; $eids = array_merge($eids,$sub_dep['emp_ids']); foreach ($s[$sub_id] as $sub2_id){ $dep_ids[] = $sub2_id; $sub2_dep = $s['base'][$sub2_id]; $eids = array_merge($eids,$sub2_dep['emp_ids']); } } } $DEP_IDS = $dep_ids; $emp_ids = $emp_ids ? array_intersect($emp_ids,$eids) : $eids; } if($isDepartment){ $eids = []; $dep_ids = []; $s = Department::getStructure(); foreach ($s['base'] as $dep){ foreach ($dep['directors'] as $dir){ if($dir['emp']['id']==Emp::$AUTH_ID){ $eids = array_merge($eids,$dep['emp_ids']); $dep_ids[] = $dep['id']; foreach ($s[$dep['id']] as $sub_id){ $dep_ids[] = $sub_id; $sub_dep = $s['base'][$sub_id]; $eids = array_merge($eids,$sub_dep['emp_ids']); foreach ($s[$sub_id] as $sub2_id){ $dep_ids[] = $sub2_id; $sub2_dep = $s['base'][$sub2_id]; $eids = array_merge($eids,$sub2_dep['emp_ids']); } } } } } //$emp_ids = $eids; //$emp_ids = array_merge($emp_ids,$eids); $emp_ids = $emp_ids ? array_intersect($emp_ids,$eids) : $eids; $DEP_IDS= $dep_ids; /* if($eids) { $project_and[] = \Where::_in(Emp::$ID,$eids); } else { $project_and[] = \Where::_operator(Emp::$ID,'=',0); } */ } $res['post'] = $_POST; if($_POST['location']){ $location_ids = []; foreach ($_POST['location'] as $v){ $location_ids[] = intval($v); } $emps_and[] = \Where::_in(Emp::$CITY,$location_ids); $r = Emp::select([ \Query::WHERE=>new \Where(\Where::_and([ \Where::_in(Emp::$CITY,$location_ids) ])) ]); $emp_loc_ids = []; while($l = \Db::fetch($r)){ $emp_loc_ids[] = $l[Emp::$ID]; } $emp_ids = $emp_ids ? array_intersect($emp_ids,$emp_loc_ids) : $emp_loc_ids; } if($name = trim($_POST['name'])){ $project_and[] = \Where::_operator(Emp::$NAME,'LIKE','%'.$name.'%'); $emp_name_ids = []; $r = Emp::select([ \Query::WHERE => \Where::_operator(Emp::$NAME,'LIKE','%'.$name.'%') ]); while($l = \DB::fetch($r)){ $emp_name_ids[ ] = $l[Emp::$ID]; } //$emp_ids = array_intersect($emp_ids,$emp_name_ids); $emp_ids = $emp_ids ? array_intersect($emp_name_ids,$emp_ids) : $emp_name_ids; $res['$emp_name_ids'] = $emp_name_ids; } if($_POST['location'] || $_POST['department'] || $_POST['name'] || $isOffice || $isDepartment){ if(!$emp_ids) { $emp_ids = [0]; } } $emps_and = [$emp_and]; if($emp_ids){ $emps_and[]= \Where::_in(Emp::$ID,$emp_ids); } $workload = []; //$and[] = \Where::_operator(Emp::$ARCHIVE,'=',0); //$and[] = \Where::_operator(Emp::$REMOVED,'=',0); /* $r = Emp::select($q = [ \Query::TABLES => [Emp::$table_name], \Query::LEFT_JOINS => [ [Member::$table_name,Emp::$ID,Member::$EMP], [Project::$table_name,Project::$TEAM,Member::$TEAM], ], \Query::WHERE => \Where::_and($and), ]); */ $DEP_EMPS = []; /* if($_POST['department']){ foreach ($_POST['department'] as $v){ if(intval($v)>0){ $DEP_IDS[] = $v; } } } */ /* if($isDepartment){ $DEP_IDS = []; $s = Department::getStructure(); foreach ($s['base'] as $dep){ foreach ($dep['directors'] as $dir){ if($dir['emp']['id']==Emp::$AUTH_ID){! $DEP_IDS[] = $dep['id']; } } } } */ //$res['dids'] = []; // Делаем разбивку по департаментам $dep_begin = $begin ? : (self::getFirstDateForCompany() ? : date('Y-m-d')); $dep_end = $end ? : date('Y-m-d'); $dep_begin = ($dep_begin == '0000-00-00') ? date('Y-m-d') : $dep_begin; $total_work_hours = Day::getWorkHours($dep_begin,$dep_end); $res['did_info']['first'] = self::getFirstDateForCompany(); $res['did_info']['$dep_begin'] = $dep_begin; $res['did_info']['$dep_end'] = $dep_end; $res['did_info']['total_work_hours'] = $total_work_hours; $structure = Department::getStructure(); $res['ss'] = $structure; //self::getDepartmentEmpsfunction(0,$structure,$res,$dep_begin,$dep_end,$emp_ids); $EMP_DEPS = []; $EMP_DEPS_IDS = []; foreach ($structure['base'] as $k=>$v){ foreach ($v['emp_ids'] as $emp_id){ $EMP_DEPS[$emp_id][] = $v['title']; $EMP_DEPS_IDS[$emp_id][] = $k; } } $res['$EMP_DEPS'] = $EMP_DEPS; $res['$DEP_IDS'] = $DEP_IDS; $res['$EMP_DEPS_IDS'] = $EMP_DEPS_IDS; if($DEP_IDS){ foreach ($res['dids'] as $did=>$v){ if(!in_array($did,$DEP_IDS)){ unset($res['dids'][$did]); } else { $DEP_EMPS = array_merge($DEP_EMPS,$res['dids'][$did]['emp_ids']); } } } $res['$DEP_EMPS'] = $DEP_EMPS; if($DEP_EMPS){ $emps_and[] = \Where::_in(Emp::$ID,$DEP_EMPS); } uasort($res['dids'],function($x,$y){ return $x['title']<=>$y['title']; }); /* $project_and[] = \Where::_or([ \Where::_operator(Emp::$ARCHIVE,'=',0), $begin ? \Where::_operator(Emp::$ARCHIVE_DATE,'>=',$begin) : null, ]); */ Merakomis::addLog('Before Emp Select'); /* $r = Emp::select($q = [ \Query::TABLES => [Emp::$table_name], \Query::LEFT_JOINS => [ [Member::$table_name, Emp::$ID, Member::$EMP], //[Project::$table_name, Project::$TEAM, Member::$TEAM], 'LEFT JOIN '.Project::$table_name.' ON '.Project::$TEAM.'='.Member::$TEAM .($and?str_replace("WHERE"," AND ",new \Where(\Where::_and($and))):'') , [Section::$table_name, Section::$ID, Member::$SECTION], ], \Query::SELECT => [ Emp::$NAME . ' as emp', Emp::$ID . ' as emp_id', Project::$NAME, Project::$CODE . ' as code', Project::$TEAM . ' as team', Project::$STEP . ' as step', Project::$CODE , Project::$STEP , Project::$DIRECTOR , Project::$ID, Project::$ARCHIVE, Emp::$STAFFING . ' as staffing_ids', Emp::$NAME, Emp::$ID, Emp::$ARCHIVE, Emp::$DATE_HIRE, Emp::$ARCHIVE_DATE, Section::$ID , Section::$STEP , Section::$NAME , Member::$SECTION . ' as emp_section', Member::$ROLE . ' as emp_role', Member::$ID . ' as member_id', ], \Query::WHERE => $emp_and ? \Where::_and($emp_and) : null, \Query::SORT=>[Project::$CODE=>'ASC'], ]); */ //Merakomis::addLog('Before Emp Select??'); //echo new \Where(\Where::_and($emps_and)); $r = Emp::select($q = [ \Query::TABLES => [Emp::$table_name], \Query::LEFT_JOINS => [ [Member::$table_name, Emp::$ID, Member::$EMP], //[Project::$table_name, Project::$TEAM, Member::$TEAM], 'LEFT JOIN '.Project::$table_name.' ON '.Project::$TEAM.'='.Member::$TEAM .($project_and?str_replace("WHERE"," AND ",new \Where(\Where::_and($project_and))):'') , [Section::$table_name, Section::$ID, Member::$SECTION], ], \Query::SELECT => [ Emp::$NAME . ' as emp', Emp::$ID . ' as emp_id', Project::$NAME, Project::$CODE . ' as code', Project::$TEAM . ' as team', Project::$STEP . ' as step', Project::$CODE , Project::$STEP , Project::$DIRECTOR , Project::$ID, Project::$ARCHIVE, Project::$CONTRACT, Project::$CONTRACTOR, Emp::$STAFFING . ' as staffing_ids', Emp::$NAME, Emp::$ID, Emp::$ARCHIVE, Emp::$DATE_HIRE, Emp::$ARCHIVE_DATE, Section::$ID , Section::$STEP , Section::$NAME , Member::$SECTION . ' as emp_section', Member::$ROLE . ' as emp_role', Member::$ID . ' as member_id', ], \Query::WHERE => $emps_and ? new \Where(\Where::_and($emps_and)) : null, \Query::SORT=>[Project::$CODE=>'ASC'], ]); $res['q'] = (string) new \Query($q); Merakomis::addLog('Before Emp Select!!'); $total_hours = 0; $projects = []; $ids = []; //$res['dids'] = []; $contract = []; while($l = \DB::fetch($r)){ $emp_id = $l[Emp::$ID]; $pid = $l[Project::$ID]; if($pid) { $contractName = Project::getContractName($l); $contract['names'][] = $contractName; } if(!$res['data'][$emp_id]['info']) { $res['data'][$emp_id]['info'] = [ 'hours'=>0, 'over'=>0, 'over1'=>0, 'over2'=>0, 'total'=>0, ];//Time::getEmpTime($time_and,$emp_id,0); $res['data'][$emp_id]['projects'] = []; $res['data'][$emp_id]['absence'] = $EMP_ABSENCES[$emp_id][DAbsence::$NAME]; //$res['hours'] += $res['data'][$emp_id]['info']['hours']; //$res['over'] += $res['data'][$emp_id]['info']['over']; //$res['total'] += $res['data'][$emp_id]['info']['total']; $res['data'][$emp_id]['department'] = implode(", ",$EMP_DEPS[$emp_id]); $res['data'][$emp_id]['staffing'] = []; $staffing_ids = json_decode($l['staffing_ids'],true); if($staffing_ids){ $staffs = Staffing::getByIDS($staffing_ids); foreach ($staffs as $v){ $res['data'][$emp_id]['staffing'][]= Staffing::getName($v); } $res['data'][$emp_id]['staffing'] = implode(", ",$res['data'][$emp_id]['staffing']); } } $res['data'][$emp_id]['id'] = $emp_id; $res['data'][$emp_id]['name'] = $l[Emp::$NAME]; $res['data'][$emp_id]['name_short'] = Emp::SurnameIO($l); $res['data'][$emp_id]['archive'] = boolval($l[Emp::$ARCHIVE]); if($pid) { $res['data'][$emp_id]['projects'][$pid]['id'] = $pid; //$res['data'][$emp_id]['projects'][$pid]['name'] = $l[Project::$NAME]; $res['data'][$emp_id]['projects'][$pid]['archive'] = boolval($l[Project::$ARCHIVE]); $res['data'][$emp_id]['projects'][$pid]['name'] = Project::getCode($l); $res['data'][$emp_id]['projects'][$pid]['role'] = Member\structure\eMemberRole::getName($l['emp_role']); $res['data'][$emp_id]['projects'][$pid]['info'] = $info = Time::getEmpTime($begin,$end,$emp_id,$pid);; //$res['data'][$emp_id]['projects'][$pid]['info'] = $info = Time::getEmpsTime($time_and,$emp_id,$pid);; $res['data'][$emp_id]['info']['hours'] += $info['hours']; $res['data'][$emp_id]['info']['over'] += $info['over']; $res['data'][$emp_id]['info']['over1'] += $info['over1']; $res['data'][$emp_id]['info']['over2'] += $info['over2']; $res['data'][$emp_id]['info']['total'] += $info['total']; $res['hours'] += $info['hours']; $res['over'] += $info['over']; $res['total'] += $info['total']; foreach ($EMP_DEPS_IDS[$emp_id] as $did){ if(in_array($did,$depReportIds)){ $depReportData[$did]['name'] = Department::getName(Department::getByID($did)); $depReportData[$did]['emp_ids'][] = $emp_id; $depReportData[$did]['emp_ids'] = array_unique($depReportData[$did]['emp_ids']); $depReportData[$did]['hours'] += $info['hours']; $depReportData[$did]['projects'][$pid]['hours'] += $info['hours']; } } $workload[$pid]['archive'] = boolval($l[Project::$ARCHIVE]); //$workload[$pid]['code'] = Project::getCode($l); $workload[$pid]['code'] = $l[Project::$CODE]; $workload[$pid]['name'] = Project::getName($l); $workload[$pid]['step'] = $l[Project::$STEP] ? Step::getName(Step::getByID(intval($l[Project::$STEP]))) : ''; $workload[$pid]['director'] = $dir_id = intval($l[Project::$DIRECTOR]); $workload[$pid]['director_name'] = ($dir_id?Emp::SurnameIO( Emp::getByID($dir_id) ):''); $workload[$pid]['emp'][$emp_id]['value'] += $info['total']; $workload[$pid]['max'] = max($workload[$pid]['max'] ??0, $workload[$pid]['emp'][$emp_id]['value']); $contract['data'][$emp_id]['id'] = $emp_id; $contract['data'][$emp_id]['name'] = Emp::SurnameIO($l); $contract['data'][$emp_id]['archive'] = intval($l[Emp::$ARCHIVE]); $contract['data'][$emp_id]['staffing'] = $res['data'][$emp_id]['staffing']; $contract['data'][$emp_id]['department'] = $res['data'][$emp_id]['department']; $contract['data'][$emp_id]['contracts'][$contractName]['value'] += $info['hours']; $contract['data'][$emp_id]['max'] = max($contract['data'][$emp_id]['max'] ??0, $contract['data'][$emp_id]['contracts'][$contractName]['value']); $projects[$pid]['title'] = Project::getCodeName($l); $projects[$pid]['value'] += $info['total']; $total_hours += $info['total']; $res['graph2'][0]['value'] += $info['hours']; $res['graph2'][1]['value'] += $info['over']; } $ids[] = $emp_id; $project_ids[] = $l[Project::$ID]; } foreach ($depReportData as $did=>&$v){ $count = count($v['emp_ids']); $v['per_emp'] = $count ? $v['hours'] / $count : 0; foreach ($v['projects'] as &$p){ $hours = $p['hours']; //$value = $hours ? $v['per_emp'] / $hours : 0; $value = $v['per_emp'] ? $hours / $v['per_emp'] : 0; $p['per_emp'] = number_format($value,2); $v['total'] += $value; unset($p); } $v['total'] = number_format($v['total'],2); unset($v); } //$emp_ids = array_intersect($emp_ids,$ids); $emp_ids = $ids; Merakomis::addLog('After Emp Loop'); $contract['names'] = array_values(array_unique($contract['names'])); $maxContract = 0; foreach ($contract['data'] as $emp_id=>$names){ $max = $contract['data'][$emp_id]['max']; foreach ($names['contracts'] as $name=>$v) { $contract['data'][$emp_id]['contracts'][$name]['percent'] = $max ? round($v['value'] / $max * 100) : 0; $contract['data'][$emp_id]['total'] += $v['value']; $contract['total'][$name] += $v['value']; $contract['all'] += $v['value']; } $maxContract = max($maxContract,$contract['data'][$emp_id]['total'] ); } foreach ($contract['data'] as $emp_id=>$names){ $contract['data'][$emp_id]['percent'] = $maxContract ? round($names['total'] / $maxContract * 100) : 0; } $graph3 = []; if($ids) { $absence_and[] = \Where::_in(Emp::$ID, $emp_ids ? : $ids); $r = Absence::select($qq = [ \Query::SELECT => [ 'COUNT(*) as cc', DAbsence::$CODE, DAbsence::$NAME, Absence::$EMP, Absence::$ABSENCE, Emp::$NAME, Emp::$ID, Emp::$ARCHIVE, ], \Query::TABLES => [Absence::$table_name], \Query::LEFT_JOINS => [ [Emp::$table_name, Emp::$ID, Absence::$EMP], [DAbsence::$table_name, Absence::$ABSENCE, DAbsence::$ID], ], \Query::WHERE => \Where::_and($absence_and), \Query::GROUP_BY => [ Absence::$EMP, Absence::$ABSENCE, ], ]); $res['qq'] = (string)new \Query($qq); while($l = \DB::fetch($r)){ $emp_id = $l[Emp::$ID]; $res['absence'][$emp_id]['archive'] = boolval($l[Emp::$ARCHIVE]); $res['absence'][$emp_id]['name'] = $l[Emp::$NAME]; $res['absence'][$emp_id]['id'] = $l[Emp::$ID]; $res['absence'][$emp_id]['total']+= intval($l['cc']); $res['absence'][$emp_id]['a'][] = [ 'code'=>$l[DAbsence::$CODE], 'name'=>$l[DAbsence::$NAME], 'count'=>intval($l['cc']), ]; $graph3[$l[DAbsence::$CODE]] += intval($l['cc']); } } Merakomis::addLog('After Absence Loop'); uasort($res['absence'],function($x,$y){ return $x['name']<=>$y['name']; }); $res['absence'] = array_values($res['absence']); uasort($res['data'],function($x,$y){ return $x['name']<=>$y['name']; }); $project_ids = array_unique($project_ids); $res['projects_list'] = []; if($project_ids){ $a = Project::getByIDS($project_ids); foreach ($a as $v){ $res['projects_list'][] = Project::format($v); } } Merakomis::addLog('After prjects Loop'); //$res['departments'] = [['id'=>0,'title'=>'Вся компания']] + (Department::getNameList(['zero']) ? : []); $res['departments'] = [['id'=>0,'title'=>'Вся компания']]; $a = Department::getNameList(); foreach ($a as $k=>$v){ $res['departments'][] = [ 'id'=>intval($k), 'title'=>$v, ]; } $res['locations'] = [['id'=>0,'title'=>'Все локации']]; $a = City::getNameList(); foreach ($a as $k=>$v){ $res['locations'][] = [ 'id'=>intval($k), 'title'=>$v, ]; } foreach ($res['data'] as $k=>&$e ){ //if($e['id']==46){ // echo '
';
            //    echo var_dump($e['projects']);
            //    echo '
'; //} uasort($e['projects'],function($x,$y){ return $x['name']<=>$y['name']; }); //if($e['id']==46){ // echo '
';
            //    echo var_dump($e['projects']);
            //    echo '
'; //} $e['projects'] = array_values($e['projects']); unset($e); } // Считаем показатели по департаментам $res['dids'] = []; if($emp_ids) { $s = Department::getStructure(); $r = Post::select($q = [ \Query::SELECT =>[ Post::$DEPARTMENT, Post::$EMP ], \Query::WHERE => new \Where(\Where::_and([ \Where::_in(Post::$EMP,$emp_ids), $DEP_IDS ? \Where::_in(Post::$DEPARTMENT,$DEP_IDS) : null, ])) ]); $res['qqq'] = (string)new \Query($q); while($l = \DB::fetch($r)){ $did = $l[Post::$DEPARTMENT]; $path = Department::getPath($did); $emp_id = $l[Post::$EMP]; foreach ($path as $pdid){ //$res['dids'][$pdid]['title'] = Department::getName( $s['base'][$pdid] ); $info = $res['data'][$emp_id]['info']; $res['dids'][$pdid]['hours'] += $info['hours']; $res['dids'][$pdid]['total'] += $info['total']; $res['dids'][$pdid]['over'] += $info['over']; $res['dids'][$pdid]['emp_ids'][] = $emp_id; if($info['total']){ $res['dids'][$pdid]['emp_work_ids'][] = $emp_id; } // Распределение сотрудников между реализуемыми проектами if(in_array($pdid,$depReportIds) and $res['data'][$emp_id]['projects']) { foreach ($res['data'][$emp_id]['projects'] as $pv){ $pInfo = $pv['info']; $pid = $pv['id']; $res['depnom'][$pdid]['total'] += $pInfo['total']; $res['depnom'][$pdid]['projects'][$pid]['total'] += $pInfo['total']; } } } } foreach ($res['dids'] as $did => &$v) { $path = Department::getPath($did); $v['path'] = $path;; $title = []; foreach ($path as $did_path ){ $title[] = $structure['base'][$did_path]['title']; } $v['title'] = implode(" → ",$title); $v['emp_count'] = count(array_unique($v['emp_ids'])); $v['emp_work'] = count(array_unique($v['emp_work_ids'])); //$v['emp_count'] = count($emp_ids ? array_intersect($v['emp_active'], $emp_ids) : $v['emp_active']); //$v['emp_work'] = count($emp_ids ? array_intersect(array_keys($v['emps']), $emp_ids) : $v['emps']);; $v['y'] = round($total_work_hours ? $v['hours'] / ($total_work_hours * $v['emp_count']) * 100 : 0) . '%'; $v['z'] = round($total_work_hours ? $v['total'] / ($total_work_hours * $v['emp_count']) * 100 : 0) . '%'; $depReportData[$did]['y'] = $v['y']; if($res['depnom'][$did]) { $emp_count = $v['emp_work']; $res['depnom'][$did]['id'] = $did; //$res['depnom'][$did]['count'] = $emp_count; $n_emp = $emp_count ? $res['depnom'][$did]['total'] / $emp_count : 0; //$res['depnom'][$did]['count'] = $n_emp; $res['depnom'][$did]['n_emp'] = $n_emp; foreach ($res['depnom'][$did]['projects'] as $pid => &$pv) { // $pv['time'] = $emp_count ? $pv['total'] / $emp_count : 0; $pv['id'] = $pid; $pv['percent'] = number_format($n_emp ? $pv['total'] / $n_emp : 0,2,'.',''); $res['pro_nom'][$pid][$did] = $pv['percent']; $res['depnom'][$did]['count'] += $pv['percent']; } $res['depnom'][$did]['count'] = number_format($res['depnom'][$did]['count'],2,'.',''); } } unset($v); } // Считаем количество проектов $r = Project::select([ \Query::SELECT => ['COUNT(*) as cc'], \Query::WHERE => \Where::_and([ \Where::_operator(Project::$ARCHIVE,'=',0), \Where::_operator(Project::$REMOVED,'=',0), ]) ]); $l = \DB::fetch($r); $res['projects'] = intval($l['cc']); $emps_info = []; Merakomis::addLog('After prjects Loop'); $minBegin = null; $maxEnd = null; foreach ($res['data'] as $emp_id => &$v){ $emp_id = $v['id']; $b = $begin ? : (self::getFirstDateForEmp($emp_id) ? : date('Y-m-d')); $e = $end ? : date('Y-m-d'); $b = ($b == '0000-00-00') ? date('Y-m-d') : $b; $total = Day::getWorkHours($b,$e); $minBegin = $minBegin ? min($b,$minBegin) : $b; $maxEnd = $maxEnd ? max($e,$maxEnd) : $e; if(!$emps_info[$emp_id]){ $emps_info[$emp_id] = self::getEmpTime($begin,$end,$emp_id,null); //$emps_info[$emp_id] = self::getEmpsTime($time_and,$emp_id,null); } $h = $emps_info[$emp_id]['hours']; $t = $emps_info[$emp_id]['total']; //$v['hours'] = $emps_info[$emp_id]['hours']; //$v['over'] = $emps_info[$emp_id]['over']; $v['hours'] = $v['info']['hours']; $v['over'] = $v['info']['over']; $v['over1'] = $v['info']['over1']; $v['over2'] = $v['info']['over2']; $v['y'] = round( $total ? $h / $total * 100 : 0).'%' ; $v['z'] = round( $total ? $t / $total * 100 : 0).'%' ; } unset($emps); unset($v); Merakomis::addLog('After Emp Format Loop'); foreach ($projects as &$v){ $v['value'] = round( number_format( $total_hours ? $v['value'] / $total_hours * 100: 0,2,'.',' ') ); } unset($v); $res['graph1'] = array_values($projects); foreach ($graph3 as $k=>$v){ $res['graph3'][] = ['title'=>$k,'value'=>$v]; } Merakomis::graphClass($res['graph1'],true,true,true); Merakomis::graphClass($res['graph2'],false); Merakomis::graphClass($res['graph3']); $res['work_days'] = $minBegin && $maxEnd ? Day::getWorkDays($minBegin,$maxEnd) : 0; $res['work_hours'] = $minBegin && $maxEnd ? Day::getWorkHours($minBegin,$maxEnd) : 0; //$workload[$pid]['emp'][$emp_id]['value'] foreach ($workload as $pid=>$projects){ $max = $workload[$pid]['max']; foreach ($projects['emp'] as $emp_id=>$emp){ $workload[$pid]['emp'][$emp_id]['percent'] = ($max ? $emp['value']/$max : 0) * 100; } } $res['workload'] = $workload; $res['data'] = array_values($res['data']); $res['dids'] = array_values($res['dids']); //$res['q'] = (string)new \Query($q); //$res['r'] = \Db::numRows($r); $res['subtitle'] = 'Моя компания'; $res['$emp_ids'] = $emp_ids; /* if($emp_ids){ $x = []; foreach ($res['data'] as $v){ if(in_array($v['id'],$emp_ids)) { $x[] = $v; } } $res['data'] = $x; foreach ($res['dids'] as $k=>$v){ if(!array_intersect($emp_ids,$v['emp_ids'])){ unset($res['dids'][$k]); } } $res['dids'] = array_values($res['dids']); } */ $res['stat_subtitle'] = $did ? Department::getName(Department::getByID(intval($did))) : 'Моя компания'; if($did){ $dep = Department::getByID($did); $res['subtitle'] = Department::getName($dep); } $res['director_name'] = ''; if($_POST['name']){ $res['director_name'] = ', '.$_POST['name']; } $res['location_names'] = $isOffice?$officeName:'все локации'; if($_POST['location']) { $names = []; foreach ($_POST['location'] as $loc_id){ $names[] = City::getName( City::getByID( intval($loc_id) ) ); } $res['location_names'] = implode(", ",$names); } $res['department_names'] = $isDepartment?'Моё подразделение':'Вся компания'; if($_POST['department']) { $s = Department::getStructure(); $names = []; foreach ($_POST['department'] as $did){ $names[] = Department::getName($s['base'][$did]); } $res['department_names'] = implode(", ",$names); } $res['depReportData'] = $depReportData; $res['contract'] = $contract; $depReport = array_values($depReport); $res['depReport'] = $depReport; $depIds = []; foreach ($_POST['department'] as $v){ $depIds[] = intval($v); } $locIds = []; foreach ($_POST['location'] as $v){ $locIds[] = intval($v); } $res['company_rules'] = [ 'departments'=>$depIds, 'departmentsDisabled'=>count($depIds)>0, 'locations'=>$locIds, 'locationsDisabled'=>count($locIds)>0, ]; return $res; } static $cache_first_date = []; static function getFirstDateForCompany(){ // На созвне было принято считать дату старта от 1 января 2023 года return '2023-01-01'; if(isset(self::$cache_first_date[0])) return self::$cache_first_date[0]; $r = self::select($q = [ \Query::TABLES => [Time::$table_name], \Query::SELECT => ['MIN('.self::$DATE.') as cc'], \Query::WHERE => \Where::_operator(self::$DATE,'<>','0000-00-00'), \Query::COUNT=>1, ]); $l = \DB::fetch($r); $res = $l['cc']; return self::$cache_first_date[0] = $res; } static function getFirstDateForEmp($emp_id){ // На созвне было принято считать дату старта от 1 января 2023 года return '2023-01-01'; if(isset(self::$cache_first_date[$emp_id])) return self::$cache_first_date[$emp_id]; $emp_id = intval($emp_id); $r = self::select([ \Query::SELECT => ['MIN('.self::$DATE.') as cc'], \Query::WHERE => new \Where(\Where::_and([ \Where::_operator(self::$EMP,'=',$emp_id), ])), \Query::COUNT=>1, ]); $l = \DB::fetch($r); $res = $l['cc']; return self::$cache_first_date[$emp_id] = $res; } static function getTeamStat($project_and,$and,$time_and,&$absence_and,$begin,$end,$project_and_all) { $PROJECT_ID = intval($_POST['subtype']); $res = [ 'begin_end'=>$begin.' - '.$end, 'data'=>[], 'hours'=>0, 'over'=>0, 'total'=>0, 'section'=>[], 'sections'=>[], 'projects2'=>[], 'parents'=>[], 'graph1'=>[], 'graph2'=>[], 'total_r'=>0, 'total_o'=>0, 'directors'=>[['id'=>0,'title'=>'Все РП']], 'sections_total'=>[], 'section_emp_total'=>[], 'total_money'=>0, 'period_data' => [], 'section_data'=>[], 'section_info'=>['time'=>['max'=>0]], 'subsection_data'=>[], 'subsection_info'=>['time'=>['max'=>0]], 'avgPerHour'=>'0', 'project_count'=>0, 'totals'=>[ 'sections'=>[ 'total_emps' => 0, 'emps' => 0, 'hours' => 0, 'over1' => 0, 'over2' => 0, 'total' => 0, 'money_hours' => 0, 'money_over1' => 0, 'money_over2' => 0, 'money_total' => 0, ], 'subsections'=>[], ], 'sub'=>[], 'rules'=>[ 'money' => Rules::isAnalysisProjectsFinance($PROJECT_ID), 'project' => Rules::isAnalysisProjectsProject($PROJECT_ID), 'section' => Rules::isAnalysisProjectsSection($PROJECT_ID), 'subsection' => Rules::isAnalysisProjectsSubsection($PROJECT_ID), 'team' => Rules::isAnalysisProjectsTeam($PROJECT_ID), 'showMoney' => Rules::isAnalysisProjectsShowMoney($PROJECT_ID), ] ]; $isGip = Rules::isGipInProject($PROJECT_ID); $isDirector = Rules::isMeDirector($PROJECT_ID); $isGroupViewer = Rules::isGroupProjectViewer(); $isOnlyAr = false; $isOnlyKr = false; $isMainEngineer = false; $isDepartmentDirector = false; $REPORT_SECTIONS = ['АР', 'КР', 'ИОС', 'СПЕЦ', 'BIM-IT', 'УПР']; $subEmps = []; if($isDirector || $isGip || $isGroupViewer) { } else { $isOnlyAr = Rules::isGapInProject($PROJECT_ID); $isOnlyKr = Rules::isGkpInProject($PROJECT_ID); $isMainEngineer = Rules::isMainEngineerInProject($PROJECT_ID); $isDepartmentDirector = Rules::isDepartmentDirector(); if ($isOnlyAr) { $REPORT_SECTIONS = ['АР']; } else if ($isOnlyKr) { $REPORT_SECTIONS = ['КР']; } else if ($isMainEngineer) { $project = Project::getByID($PROJECT_ID); $r = Member::select([ \Query::WHERE => new \Where(\Where::_and([ \Where::_operator(Member::$EMP, '=', Emp::$AUTH_ID), \Where::_operator(Member::$TEAM, '=', $project[Project::$TEAM]), ])), \Query::COUNT => 1, ]); $member = \DB::fetch($r); $section = Section::getByID($member[Member::$SECTION]); /* if($section[Section::$PARENT]) { $section = Section::getByID($section[Section::$PARENT]); } if($section[Section::$PARENT]) { $section = Section::getByID($section[Section::$PARENT]); } */ //Section::getFullName($section); $REPORT_SECTIONS = [Section::getFullName($section)]; } else if ($isDepartmentDirector) { $subEmps = Rules::getSubEmps(); // $REPORT_SECTIONS = []; } } $res['rulesss'] = [ '$isGip'=>$isGip, '$isDirector'=>$isDirector, '$isOnlyAr'=>$isOnlyAr, '$isOnlyKr'=>$isOnlyKr, '$isMainEngineer'=>$isMainEngineer, '$isDepartmentDirector'=>$isDepartmentDirector, ]; //$res['$isDepartmentDirector'] = $isDepartmentDirector; $isSummary = !boolval($_POST['subtype']); $graph1 = []; $graph2 = []; $avgPerHour = []; $minBegin = null; $maxEnd = null; $SMP_ABSENCES = Emp::getAbsencesToday(); $IS_ALL_SECTION_VIEW = false; $MY_ROLES = []; $r = Member::select($qq = [ \Query::TABLES =>[ Member::$table_name], \Query::LEFT_JOINS =>[ [Team::$table_name,Team::$ID,Member::$TEAM], [Project::$table_name,Project::$TEAM,Team::$ID], ], \Query::WHERE => new \Where(\Where::_and([ \Where::_operator(Member::$EMP,'=',Emp::$AUTH_ID), \Where::_operator(Member::$ACTIVE,'=',1), ]))] ); while($l = \DB::fetch($r)){ $MY_ROLES[$l[Project::$ID]] = $l[Member::$ROLE]; } $res['$MY_ROLES'] = $MY_ROLES; $res['$MY_ROLES_Q'] = (string)new \Query($qq); if((Emp::isViewAll() || Emp::isAdmin() || Emp::isMeTopManager() || Emp::isMeGroup(eEmpGroup::GENERAL) || Emp::isMeGroup(eEmpGroup::ALL) ) ) { $IS_ALL_SECTION_VIEW = true; } else { // $and[] = \Where::_operatorForce(Member::$ACTIVE, '=', 1); // $and[] = \Where::_operatorForce(Project::$DIRECTOR, '=', Emp::$AUTH_ID); } $and[] = \Where::_operatorForce(Project::$TEAM,'=',Member::$TEAM); $dir_ids = []; if($_POST['directors']){ foreach ($_POST['directors'] as $v){ if(intval($v) and $v>0){ $dir_ids[] = $v; } } } if($dir_ids){ $and[] = \Where::_in(Project::$DIRECTOR,$dir_ids); } $step_ids = []; if($_POST['steps']){ foreach ($_POST['steps'] as $v){ if(intval($v) and $v>0){ $step_ids[] = $v; } } } if($step_ids){ $and[] = \Where::_in(Project::$STEP,$step_ids); } $and2 = $and; if($project_and){ $and = array_merge($and,$project_and); } if($project_and_all){ $and2 = array_merge($and2,$project_and_all); $r = Member::select($q = [ \Query::TABLES => [Member::$table_name], \Query::LEFT_JOINS => [ [Section::$table_name,Section::$ID,Member::$SECTION], [Project::$table_name,Project::$TEAM,Member::$TEAM], [Emp::$table_name,Emp::$ID,Member::$EMP], ], \Query::SELECT => [ 'COUNT(DISTINCT '.Project::$ID.') as cc', ], \Query::WHERE => $and2 ? new \Where(\Where::_and($and2)) : null, ]); $l = \DB::fetch($r); $res['project_count'] = $l['cc']; } if($isSummary){ if(!Rules::isAdmin()){ $arr = Project::getListForSummary(); $pids = []; foreach ($arr as $v) { $pids[] = $v[Project::$ID]; } if($pids) { $and[] = \Where::_in(Project::$ID, $pids); } } } $r = Member::select($q = [ \Query::TABLES => [Member::$table_name], \Query::LEFT_JOINS => [ [Section::$table_name,Section::$ID,Member::$SECTION], [Project::$table_name,Project::$TEAM,Member::$TEAM], [Emp::$table_name,Emp::$ID,Member::$EMP], ], \Query::SELECT => [ Project::$NAME.' as name', Project::$NAME, Project::$CODE.' as code', Project::$TEAM.' as team', Project::$STEP.' as step', Project::$DATE, Project::$TEAM.' as team_id', Project::$STATUS.' as status', Project::$STEP, Project::$CODE, Project::$ARCHIVE, Project::$DIRECTOR.' as dir_id', Project::$ID.' as id', Emp::$NAME.' as emp', Emp::$ID.' as emp_id', Emp::$NAME, Emp::$ARCHIVE, Section::$STEP, Section::$ID, Section::$NAME, Member::$SECTION.' as emp_section', Member::$ROLE.' as emp_role', Member::$ID.' as member_id', Member::$ACTIVE, ], \Query::WHERE => $and ? new \Where(\Where::_and($and)) : null, \Query::SORT => [ Project::$CODE=>'ASC', Section::$NAME=>'ASC', ], ]); $total_hours = 0; $mathSections = ['АР', 'КР', 'ИОС', 'СПЕЦ', 'BIM-IT', 'УПР']; $mathSections = [ Member\structure\eMemberRole::MAIN_ARCHITECT => ['АР'], Member\structure\eMemberRole::MAIN_CONSTRUCTOR => ['КР'], Member\structure\eMemberRole::DIRECTOR_ENGINEER_EOM => ['ИОС'], Member\structure\eMemberRole::DIRECTOR_ENGINEER_SSIAK => ['ИОС'], Member\structure\eMemberRole::DIRECTOR_ENGINEER_VK => ['ИОС'], Member\structure\eMemberRole::DIRECTOR_ENGINEER_OVIK => ['ИОС'], Member\structure\eMemberRole::DIRECTOR_ENGINEER => ['ИОС'], Member\structure\eMemberRole::MAIN_ENGINEER => ['all'], ]; $res['q'] = (string) new \Query($q); $loopCounter = 0; $periods = self::getPeriodWithDays($begin,$end); foreach ($periods as $period){ $d = strtotime($period[0]); $y = date('Y',$d); $m = date('m',$d); $res['periods'][$y][] = $m; } $isAdmin = Rules::isAdmin(); //$isAdmin = true; $myMoneyProjectIds = []; if(!$isAdmin){ $myMoneyProjectIds = Project::getListForMoney(); } $res['myMoneyProjectIds'] = $myMoneyProjectIds; $res['isAdmin'] = $isAdmin; $emp_ids = []; while($l = \DB::fetch($r)){ $pid = $l['id']; $emp_id = $l['emp_id']; $res['step'][$l['step']] = $step = Step::getStructure($l['step']); $emp_section = $l['emp_section']; $emp_section_name = Section::getFullName($l); $isMeDirectorLocal = Rules::isMeDirector($pid); //$res['$isMeDirectorLocal'][$pid] = $isMeDirectorLocal; //$res['$subEmps'][$pid] = $subEmps; $res['$PidEmps'][$pid][] = $emp_id; //$res['$isOnlyAr || $isOnlyKr || $isMainEngineer'][$pid] = $isOnlyAr || $isOnlyKr || $isMainEngineer; //$res['$isDepartmentDirector'][$pid] = $isOnlyAr || $isOnlyKr || $isMainEngineer; $empSectionFirstLetters = mb_strtoupper(mb_substr($emp_section_name,0,2)); if($isOnlyAr || $isOnlyKr || $isMainEngineer){ if($isMainEngineer){ if ($emp_section_name != $REPORT_SECTIONS[0]) continue; } else { if ($empSectionFirstLetters != $REPORT_SECTIONS[0]) continue; } } else if($isDepartmentDirector){ if($isMeDirectorLocal){ } else { if (!in_array($emp_id, $subEmps)) continue; } //$REPORT_SECTIONS[] = $empSectionFirstLetters; //$REPORT_SECTIONS = array_unique($REPORT_SECTIONS); } $section_parent = $step['base'][$emp_section]['path'][0]; $isRemovedSection = false; $parent_section_name = ''; $emp_section_name = ''; if(!$section_parent){ $isRemovedSection = true; $section_parent = $emp_section; } else { $parent_section_name = $step['base'][$emp_section][Section::$NAME]; $parent_section_name = $step['base'][$section_parent][Section::$NAME]; $res['$parent_section_name'][] = $parent_section_name; } $is_all_section = ($MY_ROLES[$pid] == Member\structure\eMemberRole::MAIN_ENGINEER); $isMeDirector = (Emp::$AUTH_ID == $l['dir_id']); $res['roles'][] = $l['emp_role']; $res['project_view'][$pid] = [$IS_ALL_SECTION_VIEW , in_array($parent_section_name,$mathSections[$MY_ROLES[$pid]]), $MY_ROLES[$pid],$parent_section_name, $is_all_section,$isMeDirector]; if($IS_ALL_SECTION_VIEW || in_array($parent_section_name,$mathSections[$MY_ROLES[$pid]]) || $is_all_section || $isMeDirector || true ) { $res['project'][$pid] = $l; $l['role'] = Member\structure\eMemberRole::getName($l['emp_role']); $l['section'] = Section::getFullName($l); $l['emp_name'] = Emp::SurnameIO($l); //$info = self::getEmpTime($begin,$end, $emp_id, $pid); $info = self::getEmpsTimeWithFot($begin,$end,$emp_id,$pid); if($emp_id) $emp_ids[] = $emp_id; //$res['aa'][$emp_id][$pid] = $info;; //$res['bb'][$emp_id][$pid] = $info;; $l['info'] = $info; if (!$res['data'][$pid][$emp_id]) $res['data'][$pid][$emp_id] = $l; if(!$isAdmin){ if(!in_array($pid,$myMoneyProjectIds)){ $info['money_hours'] = 0; $info['money_over1'] = 0; $info['money_over2'] = 0; $info['money'] = 0; foreach ($info['money_period'] as $year=>$months) { foreach ($months as $month => $vals) { $info['money_period'][$year][$month]['total'] = 0; } } $res['data'][$pid][$emp_id]['no_money'] = true; } } $hours = $info['hours']; $over = $info['over']; $over1 = $info['over1']; $over2 = $info['over2']; $total = $info['total']; $money = $info['money']; $res['data'][$pid][$emp_id]['hours'] = $hours; $res['data'][$pid][$emp_id]['over'] = $over; $res['data'][$pid][$emp_id]['over1'] = $over1; $res['data'][$pid][$emp_id]['over2'] = $over2; $res['data'][$pid][$emp_id]['total'] = $total; $res['data'][$pid][$emp_id]['absence'] = $SMP_ABSENCES[$emp_id][DAbsence::$NAME]; $res['data'][$pid][$emp_id]['money_hours'] += $info['money_hours']; $res['data'][$pid][$emp_id]['money_over1'] += $info['money_over1']; $res['data'][$pid][$emp_id]['money_over2'] += $info['money_over2']; $res['data'][$pid][$emp_id]['money_total'] += $info['money']; $res['data'][$pid][$emp_id]['xx'][] = $info['xx']; $res['data'][$pid][$emp_id]['active'] = $l[Member::$ACTIVE]?1:0; $res['data'][$pid][$emp_id]['archive'] = intval($l[Emp::$ARCHIVE]); if ($emp_section) { $res['section'][$pid][$emp_section]['name'] = $emp_section_name = Section::getFullName($l);// $step['base'][$emp_section][Section::$NAME]; //$res['section'][$pid][$emp_section]['name'] = Section::getName($l);// $step['base'][$emp_section][Section::$NAME]; $res['section'][$pid][$emp_section]['emps'][$emp_id] = $l; $res['section'][$pid][$emp_section]['hours'] += $hours; $res['section'][$pid][$emp_section]['over'] += $over; $res['section'][$pid][$emp_section]['over1'] += $over1; $res['section'][$pid][$emp_section]['over2'] += $over2; $res['section'][$pid][$emp_section]['total'] += $total; $res['section'][$pid][$emp_section]['emp_hours'][$emp_id] += $total; $res['section'][$pid][$emp_section]['money_hours'] += $info['money_hours']; $res['section'][$pid][$emp_section]['money_over1'] += $info['money_over1']; $res['section'][$pid][$emp_section]['money_over2'] += $info['money_over2']; $res['section'][$pid][$emp_section]['money_total'] += $info['money']; } if ($section_parent) { $res['sections'][$section_parent]['name'] = $section_name = ($isRemovedSection ? 'Архив №' . $section_parent : $step['base'][$section_parent][Section::$NAME]); $res['sections'][$section_parent]['emps'][$emp_id] = $l; $res['sections'][$section_parent]['hours'] += $hours; $res['sections'][$section_parent]['over'] += $over; $res['sections'][$section_parent]['total'] += $total; $section_name = mb_convert_case($section_name, MB_CASE_UPPER); $res['parents'][$pid][$section_parent]['name'] = $section_name; if (!$res['parents'][$pid][$section_parent]['emps']) $res['parents'][$pid][$section_parent]['emps'] = []; if (!$res['parents'][$pid][$section_parent]['total_emps']) $res['parents'][$pid][$section_parent]['total_emps'] = []; $res['parents'][$pid][$section_parent]['total_emps'][] = $emp_id; if ($total) { $res['parents'][$pid][$section_parent]['emps'][] = $emp_id; } $res['parents'][$pid][$section_parent]['hours'] += $hours; $res['parents'][$pid][$section_parent]['over'] += $over; $res['parents'][$pid][$section_parent]['over1'] += $over1; $res['parents'][$pid][$section_parent]['over2'] += $over2; $res['parents'][$pid][$section_parent]['total'] += $total; $res['parents'][$pid][$section_parent]['money_hours'] += $info['money_hours']; $res['parents'][$pid][$section_parent]['money_over1'] += $info['money_over1']; $res['parents'][$pid][$section_parent]['money_over2'] += $info['money_over2']; $res['parents'][$pid][$section_parent]['money_total'] += $info['money']; // if(in_array($section_name,$mathSections)) { //if($IS_ALL_SECTION) { $res['projects2'][$pid]['sections'][$section_name]['total'] += $total; if ($total) { $res['projects2'][$pid]['sections'][$section_name]['emps'][] = $emp_id; $res['projects2'][$pid]['sections'][$section_name]['emps'] = array_unique($res['projects2'][$pid]['sections'][$section_name]['emps']); $res['projects2'][$pid]['emps_total_count'][] = $emp_id; $res['projects2'][$pid]['emps_total_count'] = array_unique($res['projects2'][$pid]['emps_total_count']); } $res['projects2'][$pid]['sections']['total'] += $total; //$res['projects2'][$pid]['money'] += $total * self::$PER_HOUR; //$res['total_money'] += $total * self::$PER_HOUR; $res['projects2'][$pid]['money'] += $money; $res['total_money'] += $money; $res['sections_total'][$section_name] += $total; $res['sections_total']['total'] += $total; $res['sections_money'][$section_name] += $money; //} foreach ($info['period'] as $year=>$months){ $mt = 0; foreach ($months as $month=>$vals){ $ymTimeTotal = $info['period'][$year][$month]['total']; $ymMoneyTotal = $info['money_period'][$year][$month]['total']; // Для периодов $res['period_data'][$year][$month]['time'] += $ymTimeTotal; $res['period_data'][$year][$month]['money'] += $ymMoneyTotal; $time_max = $res['period_info']['time']; $time_curr = $res['period_data'][$year][$month]['time']; $money_max = $res['period_info']['money']; $money_curr = $res['period_data'][$year][$month]['money']; $res['period_info']['time'] = $time_max ? max($time_max,$time_curr) : $time_curr; $res['period_info']['money'] = $money_max ? max($money_max,$money_curr) : $money_curr; // Теперь для главных секций $time_curr = ($res['section_data'][$section_name][$year][$month]['time'] += $ymTimeTotal); $money_curr = ($res['section_data'][$section_name][$year][$month]['money'] += $ymMoneyTotal); $time_max = $res['section_info']['time'][$section_name]['max']; $money_max = $res['section_info']['money'][$section_name]['max']; $res['section_info']['time'][$section_name]['max'] = $time_max ? max($time_max,$time_curr) : $time_curr; $res['section_info']['money'][$section_name]['max'] = $money_max ? max($money_max,$money_curr) : $money_curr; $res['section_info']['time'][$year][$month] += $ymTimeTotal; $res['section_info']['money'][$year][$month] += $ymMoneyTotal; $res['section_info']['time']['max'] = $res['section_info']['time']['max'] ? max($res['section_info']['time']['max'],$res['section_info']['time'][$section_name]['max']) : $res['section_info']['time'][$section_name]['max']; // Теперь по подсекциям $time_curr = ($res['subsection_data'][$emp_section_name][$year][$month]['time'] += $ymTimeTotal); $money_curr = ($res['subsection_data'][$emp_section_name][$year][$month]['money'] += $ymMoneyTotal); $time_max = $res['subsection_info']['time'][$emp_section_name]['max']; $money_max = $res['subsection_info']['money'][$emp_section_name]['max']; $res['subsection_info']['time'][$emp_section_name]['max'] = $time_max ? max($time_max,$time_curr) : $time_curr; $res['subsection_info']['money'][$emp_section_name]['max'] = $money_max ? max($money_max,$money_curr) : $money_curr; $res['subsection_info']['time'][$year][$month] += $ymTimeTotal; $res['subsection_info']['money'][$year][$month] += $ymMoneyTotal; $res['subsection_info']['time']['max'] = $res['subsection_info']['time']['max'] ? max($res['section_info']['time']['max'],$res['subsection_info']['time'][$emp_section_name]['max']) : $res['subsection_info']['time'][$emp_section_name]['max']; // Теперь по подсекциям для pie $res['sub'][$parent_section_name][$emp_section_name][$year][$month]['time'] += $ymTimeTotal; $res['sub'][$parent_section_name][$emp_section_name][$year][$month]['money'] += $ymMoneyTotal; $res['sub_graph'][$parent_section_name]['time'][$emp_section_name]['title'] = $emp_section_name; $res['sub_graph'][$parent_section_name]['time'][$emp_section_name]['value'] += $ymTimeTotal; $res['sub_graph'][$parent_section_name]['money'][$emp_section_name]['title'] = $emp_section_name; $res['sub_graph'][$parent_section_name]['money'][$emp_section_name]['value'] += $ymMoneyTotal; } } } $res['total'] += $total; $res['hours'] += $hours; $res['over'] += $over; $res['projects2'][$pid]['archive'] = boolval($l[Project::$ARCHIVE]); $res['projects2'][$pid]['name'] = ($l['name']); //$res['projects2'][$pid]['code'] = Project::getCode($l); $res['projects2'][$pid]['code'] = $l[Project::$CODE]; $res['projects2'][$pid]['step'] = ($c = intval($l[Project::$STEP])) ? Step::getName(Step::getByID($c)) : ''; $res['projects2'][$pid]['status'] = eStatus::getName($l['status']); $res['projects2'][$pid]['hours'] += $hours; $res['projects2'][$pid]['total'] += $total; $res['projects2'][$pid]['over'] += $over; $res['projects2'][$pid]['over1'] += $over1; $res['projects2'][$pid]['over2'] += $over2; $res['projects2'][$pid]['money_hours'] += $info['money_hours']; $res['projects2'][$pid]['money_over1'] += $info['money_over1']; $res['projects2'][$pid]['money_over2'] += $info['money_over2']; $res['projects2'][$pid]['money_total'] += $info['money']; $total_hours += $total; if ($total) { $res['projects2'][$pid]['emp_ids'][] = $l['emp_id']; } $res['projects2'][$pid]['emp_ids_total'][] = $l['emp_id']; $res['projects2'][$pid]['team'] = $l['team_id']; $res['projects2'][$pid]['dir_id'] = $l['dir_id']; } } $res['graph2'][] = ['title'=>'Рабочие', 'value'=>$res['hours']]; $res['graph2'][] = ['title'=>'Сверхурочные','value'=>$res['over']]; $emp_ids = array_unique($emp_ids); foreach ($emp_ids as $emp_id) { $info = self::getEmpsTimeWithFot($begin, $end, $emp_id); foreach ($info['fot'] as $year => $months) { foreach ($months as $month => $ph) { $avgPerHour[] = $ph; } } } foreach ($res['section'] as $pid=>&$sections){ uasort($sections,function ($x,$y){ return $x['name']<=>$y['name']; }); unset($sections); } foreach ($res['parents'] as $pid=>&$sections){ uasort($sections,function ($x,$y){ return $x['name']<=>$y['name']; }); unset($sections); } foreach ($res['data'] as $pid=>&$sections){ uasort($sections,function ($x,$y){ return $x['emp']<=>$y['emp']; }); unset($sections); } $res['period_info']['money'] = self::convertMoney($res['period_info']['money']); $summaryGraph1 = [ 'title'=>'Время, ч.', 'titles'=>['Время пр-я, ч'], 'labels'=>[], 'datasets'=>[[ 'borderColor'=>Merakomis::getChartColor(0), 'data'=>[], ]] ]; $summaryGraph2 = [ 'title'=>'Стоимость пр-я, млн '.Merakomis::CURRENCY, 'titles'=>['Стоимость пр-я, млн '.Merakomis::CURRENCY], 'labels'=>[], 'datasets'=>[[ 'borderColor'=>Merakomis::getChartColor(1), 'data'=>[], ]] ]; // Графики для проекта по разделам $graphProjectSections = [ 'title'=>'Время проектирования, ч.', 'titles'=>($isOnlyAr || $isOnlyKr || $isMainEngineer) ? $REPORT_SECTIONS : array_slice($REPORT_SECTIONS,0,3), 'labels'=>[], 'datasets'=>[ [ 'borderColor'=>Merakomis::getGraphColor(0), 'data'=>[], ], [ 'borderColor'=>Merakomis::getGraphColor(1), 'data'=>[], ], [ 'borderColor'=>Merakomis::getGraphColor(2), 'data'=>[], ], ] ]; $graphProjectSubsections = [ 'title'=>'Время проектирования, ч.', 'titles'=>array_keys($res['subsection_data']), 'labels'=>[], 'datasets'=>[ ] ]; foreach ($graphProjectSubsections['titles'] as $key=>$name) { //$graphProjectSubsections['datasets'][$key]['borderColor'] = Merakomis::getChartColor($key); $graphProjectSubsections['datasets'][$key]['borderColor'] = Merakomis::getGraphColor($key); } foreach ($res['period_data'] as $y=>$mm){ foreach($mm as $m=>$v){ $label = $m.'.'.substr($y,2,2); $summaryGraph1['labels'][] = $label; $summaryGraph2['labels'][] = $label; $graphProjectSubsections['labels'][] = $label; $graphProjectSections['labels'][] = $label; $summaryGraph1['datasets'][0]['data'][] = $res['period_data'][$y][$m]['time']; $summaryGraph2['datasets'][0]['data'][] = $res['period_data'][$y][$m]['money']; foreach ($graphProjectSections['titles'] as $key=>$name){ $graphProjectSections['datasets'][$key]['data'][] = $res['section_data'][$name][$y][$m]['time']; } foreach ($graphProjectSubsections['titles'] as $key=>$name){ $graphProjectSubsections['datasets'][$key]['data'][] = $res['subsection_data'][$name][$y][$m]['time']; } $res['period_data'][$y][$m]['money'] = self::convertMoney($v['money']); } } if($isOnlyAr || $isOnlyKr || $isMainEngineer){ $graphProjectSections['datasets'] = [$graphProjectSections['datasets'][0]]; } else { $graphProjectSections['datasets'] = array_slice($graphProjectSections['datasets'],0,3); } $res['summaryGraph1'] = $summaryGraph1; $res['summaryGraph2'] = $summaryGraph2; $res['graphProjectSections'] = $graphProjectSections; $res['graphProjectSubsections'] = $graphProjectSubsections; foreach ($res['projects2'] as $pid=>$project){ foreach ($project['sections'] as $section_name=>$a){ $res['section_emp_total'][$section_name] += count( $a['emps'] ); $res['section_emp_total']['total'] += count( $a['emps'] ); } $res['projects2'][$pid]['money'] = self::convertMoney($res['projects2'][$pid]['money']); $res['projects2'][$pid]['money_hours'] = self::convertMoney($res['projects2'][$pid]['money_hours']); $res['projects2'][$pid]['money_over1'] = self::convertMoney($res['projects2'][$pid]['money_over1']); $res['projects2'][$pid]['money_over2'] = self::convertMoney($res['projects2'][$pid]['money_over2']); $res['projects2'][$pid]['money_total'] = self::convertMoney($res['projects2'][$pid]['money_total']); } $res['total_money'] = self::convertMoney($res['total_money']); $emps_info = []; foreach ($res['data'] as $pid=>&$emps){ $res['graph1'][] = [ 'title'=>Project::getCodeName($res['project'][$pid]), 'value'=>$total_hours ? round($res['projects2'][$pid]['total'] / $total_hours * 100) : 0, ]; foreach ($emps as &$v){ $emp_id = $v['emp_id']; $b = $begin ? : (self::getFirstDateForEmp($emp_id) ? : date('Y-m-d')); $e = $end ? : date('Y-m-d'); $b = ($b == '0000-00-00') ? date('Y-m-d') : $b; $total = Day::getWorkHours($b,$e); $v['range'] = [$b,$e,$res['project'][$pid][Project::$DATE],$total ]; $minBegin = $minBegin ? min($b,$minBegin) : $b; $maxEnd = $maxEnd ? max($e,$maxEnd) : $e; if(!$emps_info[$emp_id]){ $emps_info[$emp_id] = self::getEmpTime($begin,$end,$emp_id,null); } $st = $res['section'][$pid][$v['emp_section']]['total']; $h = $emps_info[$emp_id]['hours']; $t = $emps_info[$emp_id]['total']; //$v['x'] = round( $st ? $v['total'] / $st * 100 : 0).'% '.$v['hours'].'/'.$st; $v['x'] = round( $st ? $v['total'] / $st * 100 : 0).'%'; $v['y'] = round( $total ? $h / $total * 100 : 0).'%' ; $v['z'] = round( $total ? $t / $total * 100 : 0).'%' ; $v['money_hours'] = self::convertMoney($v['money_hours']); $v['money_over1'] = self::convertMoney($v['money_over1']); $v['money_over2'] = self::convertMoney($v['money_over2']); $v['money_total'] = self::convertMoney($v['money_total']); } } unset($emps); unset($v); $graph3 = []; $graph4 = []; foreach ($REPORT_SECTIONS as $name){ $graph3[] = [ 'title'=>$name,'value'=>cfloatval($res['sections_total'][$name]), ]; $graph4[] = [ 'title'=>$name,'value'=>cfloatval(self::convertMoney($res['sections_money'][$name])), ]; } $res['graph3'] = $graph3; $res['graph4'] = $graph4; foreach($res['sub_graph'] as $sid=>$v){ $res['sub_graph'][$sid]['time'] = array_values($v['time']); $res['sub_graph'][$sid]['money'] = array_values($v['money']); foreach($res['sub_graph'][$sid]['money'] as &$vv){ $vv['value'] = cfloatval(self::convertMoney($vv['value'],['round'=>3])); unset($vv); } Merakomis::graphClass($res['sub_graph'][$sid]['time'],false); Merakomis::graphClass($res['sub_graph'][$sid]['money'],false); } Merakomis::graphClass($res['graph1'],true,true,true); Merakomis::graphClass($res['graph2'],false); Merakomis::graphClass($res['graph3'],false); Merakomis::graphClass($res['graph4'],false); $periods = self::getPeriodWithDays($begin,$end); $res['mYperiods'] = $periods; foreach ($res['section']as $pid=>&$s){ $b = $begin ? : ($res['project'][$pid][Project::$DATE] ? : date('Y-m-d')); $e = $end ? : date('Y-m-d'); $b = ($b == '0000-00-00') ? date('Y-m-d') : $b; $total = Day::getWorkHours($b,$e); foreach ($s as $sid=>&$v){ $v['r'] = number_format($total ? $v['hours']/$total : 0,"2","."," "); $v['o'] = number_format($total ? $v['total']/$total : 0,"2","."," "); $v['t'] = $total; $v['money_hours'] = self::convertMoney($v['money_hours']); $v['money_over1'] = self::convertMoney($v['money_over1']); $v['money_over2'] = self::convertMoney($v['money_over2']); $v['money_total'] = self::convertMoney($v['money_total']); } } unset($v); unset($s); $counter = 0; $keys = ['hours', 'over1', 'over2', 'total', 'money_hours', 'money_over1', 'money_over2', 'money_total',]; foreach ($res['parents']as $pid=>&$s){ $b = $begin ? : ($res['project'][$pid][Project::$DATE] ? : date('Y-m-d')); $e = $end ? : date('Y-m-d'); $b = ($b == '0000-00-00') ? date('Y-m-d') : $b; $total = Day::getWorkHours($b,$e); foreach ($s as $sid=>&$v){ $v['r'] = number_format($rValue = $total ? $v['hours']/$total : 0,"2","."," "); $v['o'] = number_format($oValue = $total ? $v['total']/$total : 0,"2","."," ");//.":".$v['total'].":".$v['over']; $v['t'] = $total; $v['money_hours'] = self::convertMoney($v['money_hours']); $v['money_over1'] = self::convertMoney($v['money_over1']); $v['money_over2'] = self::convertMoney($v['money_over2']); $v['money_total'] = self::convertMoney($v['money_total']); $v['total_emps'] = array_unique($v['total_emps']); $v['emps'] = array_unique($v['emps']); //$v['bg'] = Merakomis::getGraphClasses($counter++); $res['totals']['sections']['r'] += $rValue; $res['totals']['sections']['o'] += $oValue; $res['totals']['sections']['emps'] += count($v['emps']); $res['totals']['sections']['total_emps'] += count($v['total_emps']); foreach ($keys as $key){ $res['totals']['sections'][$key] += $v[$key]; $res['totals']['subsections'][$v['name']][$key] += $v[$key]; } } unset($v); } unset($s); $res['totals']['sections']['r'] = number_format($res['totals']['sections']['r'],"2","."," "); $res['totals']['sections']['o'] = number_format($res['totals']['sections']['o'],"2","."," "); $res['absence'][] = []; $nf = function ($x,$o=2){ return number_format($x,$o,".",""); }; foreach ($res['project'] as $pid=>$v){ $b = $begin ? : ($v[Project::$DATE] ? : date('Y-m-d')); $e = $end ? : date('Y-m-d'); $b = ($b == '0000-00-00') ? date('Y-m-d') : $b; // $res['hours2'][$pid]['range'] = [$b,$e]; $res['projects2'][$pid]['t'] = $t = Day::getWorkHours($b,$e); $res['projects2'][$pid]['r'] = $nf($t ? $res['projects2'][$pid]['hours'] / $t : 0); $res['projects2'][$pid]['o'] = $nf($t ? $res['projects2'][$pid]['total'] / $t : 0); $res['projects2'][$pid]['v'] = $nf($res['projects2'][$pid]['r']*100,0).'%'; $res['projects2'][$pid]['n'] = $nf( $res['projects2'][$pid]['over'] ? ($res['projects2'][$pid]['hours'] / $res['projects2'][$pid]['over'])*100 : 0,0).'%'; $res['projects2'][$pid]['range'] = [$b,$e]; $res['projects2'][$pid]['emps'] = count(array_unique($res['projects2'][$pid]['emp_ids'])); $res['projects2'][$pid]['emps_total'] = count(array_unique($res['projects2'][$pid]['emp_ids_total'])); $res['projects2'][$pid]['director'] = [ 'id'=>0, 'title'=>'', ]; if($did = $res['projects2'][$pid]['dir_id']){ $e = Emp::getByID($did); if($e){ $res['projects2'][$pid]['director'] = [ 'id'=>$did, 'title'=>Emp::SurnameIO($e), ]; } } /* $r = Member::select([ \Query::SELECT => ['COUNT(*) as cc'], \Query::WHERE => \Where::_operator(Member::$TEAM,'=',intval($res['projects2'][$pid]['team'])) ]); $l = \DB::fetch($r); */ //$res['projects2'][$pid]['emps_total'] = intval($l['cc']); $res['total_r'] += $res['projects2'][$pid]['r']; $res['total_o'] += $res['projects2'][$pid]['o']; } $period = self::getPeriod($begin,$end); $res['work_days'] = $minBegin && $maxEnd ? Day::getWorkDays($minBegin,$maxEnd) : 0; $res['work_hours'] = $minBegin && $maxEnd ? Day::getWorkHours($minBegin,$maxEnd) : 0; //$res['per_hour'] = self::$PER_HOUR.' '.Merakomis::CURRENCY.'/ч.'; $res['per_hour'] = ($avgPerHour ? number_format(array_sum($avgPerHour)/count($avgPerHour),0,"."," ") : 0).' '.Merakomis::CURRENCY.'/ч.'; if(!Rules::isAnalysisProjectsShowMoney($PROJECT_ID)){ $res['per_hour'] = '- '.Merakomis::CURRENCY.'/ч.';; } $res['$avgPerHour'] = $avgPerHour; $res['$avgPerHourSum'] = array_sum($avgPerHour); $res['report_sections'] = $REPORT_SECTIONS; $res['directors'] = array_values($res['directors']); $res['total_r'] = number_format($res['total_r'],2,"."," "); $res['total_o'] = number_format($res['total_o'],2,"."," "); return $res; } static function getDepartmentStat($project_and,$and,$time_and,&$absence_and,$begin,$end) { $res = [ 'data'=>[], 'absence'=>[], 'total'=>[], 'post'=>[], 'dids'=>[], ]; //$emp_ids = Emp::getSubEmps(Emp::$AUTH_ID); //$emp_ids[] = Emp::$AUTH_ID; //$absence_and[] = \Where::_in(Absence::$EMP,array_unique($emp_ids)); $select_dep_ids = []; if($_POST['department']){ foreach ($_POST['department'] as $dep_id){ if($dep_id = intval($dep_id)) { $select_dep_ids[] = $dep_id; } } } $res['$select_dep_ids'] = $select_dep_ids; // Получаем список подразделений, где я руководитель $r = Post::select($q = [ \Query::TABLES => [Post::$table_name], \Query::LEFT_JOINS => [ [Department::$table_name,Department::$ID,Post::$DEPARTMENT], ], \Query::WHERE => new \Where(\Where::_and([ \Where::_operator(Post::$EMP,'=',Emp::$AUTH_ID), \Where::_operator(Post::$IS_DIRECTOR,'=',1), ])) ]); $project_ids = []; $project_and[] = \Where::_or([ \Where::_operator(Emp::$ARCHIVE,'=',0), $begin ? \Where::_operator(Emp::$ARCHIVE_DATE,'>=',$begin) : null, ]); $structure = $s = Department::getStructure(); $res['departments']['0'] = ['id'=>'0','title'=>'Все департаменты']; while($ll = \DB::fetch($r)){ // Теперь надо получить сотрудников по каждому департаменту $id = $ll[Post::$ID]; $did = $ll[Department::$ID]; $department_name = Department::getName($ll); $res['departments'][$did] = ['name'=>$department_name,'title'=>$department_name,'id'=>$did]; if($select_dep_ids and !in_array($did,$select_dep_ids)) { continue; } $dep_ids = Emp::getIdsForSubEmps($did); $dep_ids[] = $did; $res['deps'][$id] = $dep_ids; $x = ['employees','directors']; $eids = []; foreach ($dep_ids as $dep_id){ $d = $s['base'][$dep_id]; foreach ($x as $type) { foreach ($d[$type] as $directors) { if($directors['emp']['id']){ $eids[] = intval($directors['emp']['id']); } /* foreach ($directors['roles'] as $role) { if ($role['emp']['id']) { $eids[] = intval($role['emp']['id']); } } */ } } } $res['eids'][$id] =$eids; $eids = array_unique($eids); // Теперь надо получить статистику по проектам. $abs_eids = []; if($eids) { $dep_and = $project_and; $dep_and[] = \Where::_in(Emp::$ID,$eids); $rr = Emp::select($q = [ \Query::TABLES => [Emp::$table_name], \Query::LEFT_JOINS => [ [Member::$table_name, Emp::$ID, Member::$EMP], //[Project::$table_name, Project::$TEAM, Member::$TEAM], 'LEFT JOIN '.Project::$table_name.' ON '.Project::$TEAM.'='.Member::$TEAM .($and?str_replace("WHERE"," AND ",new \Where(\Where::_and($and))):'') , [Section::$table_name, Section::$ID, Member::$SECTION], ], \Query::SELECT => [ Emp::$NAME . ' as emp', Emp::$ID . ' as emp_id', Project::$NAME , Project::$NAME . ' as name', Project::$CODE . ' as code', Project::$TEAM . ' as team', Project::$STEP . ' as step', Project::$ID . ' as id', Emp::$STAFFING . ' as staffing_ids', Emp::$NAME . ' as emp', Emp::$ID . ' as emp_id', Section::$ID , Section::$STEP , Section::$NAME , Project::$CODE , Project::$STEP , Member::$SECTION . ' as emp_section', Member::$ROLE . ' as emp_role', Member::$ID . ' as member_id', ], \Query::SORT => [Project::$CODE=>'ASC'], \Query::WHERE => $and ? new \Where(\Where::_and($dep_and)) : null, ]); $res['qq'][] = (string)new \Query($q); while($l = \DB::fetch($rr)){ $pid = $l['id']; $emp_id = $l['emp_id']; $abs_eids[] = $emp_id; $res['project'][$pid] = $l; $role = Member\structure\eMemberRole::getName($l['emp_role']); $l['role'] = $role; $l['section'] = Section::getFullName($l); $project_ids[] = $l['id']; $hours = 0; $over = 0; $total = 0; if($pid) { $info = self::getEmpTime($begin,$end, $emp_id, $pid); $hours = $info['hours']; $over = $info['over']; $total = $info['total']; } if(!$l['code']) $l['code'] = '??'; $l['staffing'] = []; $staffing_ids = json_decode($l['staffing_ids'],true); if($staffing_ids){ $staffs = Staffing::getByIDS($staffing_ids); foreach ($staffs as $v){ $l['staffing'][]= Staffing::getName($v); } $l['staffing'] = implode(", ",$l['staffing']); } if($pid) { if (!$res['data'][$did][$emp_id][$pid]) $res['data'][$did][$emp_id][$pid] = $l; $res['data'][$did][$emp_id][$pid]['hours'] = $hours; $res['data'][$did][$emp_id][$pid]['over'] = $over; $res['data'][$did][$emp_id][$pid]['total'] += $total; $res['emp_roles'][$did][$emp_id][] = $role; } else { $res['data'][$did][$emp_id][$pid] = [ 'emp_id'=>$l['emp_id'], 'emp'=>$l['emp'], ]; if(!$res['emp_roles'][$did][$emp_id]) $res['emp_roles'][$did][$emp_id]=[]; } $res['emp'][$did][$emp_id]['total'] += $total; $res['total'][$did]['title'] = $department_name; $res['total'][$did]['hours'] += $hours; $res['total'][$did]['over' ] += $over; $res['total'][$did]['total'] += $total; $res['total'][$did]['graph1'][$pid]['title'] = Project::getCodeName($l); $res['total'][$did]['graph1'][$pid]['value'] += $total; } foreach ($res['emp_roles'][$did] as $emp_id=>$roles) { $res['emp_roles'][$did][$emp_id] = array_values(array_unique($roles)); } if(!$res['absence'][$did])$res['absence'][$did]=[]; $absence_and2 = $absence_and; //$absence_and2[] = \Where::_in(Absence::$EMP,$eids); $absence_and2[] = \Where::_in(Absence::$EMP,$abs_eids); $ra = Absence::select($q = [ \Query::SELECT => [ 'COUNT(*) as cc', DAbsence::$CODE, DAbsence::$NAME, Absence::$EMP, Absence::$ABSENCE, Emp::$NAME, Emp::$ID, ], \Query::TABLES => [Absence::$table_name], \Query::LEFT_JOINS => [ [Emp::$table_name,Emp::$ID,Absence::$EMP], [DAbsence::$table_name,Absence::$ABSENCE,DAbsence::$ID], ], \Query::WHERE => new \Where(\Where::_and($absence_and2)), \Query::GROUP_BY => [ Absence::$EMP, Absence::$ABSENCE, ], ]); $res['absence_q'][] = (string)new \Query($q); while($la = \DB::fetch($ra)){ $emp_id = $la[Absence::$EMP]; $count = intval($la['cc']); $res['absence'][$did][$emp_id][$la[Absence::$ABSENCE]] = [ 'code'=>$la[DAbsence::$CODE], 'title'=>$la[DAbsence::$NAME]?:'-', 'count'=>$count, 'name'=>$la[Emp::$NAME]?:' ', 'id'=>$la[Emp::$ID], 'roles'=>$res['emp_roles'][$did][$la[Emp::$ID]] ? : [], ]; $res['emp'][$did][$emp_id]['absence'] += $count; $res['total'][$did]['graph3'][$la[Absence::$ABSENCE]]['title'] = $la[DAbsence::$CODE]; $res['total'][$did]['graph3'][$la[Absence::$ABSENCE]]['value'] += $count; } } } $dep_begin = $begin ? : (self::getFirstDateForCompany() ? : date('Y-m-d')); $dep_end = $end ? : date('Y-m-d'); $total_work_hours = Day::getWorkHours($dep_begin,$dep_end); self::getDepartmentEmpsfunction(0,$structure,$res,$dep_begin,$dep_end); // Считаем показатели по департаментам foreach ($res['dids'] as $did=>&$v){ $v['emp_count'] = count($v['emp_ids']); $v['emp_work'] = count(array_keys($v['emps'])); $v['y'] = round($total_work_hours ? $v['hours'] / ($total_work_hours * $v['emp_count']) * 100 : 0).'%'; $v['z'] = round($total_work_hours ? $v['total'] / ($total_work_hours * $v['emp_count']) * 100 : 0).'%'; if(!in_array($did,array_keys($res['total']))){ unset($res['dids'][$did]); } } // $res['data'][$did][$emp_id][$pid] //$res['emp'] = []; $emps_info = []; foreach ($res['data'] as $did_id=>$emps ){ foreach ($emps as $emp_id=>$projects){ foreach ($projects as $v) { $res['emp'][$did_id][$emp_id]['hours'] += $v['hours']; $res['emp'][$did_id][$emp_id]['over'] += $v['over']; //$res['emp'][$did_id][$emp_id]['hours']+=$v['over']; } $b = $begin ? : (self::getFirstDateForEmp($emp_id) ? : date('Y-m-d')); $e = $end ? : date('Y-m-d'); $b = ($b == '0000-00-00') ? date('Y-m-d') : $b; $total = Day::getWorkHours($b,$e); if(!$emps_info[$emp_id]){ $emps_info[$emp_id] = self::getEmpTime($begin,$end,$emp_id,null); } $h = $emps_info[$emp_id]['hours']; $t = $emps_info[$emp_id]['total']; $res['emp'][$did_id][$emp_id]['y'] = round( $total ? $h / $total * 100 : 0).'%' ; $res['emp'][$did_id][$emp_id]['z'] = round( $total ? $t / $total * 100 : 0).'%' ; } } unset($v); $project_ids = array_unique($project_ids); $res['projects_list'] = []; if($project_ids){ $a = Project::getByIDS($project_ids); foreach ($a as $v){ $res['projects_list'][] = Project::format($v); } } foreach ($res['total'] as $did=>&$v){ foreach ($v['graph1'] as $k=>$vv){ $v['graph1'][$k]['value'] = round($v['total'] ? $vv['value'] / $v['total'] * 100: 0); } $v['graph1'] = array_values($v['graph1']); $v['graph2'] = [ ['title'=>'Рабочие','value'=>$v['hours']], ['title'=>'Сверхурочные','value'=>$v['over']], ]; $v['graph3'] = array_values($v['graph3']); foreach ($v['graph3'] as $k=>$vv){ //$v['graph3'][$k]['value'] = round($v['total'] ? $vv['value'] / $v['total'] * 100: 0); } $v['graph3'] = array_values($v['graph3']?:[]); Merakomis::graphClass($v['graph1'],true,true,true); Merakomis::graphClass($v['graph2'],false); Merakomis::graphClass($v['graph3']); } unset($v); $res['roles'] = Member\structure\eMemberRole::getNameList(); array_unshift($res['roles'],['id'=>0,'title'=>'Не выбрано']); return $res; } static function getStaff($emp_and, $absence_and, $begin, $end, $filter){ $res = [ 'saved'=>Filter::formatArray( Filter::getByToOid('analysis_9',msTo::MERAKOMBIS_EMP, Emp::$AUTH_ID) ), 'emp'=>[], 'absence'=>[], 'stat1'=>[], 'stat2'=>[], 'stat3'=>[], 'stat4'=>[], 'stat'=>[ 'emps' =>0, 'salary' =>0, 'per_hour' =>Time::$PER_HOUR, 'age' =>[], 'work' =>[], 'hire' =>0, 'archive' =>0, 'begin' =>0, 'end' =>0, 'ssch' =>0, 'flow' =>0, ], 'filter'=>$filter, 'filter_text'=>'', 'options'=>[ 'staffing'=>[], 'department'=>[], 'type'=>[], 'group'=>[], 'city'=>[], 'org'=>[], 'orgtype'=>[], ], ]; $filter_text = []; $emp_and = [$emp_and]; if(is_numeric($filter[$c ='accept']) and $filter[$c]>=0) { $emp_and[] = \Where::_operator(Emp::$ACCEPT,'=',intval($filter[$c])); $filter_text[] = $filter[$c] ? 'Подтвержденные':'Не подтвержденные'; } if(is_numeric($filter[$c ='active']) and $filter[$c]>=0) { $emp_and[] = \Where::_operator(Emp::$ACTIVE,'=',intval($filter[$c])); $filter_text[] = $filter[$c] ? 'Активные':'Не активные'; } if(is_numeric($filter[$c ='archive']) and $filter[$c]>=0) { $emp_and[] = \Where::_operator(Emp::$ARCHIVE,'=',intval($filter[$c])); $filter_text[] = $filter[$c] ? 'Архивные':'Не архивные'; } if(is_numeric($filter[$c ='type']) and $filter[$c]>0) { $emp_and[] = \Where::_operator(Emp::$TYPE,'=',intval($filter[$c])); $filter_text[] = eEmpType::getName( $filter[$c] ); } if(is_numeric($filter[$c ='city']) and $filter[$c]>0) { $emp_and[] = \Where::_operator(Emp::$CITY,'=',intval($filter[$c])); $filter_text[] = City::getName( City::getByID($filter[$c]) ); } if(is_numeric($filter[$c ='org']) and $filter[$c]>0) { $emp_and[] = \Where::_operator(Emp::$ORG,'=',intval($filter[$c])); $filter_text[] = Org::getName( Org::getByID($filter[$c]) ); } if(is_numeric($filter[$c ='orgtype']) and $filter[$c]>0) { $emp_and[] = \Where::_operator(Emp::$ORG_TYPE,'=',intval($filter[$c])); $filter_text[] = OrgType::getName( OrgType::getByID($filter[$c]) ); } if(is_numeric($filter[$c ='sex']) and $filter[$c]!=0) { $emp_and[] = \Where::_operator(Emp::$SEX,'=',intval($filter[$c])); $filter_text[] = Emp::getSexName([Emp::$SEX=>$filter[$c]]); } if(($filter[$c ='hire']) and $filter[$c]) { $info = self::parseDateFilter($filter[$c]); $infoBegin = $info['begin']; $infoEnd = $info['end']; if($infoBegin) { //$emp_and[] = \Where::_operator(Emp::$DATE_HIRE, '>=', $begin); $emp_and[] = \Where::_between(Emp::$DATE_HIRE, $infoBegin,$infoEnd); $filter_text[] = 'Начало работы с ' . $infoBegin; } } if(is_numeric($filter[$c ='freelancer']) and $filter[$c]>=0) { $emp_and[] = \Where::_operator(Emp::$IS_FREELANCER,'=',$filter[$c]); $filter_text[] = $filter[$c]?'Удалёнка':'Не удалёнка'; } if(is_numeric($filter[$c ='group']) and $filter[$c]>0) { $emp_and[] = \Where::_inQuery(Emp::$ID,[ \Query::TABLES => [Group::$table_name], \Query::SELECT => [Group::$EMP], \Query::WHERE => \Where::_operator(Group::$GROUP,'=',$filter[$c]) ]); $filter_text[] = eEmpGroup::getName($filter[$c]); } $structure = Department::getStructure(); if(is_numeric($filter[$c ='department']) and $filter[$c]>0) { $dep_emp_ids = $structure['base'][$filter[$c]]['emp_ids']; $emp_and[] = \Where::_in(Emp::$ID,$dep_emp_ids?:[0]); $filter_text[] = Department::getName( $structure['base'][$filter[$c]] ); } if(is_numeric($filter[$c ='staffing']) and $filter[$c]>0) { $emp_and[] = \Where::_operator(Emp::$STAFFING,'LIKE','%"'.$filter[$c].'"%') ; $filter_text[] = Staffing::getName( Staffing::getByID(intval($filter[$c])) );; } $EMP_DEPS = []; foreach ($structure['base'] as $v){ foreach ($v['emp_ids'] as $emp_id){ $EMP_DEPS[$emp_id][] = $v['title']; } } $res['$EMP_DEPS'] = $EMP_DEPS; $r = Emp::select($q = [ \Query::LEFT_JOINS =>[ [City::$table_name,City::$ID,Emp::$CITY], [Org::$table_name,Org::$ID,Emp::$ORG], ], \Query::TABLES => [Emp::$table_name], \Query::WHERE => $emp_and ? new \Where(\Where::_and($emp_and) ) : null, // \Query::SORT=>[Project::$CODE=>'ASC'], ]); $res['q'] = (string)new \Query($q); $res['rr'] = $r; while($l = \DB::fetch($r)){ $age = Emp::getAge($l); $work_days = Emp::getWorkDays($l); $res['stat']['emps']++; $res['stat']['salary']+=$l[Emp::$SALARY]; if($age) { $res['stat']['age'][] = $age; } if($work_days) { $res['stat']['work'][] = $work_days; } if($l[Emp::$DATE_HIRE] and $begin and $l[Emp::$DATE_HIRE]>=$begin and $l[Emp::$DATE_HIRE]<=$end){ $res['stat']['hire']++; } if($l[Emp::$ARCHIVE_DATE] and $begin and $l[Emp::$ARCHIVE_DATE]>=$begin and $l[Emp::$ARCHIVE_DATE]<=$end){ $res['stat']['archive']++; } if(($l[Emp::$DATE_HIRE] and $begin and $l[Emp::$DATE_HIRE]<=$begin) || !$l[Emp::$DATE_HIRE]){ $res['stat']['begin']++; } if(($l[Emp::$ARCHIVE_DATE] and $end and $l[Emp::$ARCHIVE_DATE]>=$end) || !$l[Emp::$ARCHIVE_DATE]){ $res['stat']['end']++; } $emp_id = $l[Emp::$ID]; $res['emp'][$emp_id] = [ 'id' => $emp_id, 'name' => Emp::getName($l), 'archive' => intval($l[Emp::$ARCHIVE]), 'staffing' => '', 'department' => implode(", ",$EMP_DEPS[$emp_id]), 'city' => ( $l[Emp::$CITY] ? City::getName($l) : '' ), 'org' => ( $l[Emp::$ORG] ? Org::getName($l) : '' ), 'freelance' => $l[Emp::$IS_FREELANCER] ? 'Да' : 'Нет', 'org_type' => $l[Emp::$ORG_TYPE] ? OrgType::getName(OrgType::getByID( $l[Emp::$ORG_TYPE] )) : '', //'hire' => Merakomis::fdate($l[Emp::$DATE_HIRE]), 'hire' => $l[Emp::$DATE_HIRE], //'sex' => ($l[Emp::$SEX]?'Мужской':'Женский'), 'sex' => Emp::getSexName($l), 'age' => $age, 'work_period' => Emp::getWorkPeriod($l), 'nopriz' => $l[Emp::$NOPRIZ], 'nostroi' => $l[Emp::$NOSTROI], 'technadzor' => $l[Emp::$TECHNADZOR], 'children' => [], 'salary' => Merakomis::fprice($l[Emp::$SALARY]), 'per_hour' => Merakomis::fprice(Time::$PER_HOUR), ]; $staffing_ids = json_decode($l[Emp::$STAFFING],true); if($staffing_ids){ $staffs = Staffing::getByIDS($staffing_ids); $res['emp'][$emp_id]['staffing'] = []; foreach ($staffs as $v){ $res['emp'][$emp_id]['staffing'][] = Staffing::getName($v); } $res['emp'][$emp_id]['staffing'] = implode(", ",$res['emp'][$emp_id]['staffing']); } $res['stat1'][] = $emp_id; $res['stat2'][] = $emp_id; if($l[Emp::$NOPRIZ] || $l[Emp::$NOSTROI] || $l[Emp::$TECHNADZOR] ){ $res['stat4'][] = $emp_id; } } $emp_ids = array_keys($res['emp']); if($emp_ids) { $r = Children::select([ \Query::WHERE => new \Where(\Where::_and([ \Where::_in(Children::$EMP, $emp_ids), ])) ]); while ($l = \DB::fetch($r)) { $emp_id = $l[Children::$EMP]; $res['emp'][$emp_id]['children'][] = [ 'name' => Children::getName($l), 'age' => Children::getAge($l), ]; $res['stat3'][] = $emp_id; } $res['stat3'] = array_values(array_unique($res['stat3'])); $absence_and[] = \Where::_in(Emp::$ID, $emp_ids ); $r = Absence::select($qq = [ \Query::SELECT => [ 'COUNT(*) as cc', DAbsence::$CODE, DAbsence::$NAME, Absence::$EMP, Absence::$ABSENCE, Emp::$NAME, Emp::$ID, Emp::$ARCHIVE, ], \Query::TABLES => [Absence::$table_name], \Query::LEFT_JOINS => [ [Emp::$table_name, Emp::$ID, Absence::$EMP], [DAbsence::$table_name, Absence::$ABSENCE, DAbsence::$ID], ], \Query::WHERE => \Where::_and($absence_and), \Query::GROUP_BY => [ Absence::$EMP, Absence::$ABSENCE, ], ]); $res['qq'] = (string)new \Query($qq); while ($l = \DB::fetch($r)) { $emp_id = $l[Emp::$ID]; $res['absence'][$emp_id]['archive'] = boolval($l[Emp::$ARCHIVE]); $res['absence'][$emp_id]['name'] = $l[Emp::$NAME]; $res['absence'][$emp_id]['id'] = $l[Emp::$ID]; $res['absence'][$emp_id]['total'] += intval($l['cc']); $res['absence'][$emp_id]['a'][] = [ 'code' => $l[DAbsence::$CODE], 'name' => $l[DAbsence::$NAME], 'count' => intval($l['cc']), ]; } $res['absence'] = array_values($res['absence']); } $age = $res['stat']['age']; $work = $res['stat']['work']; $res['stat']['age'] = $age ? number_format(array_sum($age) / count($age),1) : 0; $res['stat']['work'] = $work ? number_format(array_sum($work) / count($work) / 365,1) : 0; $res['filter_text'] = implode(", ",$filter_text); $res['stat']['ssch'] = ($res['stat']['begin'] + $res['stat']['end']) / 2; $res['stat']['flow'] = round($res['stat']['ssch'] ? $res['stat']['archive']/$res['stat']['ssch'] * 100 : 0); self::generateFilterOptions($res); return $res; } static function generateFilterOptions(&$res){ $res['options']['staffing'] = [['id'=>0,'title'=>'Не выбрано']]; $r = Staffing::select([ \Query::WHERE => new \Where(\Where::_and([ \Where::_operator(Staffing::$VIS,'=',1) ])), \Query::SORT=>[Staffing::$NAME=>'ASC'] ]); while($l = \DB::fetch($r)){ $res['options']['staffing'][] = [ 'id'=>intval($l[Staffing::$ID]), 'title'=>Staffing::getName($l), ]; } $res['options']['type'] = array_merge([0=>'Не выбрано'],eEmpType::getNameList()); $res['options']['group'] = array_merge([['id'=>0,'title'=>'Не выбрано']],eEmpGroup::getNameList()); $res['options']['city'] = array_merge([0=>'Не выбрано'],City::getNameList()); $res['options']['org'] = array_merge([0=>'Не выбрано'],Org::getNameList()); $res['options']['orgtype'] = array_merge([0=>'Не выбрано'],OrgType::getNameList()); $res['options']['department'] = [['id'=>0,'title'=>'Вся компания']]; $a = Department::getNameList(); foreach ($a as $k=>$v){ $res['options']['department'][] = [ 'id'=>intval($k), 'title'=>$v, ]; } } static function getEmpWhereAnd($begin,$end){ return \Where::_and([ \Where::_or([ \Where::_operator(Emp::$DATE_HIRE,'<=',$end), // \Where::_operatorForce(Emp::$DATE_HIRE,' is ','NULL'), \Where::_and([ \Where::_operatorForce(Emp::$DATE_HIRE,' is ','NULL'), \Where::_operator(Emp::$ARCHIVE_DATE,'>=',$begin), ]), \Where::_and([ \Where::_operatorForce(Emp::$DATE_HIRE,' is ','NULL'), \Where::_operatorForce(Emp::$ARCHIVE_DATE,' is ','NULL'), ]), ]), \Where::_or([ \Where::_operator(Emp::$ARCHIVE_DATE,'>=',$begin), \Where::_operatorForce(Emp::$ARCHIVE_DATE,' is ','NULL'), ]), ]); } static function getStat($filter){ $res = []; $emp_id = (intval($filter['emp_id']) ? : Emp::$AUTH_ID); $type = intval($filter['type']); $subtype = ($filter['subtype']); $project = ($filter['project']); if($project==[0]) $project = 0; if($type==1){ if($subtype) { $project = intval($subtype); } } $begin = (($filter['range'][0]=='0000-00-00')?null:$filter['range'][0]); $end = (($filter['range'][1]=='0000-00-00')?null:$filter['range'][1]); // $archive = boolval($filter['archive']) ? 1 : 0; $and = []; $project_and = []; $time_and = []; $and[] = \Where::_operator(Project::$REMOVED,'=',0); //if(isset($filter['archive'])) { $and[] = \Where::_operator(Project::$ARCHIVE, '=', $archive); } $project_and[] = \Where::_or([ \Where::_operator(Project::$DATE,"<=",$end), \Where::_operatorForce(Project::$DATE," is ",'null'), ]); $project_and[] = \Where::_or([ \Where::_operator(Project::$ARCHIVE_DATE,">=",$begin), \Where::_operatorForce(Project::$ARCHIVE_DATE," is ",'null'), ]); $project_and_all = $project_and; if($project) { if(is_array($project)){ $project_and[] = \Where::_in(Project::$ID, $project); } else { $project_and[] = \Where::_operator(Project::$ID, '=', $project); } } if($begin) $time_and[] = \Where::_between(self::$DATE,$begin,$end); $absence_and = [ \Where::_operator(Absence::$ABSENCE,'<>',0) ]; if($begin) $absence_and[] = \Where::_between(Absence::$DATE,$begin,$end); /* $projects_ids = []; $list = Project::getList(Emp::$AUTH_ID); foreach ($list as $v){ $projects_ids[] = $v[Project::$ID]; } if($projects_ids){ $and[] = \Where::_in(Project::$ID,$projects_ids); } */ $emp_and = self::getEmpWhereAnd($begin,$end); /* $emp_and = \Where::_and([ \Where::_or([ \Where::_operator(Emp::$DATE_HIRE,'<=',$end), // \Where::_operatorForce(Emp::$DATE_HIRE,' is ','NULL'), \Where::_and([ \Where::_operatorForce(Emp::$DATE_HIRE,' is ','NULL'), \Where::_operator(Emp::$ARCHIVE_DATE,'>=',$begin), ]), \Where::_and([ \Where::_operatorForce(Emp::$DATE_HIRE,' is ','NULL'), \Where::_operatorForce(Emp::$ARCHIVE_DATE,' is ','NULL'), ]), ]), \Where::_or([ \Where::_operator(Emp::$ARCHIVE_DATE,'>=',$begin), \Where::_operatorForce(Emp::$ARCHIVE_DATE,' is ','NULL'), ]), ]); */ if(in_array($type,[1])){ $project_and[] = $emp_and; } Merakomis::addLog('Prepare STAT'); $project_name = ''; $res['projects_list'] = []; // 0. По проектам // 1. По моей команде // 2. По подразделениям switch ($type){ case 0: $res = self::getProjectStat($project_and,$and,$time_and,$absence_and,$emp_id); //$projects_list = Project::getListFormatted($emp_id,$archive); $res['projects_list'] = Project::getListFormatted($emp_id); break; case 1: $res = self::getTeamStat($project_and, $and, $time_and, $absence_and, $begin, $end,$project_and_all); if($_POST['directors']){ foreach ($_POST['directors'] as $v){ $project_name.= ', '.Emp::getName(Emp::getByID(intval($v))); } } else { $project_name.=', все РП'; } if($_POST['steps']){ foreach ($_POST['steps'] as $v){ $project_name.= ', '.Step::getName(Step::getByID(intval($v))); } } else { $project_name.=', все стадии'; } /* if(Emp::isViewAll() || Emp::isAdmin() || Emp::isMeTopManager() || Emp::isMeGroup(eEmpGroup::GENERAL) || Emp::isMeGroup(eEmpGroup::ALL) ) { $res['projects_list'] = Project::getListFormatted(0); } else { $res['projects_list'] = Project::getMyDirectedFormatted($emp_id); } */ //$arr = Project::getListForAnalysis(); $arr = Project::getListForSummary(); foreach ($arr as $v) { if(($v[Project::$DATE] && $v[Project::$DATE]>$end && $v[Project::$DATE]!='0000-00-000') || ($v[Project::$ARCHIVE_DATE] && $v[Project::$ARCHIVE_DATE]<$begin && $v[Project::$ARCHIVE_DATE]!='0000-00-000') ) continue; $res['projects_list'][] = Project::format($v); } uasort($res['projects_list'],function($a,$b){ return $a['code']<=>$b['code']; }); $res['projects_list'] = array_values($res['projects_list']); $res['directors'] = [-1=>['id'=>-1,'title'=>'Все РП']]; foreach ($res['projects_list'] as $v){ $res['directors'][$v['director_id']] = [ 'id'=>$v['director_id'], 'title'=>$v['director'], ]; } $res['steps'] = [0=>['id'=>0,'title'=>'Все стадии']]; $a = Step::getNameList(); foreach ($a as $k=>$v){ $res['steps'][intval($k)] = ['id'=>intval($k),'title'=>$v]; } $res['directors'] = array_values($res['directors']); break; /* case 2: if($name = trim($_POST['name'])){ $project_and[] = \Where::_operator(Emp::$NAME,'LIKE','%'.$name.'%'); } $res = self::getDepartmentStat($project_and,$and,$time_and,$absence_and,$begin,$end,$emp_and); break; */ /* case 3: case 4: case 5: case 6: $group_id = 0; switch ($type) { case 3: $group_id = eEmpGroup::OFFICE_MOSCOW; break; case 4: $group_id = eEmpGroup::OFFICE_IVANOVO; break; case 5: $group_id = eEmpGroup::OFFICE_NOVOSIBORSK; break; case 6: $group_id = eEmpGroup::OFFICE_KRASNODAR; break; } if($name = trim($_POST['name'])){ $project_and[] = \Where::_operator(Emp::$NAME,'LIKE','%'.$name.'%'); } $project_and[] = \Where::_inQuery(Emp::$CITY,[ \Query::TABLES => [City::$table_name], \Query::SELECT => [City::$ID], \Query::WHERE =>\Where::_operator(City::$GROUP,'=',$group_id), ]); $res = self::getCompanyStat($project_and,$and,$time_and,$absence_and,$begin,$end,$emp_and,$type); $res['title']=eEmpGroup::getCityName($group_id); $res['subtitle']=eEmpGroup::getCitySubtitle($group_id); //$res = self::getDepartmentStat($project_and,$and,$time_and,$absence_and); break; break; */ case 3: case 4: case 5: case 6: case 10: case 2: // Моё подразделение case 7: // Моя компания $res = self::getCompanyStat($project_and,$and,$time_and,$absence_and,$begin,$end,$emp_and,$type); break; case 8: // Мои проекты: годовой отчёт $res = self::getProjectYearStat(intval($_POST['year'])); break; case 9: // Мои кадры $res = self::getStaff($emp_and,$absence_and,$begin,$end,$filter['filter']); break; case 11: // Мои кадры $res = self::getFot($emp_and,$begin,$end,$filter['filter']); break; case 12: // Мои кадры $res = self::getAllProjects($emp_and,$begin,$end,$filter['filter']); break; } Merakomis::addLog('after STAT'); if($project) { if(is_array($project)){ $projects = Project::getByIDS($project); $name = []; foreach ($projects as $v){ $name[] = Project::getCode($v); } $res['project_name'] = implode(", ",$name); } else { $res['project_name'] = Project::getName(Project::getByID(intval($project))); } $res['projects_list'] = null; } else { $res['project_name'] = 'Все проекты'; } $res['project_name'].=$project_name; $res['period'] = $begin?(Merakomis::fdate($begin).' - '.Merakomis::fdate($end)):'Всё время'; foreach ($res['projects_list'] as $k=>$v){ $res['projects_list'][$k]['title'] = $res['projects_list'][$k]['code_title']; } $res['requestId'] = $_POST['requestId']; Merakomis::addLog('Finish'); $res['logs'] = Merakomis::$LOGS; $res['range'] = [$begin,$end]; return $res; } static function cal_days_in_month($calendar, $month, $year) { // Поддерживаем только григорианский календарь (CAL_GREGORIAN) if ($calendar !== CAL_GREGORIAN) { // Можно добавить другие календари при необходимости return false; } // Проверка диапазона месяцев if ($month < 1 || $month > 12) { return false; } // Определяем количество дней в месяце return (int)date('t', mktime(0, 0, 0, $month, 1, $year)); } static function getAllProjects($emp_and,$begin,$end,$filter){ $data = []; $dirIds = []; if($_POST['directors']){ foreach ($_POST['directors'] as $v){ $dirIds[] = intval($v); } } $stepIds = []; if($_POST['steps']){ foreach ($_POST['steps'] as $v){ $stepIds[] = intval($v); } } $REPORT_SECTIONS = ['АР'=>0, 'КР'=>0, 'ИОС'=>0, 'СПЕЦ'=>0, 'BIM-IT'=>0, 'УПР'=>0]; $REPORT_SECTIONS_NAMES = array_keys($REPORT_SECTIONS); $IS_ONLY_MY_DIRECTOR = false; if(!Rules::isAdmin() && !Rules::isGroupProjectViewer() && Emp::isMeAnyDirector()){ $IS_ONLY_MY_DIRECTOR = true; $dirIds = [Emp::$AUTH_ID]; } $r = Project::select([ \Query::WHERE=> new \Where(\Where::_and([ \Where::_operator(Project::$CODE,' NOT LIKE', "0%"), $dirIds?\Where::_in(Project::$DIRECTOR,$dirIds):null, $stepIds?\Where::_in(Project::$STEP,$stepIds):null, ])) ]); $pids = []; $teams = []; $allTotal = 0; $defDate = '2000-01-01'; while($l = \db::fetch($r)){ $pid = $l[Project::$ID]; $team = $l[Project::$TEAM]; $pids[] = $pid; $row = [ 'id'=>$pid, 'code' => $l[Project::$CODE], 'step' => (($c = intval($l[Project::$STEP])) ? Step::getName(Step::getByID($c)) : ''), 'title' => Project::getName($l), 'area' => cfloatval($l[Project::$AREA]), 'director' => $dir_id = intval($l[Project::$DIRECTOR]), 'director_name' => $dir_id?Emp::SurnameIO( Emp::getByID($dir_id) ):'', 'times'=>$REPORT_SECTIONS, 'total'=>0, 'ch'=>0, 'is_bad_area'=>trim($l[Project::$AREA])=='', 'archive'=>boolval($l[Project::$ARCHIVE]), 'xxx'=>[$l[Project::$DATE],$l[Project::$ARCHIVE_DATE]], 'range'=>[ $l[Project::$DATE] ? ($l[Project::$DATE]=='0000-00-00'?$defDate:$l[Project::$DATE]) : $defDate, $l[Project::$ARCHIVE_DATE] ? ($l[Project::$ARCHIVE_DATE]=='0000-00-00'?date('Y-m-d'):$l[Project::$ARCHIVE_DATE]) : date('Y-m-d'), ], ]; $teams[$team] = $pid; $data[$pid] = $row; } $teamIds = array_keys($teams); $times = []; $r = \Query::select($q = [ \Query::SELECT => [ 'SUM('.Time::$DURATION.') as cc', Time::$PROJECT, Time::$EMP, ], \Query::TABLES => [ Time::$table_name, ], \Query::GROUP_BY=>[ Time::$PROJECT, Time::$EMP, ], \Query::WHERE=> new \Where(\Where::_and([ \Where::_in(Time::$PROJECT,$pids), \Where::_operator(Time::$EMP,'<>',0), ])) ])->execute(); while($l = \DB::fetch($r)){ $times[$l[Time::$PROJECT]][$l[Time::$EMP]]['time'] = $l['cc']; } $r = Member::select([ \Query::WHERE=> new \Where(\Where::_and([ \Where::_in(Member::$TEAM,$teamIds), ])) ]); $sections = Section::getAll(); $sectionNames = []; foreach ($sections as $v){ $sectionNames[$v[Section::$ID]] = explode(":",Section::getFullName($v))[0]; } foreach ($r as $v){ $pid = $teams[$v[Member::$TEAM]]; $times[ $pid ][ $v[Member::$EMP] ]['section_id'] = $v[Member::$SECTION]; $times[ $pid ][ $v[Member::$EMP] ]['section_name'] = $sectionNames[$v[Member::$SECTION]]; } foreach ($times as $pid=>$a){ foreach($a as $emp_id=>$v){ $sectionName = $v['section_name']; $allTotal+=$v['time']; if(!isset($data[$pid]['times'][$sectionName])) continue; $data[$pid]['times'][$sectionName]+=$v['time']; $data[$pid]['total']+=$v['time']; } } foreach ($data as &$v){ $area = $v['area']; $total = $v['total']; $v['ch'] = number_format($v['area'] ? $total / $area : 0,2,".",''); } unset($v); // Получаем директоров $directors = []; $r = Emp::select([ \Query::WHERE => new \Where(\Where::_and([ $IS_ONLY_MY_DIRECTOR ? \Where::_operator(Emp::$ID,"=",Emp::$AUTH_ID) : \Where::_inQuery(Emp::$ID,[ \Query::TABLES => [Project::$table_name], \Query::SELECT => ["DISTINCT ".Project::$DIRECTOR], ]), ])), \Query::SORT => [Emp::$NAME=>'ASC'], ]); while($l = \DB::fetch($r)){ $directors[] = ['id'=>intval($l[Emp::$ID]),'title'=>Emp::surnameio($l),]; } // Получаем этапы $steps = []; $r = Step::select([ \Query::WHERE => new \Where(\Where::_and([ \Where::_inQuery(Step::$ID,[ \Query::TABLES => [Project::$table_name], \Query::SELECT => ["DISTINCT ".Project::$STEP], ]) ])), \Query::SORT => [Step::$NAME=>'ASC'], ]); while($l = \DB::fetch($r)){ $steps[] = ['id'=>intval($l[Step::$ID]),'title'=>Step::getName($l),]; } $res = [ 'data'=>array_values($data), '$sectionNames'=>$sectionNames, '$allTotal'=>$allTotal, 'directors'=>$directors, 'steps'=>$steps, ]; return $res; } static function getFot($emp_and,$begin,$end,$filter){ $beginMonth = date('Y-m',strtotime($begin)); $endMonth = date('Y-m',strtotime($end)); $res = [ 'data'=>[], 'periods'=>[], 'periods_info'=>[ 'max_fot'=>0, 'max_money'=>0, ], 'filter'=>$filter, 'filter_text'=>'', 'options'=>[ 'staffing'=>[], 'department'=>[], 'type'=>[], 'group'=>[], 'city'=>[], 'org'=>[], 'orgtype'=>[], ], ]; $hourPeriods = self::getPeriod($begin,$end); $beginTime = strtotime($begin); $endTime = strtotime($end); $bYear = date('Y',strtotime($begin)); $bMonth = intval(date('m',strtotime($begin))); $eYear = date('Y',strtotime($end)); $eMonth = intval(date('m',strtotime($end))); foreach ($hourPeriods as $v){ $yy = $v[0]; $mm = $v[1]; $dd = "01"; $days = self::cal_days_in_month(CAL_GREGORIAN, $mm, $yy); if($yy == $bYear and $mm == $bMonth){ $dd = date('d',$beginTime); } if($yy == $eYear and $mm == $eMonth){ $days = date('d',$endTime); } $bd = $yy.'-'.($mm<10?('0'):'').$mm.'-'.$dd; $ed = $yy.'-'.($mm<10?('0'):'').$mm.'-'.$days; $hours[] = $bd.'-'.$ed; $hours[$yy][$mm] = Day::getWorkHours($bd,$ed); } $res['$hours'] = $hours; $res['$hourPeriods'] = $hourPeriods; $filter_text = []; $emp_and = [$emp_and]; if($filter[$c ='name']) { $emp_and[] = \Where::_operator(Emp::$NAME,'LIKE','%'.$filter[$c].'%'); $filter_text[] = 'Имя: «'.$filter[$c].'»'; } if(is_numeric($filter[$c ='city']) and $filter[$c]>0) { $emp_and[] = \Where::_operator(Emp::$CITY,'=',intval($filter[$c])); $filter_text[] = City::getName( City::getByID($filter[$c]) ); } if(is_numeric($filter[$c ='org']) and $filter[$c]>0) { $emp_and[] = \Where::_operator(Emp::$ORG,'=',intval($filter[$c])); $filter_text[] = Org::getName( Org::getByID($filter[$c]) ); } if(is_numeric($filter[$c ='orgtype']) and $filter[$c]>0) { $emp_and[] = \Where::_operator(Emp::$ORG_TYPE,'=',intval($filter[$c])); $filter_text[] = OrgType::getName( OrgType::getByID($filter[$c]) ); } $structure = Department::getStructure(); if(is_numeric($filter[$c ='department']) and $filter[$c]>0) { $filterDepId = $filter[$c]; $dep_emp_ids = $structure['base'][$filterDepId]['emp_ids']; if($structure[$filterDepId]){ foreach ($structure[$filterDepId] as $v){ $dep_emp_ids = array_merge($dep_emp_ids,$structure['base'][$v]['emp_ids']?:[]); } } $emp_and[] = \Where::_in(Emp::$ID,$dep_emp_ids?:[0]); $filter_text[] = Department::getName( $structure['base'][$filter[$c]] ); } if(is_numeric($filter[$c ='staffing']) and $filter[$c]>0) { $emp_and[] = \Where::_operator(Emp::$STAFFING,'LIKE','%"'.$filter[$c].'"%') ; $filter_text[] = Staffing::getName( Staffing::getByID(intval($filter[$c])) );; } $totals = []; $periods_info = []; $periods = []; $graph = [ 'title'=>'', 'titles'=>[' ФОТ, млн ₽','Стоимость пр-я, млн ₽'], 'labels'=>[], 'datasets'=>[ [ 'borderColor'=>'#FB4F14',//Merakomis::getChartColor(6), 'data'=>[], ], [ 'borderColor'=>'#0D71BE', // Merakomis::getChartColor(6), 'data'=>[], ] ] ]; $and = [ \Where::_operator(Fot::$YM,'>=',$beginMonth), \Where::_operator(Fot::$YM,'<=',$endMonth), \Where::_and($emp_and), ]; $city = City::getAll(); $org = Org::getAll(); $orgType = OrgType::getAll(); $staffingArray = Staffing::getAll(); $structure = Department::getStructure(); $EMP_DEPS = []; foreach ($structure['base'] as $v){ foreach ($v['emp_ids'] as $emp_id){ $EMP_DEPS[$emp_id][] = $v['title']; } } $r = Fot::select($q = [ \Query::LEFT_JOINS => [ [Emp::$table_name,Emp::$ID,Fot::$EMP], ], \Query::WHERE=>new \Where(\Where::_and($and)), \Query::SORT=>[Fot::$YM=>'ASC'] ]); $res['qqq_emp'] = (string)new \Query($q); $beginYM = date('Y-m',strtotime($begin)); $endYM = date('Y-m',strtotime($end)); while($l = \DB::fetch($r)){ Fot::decrypt($l); $emp_id = intval($l[Fot::$EMP]); $year = intval($l[Fot::$YEAR]); $month = intval($l[Fot::$MONTH]); $month_key = ($month<10?'0'.$month:$month); $bb = $year.'-'.$month_key; $ee = $year.'-'.$month_key; $beginDay = '01'; $endDay = date('t',strtotime($end)); if($bb==$beginYM){ $beginDay = date('d',strtotime($begin)); } if($ee==$endYM){ $endDay = date('t',strtotime($end)); } $beginEmp = $bb.'-'.$beginDay; $endEmp = $ee.'-'.$endDay; $info = self::getEmpsTimeWithFot($beginEmp,$endEmp,$emp_id); $res['data'][$emp_id]['info'][] = $info; $per_hour = cfloatval( $l[Fot::$PER_HOUR]); $res['data'][$emp_id]['staffing'] = []; $res['data'][$emp_id]['department'] = implode(", ",$EMP_DEPS[$emp_id]); $res['data'][$emp_id]['name'] = Emp::SurnameIO( $l ) ; $res['data'][$emp_id]['archive'] = boolval($l[Emp::$ARCHIVE]); $res['data'][$emp_id]['city'] = City::getName( $city[intval($l[Emp::$CITY])] ) ; $res['data'][$emp_id]['org'] = Org::getName( $org[intval($l[Emp::$ORG])] ) ; $res['data'][$emp_id]['org_type'] = OrgType::getName( $orgType[intval($l[Emp::$ORG_TYPE])] ) ; $res['data'][$emp_id]['fot']['fzp'][] = $l[Fot::$FZP]; $res['data'][$emp_id]['fot']['fot'][] = $l[Fot::$FOT]; $res['data'][$emp_id]['fot']['add'][] = $l[Fot::$ADD]; $res['data'][$emp_id]['fot']['per_hour'][] = $l[Fot::$PER_HOUR]; //$res['data'][$emp_id]['total'] += $l[Fot::$FOT]; $res['data'][$emp_id]['money'] += $info['money']; $totals['avg']['fot'][] = $l[Fot::$FOT]; $totals['avg']['fzp'][] = $l[Fot::$FZP]; $totals['avg']['add'][] = $l[Fot::$ADD]; $totals['avg']['per_hour'][] = $l[Fot::$PER_HOUR]; //$totals['fot'] += $l[Fot::$FOT]; $perHourForMonth = $per_hour * $hours[$year][$month]; $res['data'][$emp_id]['total'] += $perHourForMonth; $totals['fot'] += $l[Fot::$FOT]; $totals['per_hour'] += $l[Fot::$PER_HOUR]; $totals['total'] += $perHourForMonth; $totals['money'] += $info['money']; //$res['data'][$emp_id]['total'] .= $l[Fot::$PER_HOUR] .'*'. $hours[$year][$month]; $periods[$year][$month_key]['fot'] += $l[Fot::$FOT]; $periods[$year][$month_key]['total'] += $perHourForMonth; foreach ($info['money_period'] as $y=>$months){ foreach ($months as $m=>$vals){ $periods[$y][$m]['money'] += $vals['total']; } } $staffing_ids = json_decode($l[Emp::$STAFFING],true); if($staffing_ids){ //$staffs = Staffing::getByIDS($staffing_ids); foreach ($staffing_ids as $staff_id){ $res['data'][$emp_id]['staffing'][]= Staffing::getName($staffingArray[$staff_id]); } } $res['data'][$emp_id]['staffing'] = implode(", ",$res['data'][$emp_id]['staffing']); } foreach ($periods as $y=>$months){ foreach ($months as $m=>$vals){ $periods[$y][$m]['fot'] = $xx = Time::convertMoney($vals['total'],['round'=>3]); $periods[$y][$m]['money'] = $yy = Time::convertMoney($vals['money'],['round'=>3]); $periods_info['max_fot'] = $periods_info['max_fot'] ? max($periods_info['max_fot'], $xx) : $xx; $periods_info['max_money'] = $periods_info['max_money'] ? max($periods_info['max_money'], $yy) : $yy; $graph['labels'][] = $m.'.'.$y; $graph['datasets'][0]['data'][] = $xx; $graph['datasets'][1]['data'][] = $yy; } } $res['periods'] = $periods; $res['periods_info'] = $periods_info; $keys = ['fot','add','per_hour','fzp']; foreach ($res['data'] as $k=>&$v){ foreach($keys as $key) { $v['avg'][$key] = round(array_sum($v['fot'][$key]) / count($v['fot'][$key]), 2); $totals['avg'][$key][] = $v['avg'][$key]; } } unset($v); foreach ($res['data'] as $emp_id=>&$emp){ $emp['avg']['fzp'] = Merakomis::fprice($emp['avg']['fzp'] ,['currency'=>false]); $emp['avg']['fot'] = Merakomis::fprice($emp['avg']['fot'] ,['currency'=>false]); $emp['avg']['add'] = Merakomis::fprice($emp['avg']['add'] ,['currency'=>false]); $emp['avg']['per_hour'] = Merakomis::fprice($emp['avg']['per_hour'],['currency'=>false,'round'=>2]); $emp['total'] = Merakomis::fprice($emp['total'] ,['currency'=>false]); $emp['money'] = Merakomis::fprice($emp['money'] ,['currency'=>false]); } foreach ($totals['avg'] as $k=>$v){ $totals['avg'][$k] = Merakomis::fprice(round(array_sum($v) / count($v), 2),['currency'=>false,'round'=>$k=='per_hour'?2:0]); } $months_count= 0; foreach ($periods as $y=>$months){ $months_count+=count($months); } $totals['fot'] = Merakomis::fprice($totals['fot']/$months_count,['currency'=>false]); $totals['per_hour'] = Merakomis::fprice($totals['per_hour']/$months_count,['currency'=>false,'round'=>2]); $totals['total'] = Merakomis::fprice($totals['total'],['currency'=>false]); $totals['money'] = Merakomis::fprice($totals['money'],['currency'=>false]); //$res['data'][$emp_id]['total'] = Merakomis::fprice($res['data'][$emp_id]['total'],['currency'=>false]); //$res['data'][$emp_id]['money'] = Merakomis::fprice($res['data'][$emp_id]['money'],['currency'=>false]); $res['graph'] = $graph; $res['totals'] = $totals; $res['filter_text'] = implode(", ",$filter_text); $res['$months_count'] = $months_count; self::generateFilterOptions($res); //$res['q'] = new \Query($q).''; return $res; } static function getFormInputs(\ModuleBZ\Form &$form, array $data, $C, bool $isEdit) { $form ->addInput((new Hidden())->setName(self::$PROJECT)->setValue( intval($C[self::$PROJECT]?:$data['project']) )) ->addInput((new Hidden())->setName(self::$EMP)->setValue( intval($C[self::$EMP]?:($data['emp']?:Emp::$AUTH_ID)) )) ->addRow((new Row()) ->addColumn(((new DatePicker()) ->setName(self::$DATE) ->setValue($C[self::$DATE]) ->setClassAll('c-1-3') ->setLabel($c = V::get(Vars::$DATE)) ->setPlaceholder($c) )) ->addColumn(((new Text()) ->setName(self::$DURATION) ->setValue(cfloatval($C[self::$DURATION])) ->setClassAll('c-1-3') ->setLabel($c = V::get(Vars::$DURATION)) ->setPlaceholder($c) ->setLabel($c) )) ->addColumn(((new Switcher()) ->setName(self::$IS_OVER) ->setClassAll('c-1-3') ->setPlaceholder($c = V::get(Vars::$IS_OVER)) ->setLabel($c) ->setChecked(boolval($C[self::$IS_OVER])) )) ) ; } static function columnInfo() : array { return [ new C([ C::VAR_NAME =>&self::$ID, C::TYPE =>eColumnType::INT, C::AUTO_INCREMENT =>true, C::PRIMARY =>true, C::DEFAULT =>0, C::HIDDEN =>true, C::TH =>V::get(Vars::$ID), ]), new C([ C::VAR_NAME => &self::$EMP, C::TYPE => eColumnType::INT, C::DEFAULT => intval(Emp::$AUTH_ID), c::HIDDEN => true, ]), new C([ C::VAR_NAME => &self::$DATE, C::TYPE => eColumnType::DATE, C::TH => V::get(Vars::$DATE), C::FILTER_TYPE => eFilterType::DATE, C::FUNC_VALUE_DATA => function($v){ return Merakomis::fdate($v[self::$DATE]); } ]), new C([ C::VAR_NAME => &self::$DURATION, C::TYPE => eColumnType::DOUBLE, C::LENGTH => '10,2', C::TH => V::get(Vars::$DURATION), //c::HIDDEN => true, ]), new C([ C::VAR_NAME => &self::$IS_OVER, C::TYPE => eColumnType::TINYINT, C::TH => V::get(Vars::$IS_OVER), C::DEFAULT => 0, C::FUNC_VALUE_DATA => function($v){ return Merakomis::fbool($v[self::$IS_OVER]); } ]), new C([ C::VAR_NAME => &self::$PROJECT, C::TYPE => eColumnType::INT, c::HIDDEN => true, ]), new C([ C::VAR_NAME => &self::$PORTAL, C::TYPE => eColumnType::INT, C::DEFAULT => intval(\Site::$portal_id), c::HIDDEN => true, ]), new C([ C::VAR_NAME => &self::$ACCOUNT, C::TYPE => eColumnType::INT, C::DEFAULT => intval(\Site::$owner_id), //C::TH => V::get(Vars::$ACCOUNT), c::HIDDEN => true, ]), ]; } } new Time(); Time::init(); /// controller.php