meraproject/themes/merakomis/emp/model.php1
keboss-m 5c21d25d45 Initial commit: Merakomis portal, Docker stack and user-reader API.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-24 11:04:05 +03:00

2251 lines
89 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?
namespace themes\merakomis;
use common\Image;
use core\columns\structure\eFilterType;
use core\db\structure\Column as C;
use core\db\structure\eColumnType;
use ModuleBZ\Form\Input\DatePicker;
use ModuleBZ\Form\Input\ImagePicker;
use ModuleBZ\Form\Input\Password;
use ModuleBZ\Form\Input\Radio;
use ModuleBZ\Form\Input\Select;
use ModuleBZ\Form\Input\Submit;
use ModuleBZ\Form\Input\Switcher;
use ModuleBZ\Form\Input\Text;
use ModuleBZ\Form\Input\Textarea;
use ModuleBZ\Layout\Column;
use ModuleBZ\Layout\Row;
use ModuleBZ\Layout\Title;
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\F;
use themes\Merakomis;
use themes\merakomis\dictionary\City;
use themes\merakomis\dictionary\Department;
use themes\merakomis\dictionary\EmpStatus;
use themes\merakomis\dictionary\Org;
use themes\merakomis\dictionary\OrgType;
use themes\merakomis\dictionary\Staffing;
use themes\merakomis\emp\Group;
use themes\merakomis\emp\Rules;
use themes\merakomis\Emp\structure\eEmpGroup;
use themes\merakomis\Emp\structure\eEmpType;
use themes\merakomis\input\Children as InputChildren;
use themes\merakomis\structure\merakomisModuleTable;
use themes\merakomis\team\Member;
use themes\merakomis\time\Absence;
use themes\vhl\school\Staff;
use ui\form\structure\eInputType;
use ui\Form;
use ui\input\Input;
use core\lang\structure\LangVariable as V;
use ms\ms\structure\msModuleTable;
use themes\merakomis\emp\structure\tMerakomisEmpLang as Vars;
use \themes\merakomis\emp\Children;
use \themes\merakomis\dictionary\Absence as DAbsence;
class Emp extends merakomisModuleTable {
static $self;
static $cache = [];
static $table_name = 'tMerakomisEmp';
static $controller = 'themes.merakomis.emp';
static $ID = 'id';
static $NAME = 'name';
static $LOGIN = 'login';
static $EMAIL = 'email';
static $PASSWORD = 'pass';
static $TYPE = 'type';
static $ARCHIVE = 'archive';
static $ACTIVE = 'active';
static $ACCEPT = 'accept';
static $PORTAL = 'portal';
static $ACCOUNT = 'account';
static $CREATED = 'created';
static $UPDATED = 'updated';
static $IMAGE = 'image';
static $DATE_HIRE = 'date_hire';
static $BIRTHDATE = 'birthdate';
static $CITY = 'city';
static $PHONE = 'phone';
static $SKYPE = 'skype';
static $IS_FREELANCER = 'is_freelancer';
static $STAFFING = 'staffing';
static $DESCRIPTION = 'description';
static $ORG = 'org';
static $ORG_TYPE = 'org_type';
static $EDUCATION = 'education';
static $DIPLOMA = 'diploma';
static $DIPLOMA_DATE = 'diploma_date';
static $DIPLOMA_POST = 'diploma_post';
static $NOPRIZ = 'nopriz_text';
static $NOSTROI = 'nostroi_text';
static $TECHNADZOR = 'technadzor_text';
static $STATUS = 'status';
static $COMMENT = 'comment';
static $REMOVED = 'removed';
static $ARCHIVE_DATE = 'archive_date';
static $DISCORD = 'discrod';
static $SEX = 'sex';
static $SALARY = 'salary';
static $HAS_CHILDREN = 'has_children';
static $TG_ACC = 'tg_acc';
//--
static $FOT = 'fot';
static $ROLES = 'roles';
static $GROUP = 'group';
static $ABSENCE = 'absence';
static $DEP_SEP = '→';
/*
static $IS_SUPER_ADMIN = true;
static $IS_AUTH = true;
static $AUTH_ID = 2;
/*/
static $IS_SUPER_ADMIN = false;//true;
static $IS_AUTH = false;//true;
static $AUTH_ID = null;//2;
/**/
//--
static $CACHE;
static $cookieIDKey = 'fg_emp_id';
static $cookieHashKey = 'fg_emp_h';
static $data = null;
static function getTgCode(){
$key = (time());
return self::getTgStartHash($key,self::$data);
}
static function getTgStartHash($key,$data){
return $key.'-'.self::$data[self::$ID].'-'.self::getTgHash($key,$data);
}
static function getTgHash($key,$data){
return md5($key.SALT.$data[self::$ID].$key);
}
static function getTgStartLink(){
return Telegram::getStartLink(self::getTgCode());
}
static function getAuthCode($emp,$key){
$xx = md5($key.$emp[Emp::$LOGIN].SALT);
$xx = preg_replace('/[^\d]/','',$xx);
return substr($xx,0,5);
}
static function sendAuthCode($emp,$key){
if(is_numeric($emp)) $emp = self::getByID(intval($emp));
$code = self::getAuthCode($emp,$key);
file_put_contents(__DIR__.'/log.txt',je($emp)."\n\n");
//return Telegram::send($emp[Emp::$TG_ACC],"Ваш код для авторизации ```".$code.'```');
return Telegram::send($emp[Emp::$TG_ACC],"Ваш код для авторизации **".$code.'**');
}
static function getTitle(){return V::get(Vars::$MODULE_NAME);}
static function getSystemLangValues():array{ return Vars::getArray(); }
public function _update(\Where $w, array $values) {
$values[self::$UPDATED] = time();
if($values[self::$DATE_HIRE]=='0000-00-00') unset($values[self::$DATE_HIRE]);
if($values[self::$BIRTHDATE]=='0000-00-00') unset($values[self::$BIRTHDATE]);
if($values[self::$DIPLOMA_DATE]=='0000-00-00') unset($values[self::$DIPLOMA_DATE]);
return parent::_update($w, $values);
}
public function _insert(array $values, array $options = array()) {
if($values[self::$DATE_HIRE]=='0000-00-00') unset($values[self::$DATE_HIRE]);
if($values[self::$BIRTHDATE]=='0000-00-00') unset($values[self::$BIRTHDATE]);
if($values[self::$DIPLOMA_DATE]=='0000-00-00') unset($values[self::$DIPLOMA_DATE]);
$res = parent::_insert($values, $options); // TODO: Change the autogenerated stub
Project::checkAllProjectsForAllEmps();
self::generateFot($res->id,$values);
return $res;
}
static public function generateFot($id,$values)
{
if(isset($values[self::$SALARY]) && $values[self::$SALARY]) {
//$time = strtotime($values[self::$DATE_HIRE]);
$time = time();
$month = intval(date('m',$time));
$year = date('Y',$time);
$salary = cfloatval($values[self::$SALARY]);
$data = [
Fot::$YEAR=>$year,
Fot::$MONTH=>$month,
Fot::$EMP=>$id,
Fot::$FZP=>$salary,
];
$fot = Fot::getForEmp($id,$year,$month);
if($fot){
Fot::updateById($fot[Fot::$ID],$data);
} else {
Fot::insert($data);
}
Fot::generate($year,$month);
}
}
public function _updateById(int $id, array $values) {
$C = self::getByID($id);
if(isset($values[self::$ARCHIVE])) {
if (!$values[self::$ARCHIVE] and $C[self::$ARCHIVE]) {
$values[self::$STATUS] = 0;
}
}
$res = parent::_updateById($id, $values); // TODO: Change the autogenerated stub
self::generateFot($id,$values);
return $res;
}
static function getWorkDays($emp){
if($emp[Emp::$DATE_HIRE]=='0000-00-00') return 0;
if(!$emp[Emp::$DATE_HIRE]) return 0;
$date1 = new \DateTime($emp[Emp::$DATE_HIRE]);
$date2 = new \DateTime(date('Y-m-d'));
$interval = $date1->diff($date2);
return $interval->days;
}
static function getWorkPeriod($emp){
if($emp[Emp::$DATE_HIRE]=='0000-00-00') return '';
if(!$emp[Emp::$DATE_HIRE]) return '';
$date1 = new \DateTime($emp[Emp::$DATE_HIRE]);
$date2 = new \DateTime(date('Y-m-d'));
$interval = $date1->diff($date2);
$res = [];
$res[] = (($c = $interval->y)<10?'0':'').$c;
$res[] = (($c = $interval->m)<10?'0':'').$c;
$res[] = (($c = $interval->d)<10?'0':'').$c;
return implode("-",$res);
}
static function getAge($emp){
if($emp[Emp::$BIRTHDATE]=='0000-00-00') return '';
if(!$emp[Emp::$BIRTHDATE]) return '';
$date1 = new \DateTime($emp[Emp::$BIRTHDATE]);
$date2 = new \DateTime(date('Y-m-d'));
$interval = $date1->diff($date2);
$res = [];
if($c = $interval->y) $res[] = $c;
return implode(" ",$res);
}
static function getBirthday(){
$res = [
'date'=>date('d.m.Y'),
'dates'=>[],
];
if(Emp::$IS_AUTH) {
$r = Emp::select([
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(Emp::$BIRTHDATE,'LIKE','%'.date('-m-d')),
\Where::_operator(Emp::$ARCHIVE,'=','0'),
]))
]);
while($l = \DB::fetch($r)){
$emp_id = intval($l[Emp::$ID]);
$staffing_names = [];
$staffing = json_decode($l[Emp::$STAFFING],true)?:[];
foreach ($staffing as $staf_id){
$staffing_names[] = Staffing::getName( Staffing::getByID(intval($staf_id)) );
}
$department_names = [];
$r2 = Post::select([
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(Post::$EMP, '=',$emp_id)
]))
]);
while ($l2 = \DB::fetch($r2)) {
$department_names[] = Department::getName( Department::getByID( intval($l2[Post::$DEPARTMENT]) ) );
}
$res['dates'][] = [
'name'=>Emp::getName($l),
'text' =>implode(", ",array_merge($staffing_names,$department_names)),
//'roles'=>implode(", ",$staffing_names),
//'departments'=>implode(", ",$department_names),
];
}
}
return $res;
}
static function formatMyTopData(){
$img = '/pics/icon-user.svg';
if($img_id = intval(self::$data[self::$IMAGE])) {
$img = Image::imageResize(Image::getByID($img_id)[Image::$URL],100,100,90,['crop'=>'center']);
}
return [
'id'=>self::$data[self::$ID],
'name'=>self::$data[self::$NAME],
'is_superview'=>Emp::isSuperView(),
'avatar'=>$img,
'telegram'=> Emp::checkTelegram(),
];
}
static function isMeAccept(){
return boolval(self::$data[self::$ACCEPT]);
}
static function getPublicData($emp_id){
$emp = Emp::getByID($emp_id);
$data = Emp::format($emp);
$tr = [];
$tr['Имя'] = $data['name'] ;
$tr['Email'] = $data['email'] ;
$tr['Телефон'] = $data['phone'] ;
$tr['Skype'] = $data['skype'] ;
$tr['Discord'] = $data['discord'] ;
$tr['Штатное расписание'] = implode($data['staffing'],"\n") ;
$tr['Подразделение'] = implode($data['roles'],"\n") ;
$tr['Локация'] = $data['city'] ;
//$a = Project::getListFormatted($emp_id, $_POST['archive'], $_POST['active']);
$a = Project::getListFormatted($emp_id, 0, 1);
$projects = [];
foreach ($a as $k=>$v){
$projects[] = $v['code_title'];
}
$children = [];
$arr = Children::getForEmp($emp_id);
foreach ($arr as $child){
$children[] = $child[Children::$NAME].' ['.Merakomis::fdate($child[Children::$DATE]).']';
}
if(Rules::isRwCardEmpStaff($emp_id)){
$tr['Дата рождения'] = $data['birthday'];
$tr['Юр. лицо'] = $data['org'];
$tr['Вид сотрудничества'] = $data['org_type'];
$tr['Дата приёма на работу'] = $data['hire'];
$tr['Статус'] = $data['status'];
$tr['Удалённая работа'] = $data['is_freelance'] ? 'Да' : 'Нет';
$tr['Архивный'] = $data['archive'] ? 'Да' : 'Нет';
$tr['ВУЗ'] = $data['education'];
$tr['Диплом №'] = $data['diploma'];
$tr['Специальность по диплому'] = $data['diploma_post'];
$tr['Дата выдачи диплома'] = $data['diploma_date'];
$tr['Дети'] = implode("\n",$children);
$tr['НОПРИЗ'] = $data['nopriz'];
$tr['НОСТРОЙ'] = $data['nostroi'];
$tr['Технадзор'] = $data['technadzor'];
$tr['Дополнительная информация'] = $emp[Emp::$COMMENT];
}
if(Rules::isRwCardEmpAdmin($emp_id)){
$arr = Group::get($emp_id);
$groups = [];
foreach ($arr as $group){
$groups[] = eEmpGroup::getName($group);
}
$tr['ЗП (ross)'] = $emp[Emp::$SALARY];
$tr['Тип'] = eEmpType::getName($emp[Emp::$TYPE]);
$tr['Группы'] = implode("\n",$groups);
$tr['Дополнительная информация (администратор)'] = $emp[Emp::$DESCRIPTION];
$tr['Активен'] = $emp[Emp::$ACTIVE] ? 'Да' : 'Нет';
$tr['Подтвержден'] = $emp[Emp::$ACCEPT] ? 'Да' : 'Нет';
$tr['Телеграм'] = $emp[Emp::$TG_ACC] ? 'Закреплен' : 'Не закреплен';
}
if(Rules::isRwCardEmpActiveProjects($emp_id)){
$tr['Активные проекты'] = implode($projects,"\n");
}
return [
'data' => $data,
'form' => $emp_id ? Emp::getMyProfileForm() : null,
'form2'=> $emp_id ? Emp::getMyProfileFormPassword() : null,
'tr' => $tr,
];
}
static function SurnameIO($v){
$res = [];
$a = explode(" ",trim($v[self::$NAME]));
$res[] = $a[0];
if($a[1]) $res[] = substr1251($a[1],0,1).'.';
if($a[2]) $res[] = substr1251($a[2],0,1).'.';
return implode(" ",$res);
}
static function format($v,$isFull = true){
$roles = [];
if($isFull) {
$a = self::getRoles($v[self::$ID]);
$s = Department::getStructure();
$roles = [];
$sep = '→';
$i = 1;
foreach ($a as $role){
$deps = [];
foreach ($role['path'] as $dep_id){
$deps[] = Department::getName($s['base'][$dep_id]);
}
$roles[] = ($i++).'. '.implode(" $sep ",$deps);//." $sep ".Post::getName($role);
}
}
$staffing = [];
$ids = json_decode($v[self::$STAFFING],true);
if($ids){
$a = Staffing::getByIDS($ids);
foreach ($a as $vv){
$staffing[] = Staffing::getName($vv);
}
}
$id = intval($v[Emp::$ID]);
return [
'id' => $id,
'name' => Emp::getName($v),
'login' => $v[self::$LOGIN],
'email' => self::getEmail($v),
'birthday' => Merakomis::fdate($v[self::$BIRTHDATE]),
'hire' => Merakomis::fdate($v[self::$DATE_HIRE]),
'city' => $v[self::$CITY]?City::getName( City::getByID(intval($v[self::$CITY]))):'',
'is_freelance' => boolval($v[self::$IS_FREELANCER]),
'roles' => $roles,
'staffing' => $staffing,
'avatar' => Image::format($v[self::$IMAGE]),
'org' => Org::getName(Org::getByID(intval($v[self::$ORG]))),
'org_type' => OrgType::getName(OrgType::getByID(intval($v[self::$ORG_TYPE]))),
'education' => $v[self::$EDUCATION],
'diploma' => $v[self::$DIPLOMA],
'diploma_date' => Merakomis::fdate($v[self::$DIPLOMA_DATE]),
'diploma_post' => $v[self::$DIPLOMA_POST],
'nopriz' => trim($v[self::$NOPRIZ]),
'nostroi' => trim($v[self::$NOSTROI]),
'technadzor' => trim($v[self::$TECHNADZOR]),
'status' => EmpStatus::getName(EmpStatus::getByID(intval($v[self::$STATUS]))),
'phone' => trim($v[self::$PHONE]),
'skype' => trim($v[self::$SKYPE]),
'discord' => trim($v[self::$DISCORD]),
'archive' => boolval($v[self::$ARCHIVE]),
'is_admin' => Emp::isAdmin(),
'is_superview' => Emp::isSuperView(),
'is_any_director' => Emp::isMeAnyDirector(),
'is_view_analysis_project' => Emp::isViewAnalysisProject(),
'is_any_role_director' => Emp::isMeAnyRoleDirector(),
'groups' => Group::get($id),
'download_link' => '/api/themes.merakomis.download/emp/?id='.$id,
];
}
static function init(){
if(Merakomis::$IS_TEST){
self::$IS_AUTH = true;
self::$AUTH_ID = 3;
self::$data = Emp::getByID(self::$AUTH_ID);
} else {
self::$IS_AUTH = self::if_auth();
self::$AUTH_ID = intval(self::$data[self::$ID]);
}
//self::$IS_AUTH = true;
//self::$AUTH_ID = 1;
}
public function _deleteByIDS(array $ids) {
foreach ($ids as $id){
self::updateById($id,[
self::$REMOVED => 1,
]);
}
// return $res;
}
static function if_auth(){
if($uid = intval($_COOKIE[ self::$cookieIDKey ]) and $hash = $_COOKIE[ self::$cookieHashKey ]) {
$acc = self::getByID($uid);
$res = ( strcmp($acc[self::$PASSWORD],$hash)==0
&& boolval($acc[self::$ACTIVE])
&& !boolval($acc[self::$ARCHIVE])
&& !boolval($acc[self::$REMOVED])
)
;
if($res) self::$data = $acc;
if($uid==352) {
echo '<pre>';
echo var_dump($res);
echo '</pre>';
}
return $res;
} else return false;
}
static function prepareLogin($login) {return trim(strtolower((string)$login));}
static function preparePass($pass) {return trim((string)$pass);}
static function getByLogin(string $email){
return \DB::fetch(self::select( [
\Query::WHERE => new \Where (\Where::_and([
\Where::_operator(self::$LOGIN,'=',$email),
//\Where::_operator(self::$PORTAL,'=',\Site::$portal_id),
]))
]
));
}
static function accept($id){
self::updateById($id,[
self::$ACCEPT=>1,
]);
}
static function getAcceptHash($emp){
return md5(md5(SALT.SALT.$emp[self::$LOGIN].SALT).SALT);
}
static function getAcceptLink($emp){
return \Site::sectionUrl(Merakomis::PAGE_ACCEPT.'/?id='.$emp[self::$ID].'&hash='.self::getAcceptHash($emp),true);
}
static function sendAccept($emp){
if(!$_COOKIE['wait_send']){
self::sendEmail($emp,"Кликните <a href='".self::getAcceptLink($emp)."'>ссылку</a> для подтверждения email",'Подтверждение email');
\Core::setCookie('wait_send',1,time()+60,null);
}
}
static function sendEmail($emp,$html,$subject=''){
$res = Merakomis::mail(
$emp[self::$LOGIN],
$emp[self::$NAME],
$html,$subject
);
return $res;
}
static function checkPassword($acc,$pass):bool{
$hash = $acc[self::$PASSWORD];
$acc[self::$PASSWORD] = $pass;
self::hash($acc);
return strcmp($hash, self::hash($acc) )===0;
}
static function exit(){
History::exit(Emp::$AUTH_ID);
\Core::setCookie(self::$cookieIDKey,'-');
\Core::setCookie(self::$cookieHashKey,'-');
}
static function updateMyPass($acc,$pass){
$acc[self::$PASSWORD] = $pass;
$c = [self::$PASSWORD => self::hash($acc) ];
self::updateById($acc[self::$ID], $c);
\Core::setCookie(self::$cookieIDKey,$acc[self::$ID]);
\Core::setCookie(self::$cookieHashKey,$c[self::$PASSWORD]);
}
static function reg($login,$pass1,$pass2){
$res = ['e'=>0];
// 1 - Такого нет в списке
// 2 - Уже есть
$err = '';
if($pass1!=$pass2){
$err = 'Пароли не совпадают';
}
if(!$err){
$acc = self::getByLogin($login);
// Если такой уже зарегистрирован
if($acc[Emp::$PASSWORD]!=''){
$res['e'] = 2;
} else {
if($acc){
$id = $acc[self::$ID];
$r = Emp::updateById($id,[
Emp::$TYPE=>eEmpType::EMP,
Emp::$PASSWORD=>$pass1,
]);
$C = Emp::getByID($id);
$C[Emp::$PASSWORD] = $pass1;
$hash = Emp::hash($C);
$r = Emp::updateById($id,[Emp::$PASSWORD=>$hash]);
\Core::setCookie(self::$cookieIDKey,$id);
\Core::setCookie(self::$cookieHashKey,$hash);
$res['e'] = 0;
History::reg($r->id);
self::sendAccept($C);
} else {
// Такого в списках нет
$res['e'] = 1;
}
}
}
$res['m'] = $err;
return $res;
}
static function login($login,$pass){
$res = [];
$res['e'] = false;
$login = self::prepareLogin($login);
$pass = self::preparePass($pass);
$acc = self::getByLogin($login);
if($acc) {
if(self::checkPassword($acc,$pass)){
$isAuth = true;
if($acc[Emp::$TG_ACC]){
$isAuth = false;
if($key = $_POST['key']){
$code1 = $_POST['code'];
$code2 = Emp::getAuthCode($acc,$key);
if($code1==$code2){
$isAuth = true;
} else {
$res['e'] = 4;
History::login_bad($acc[Emp::$ID]);
}
} else {
$res['key'] = $key = time();
$res['e'] = 3;
Emp::sendAuthCode($acc, $key);
}
}
if($isAuth) {
self::$data = $acc;
self::$IS_AUTH = true;
\Core::setCookie(self::$cookieIDKey, $acc[self::$ID]);
\Core::setCookie(self::$cookieHashKey, $acc[self::$PASSWORD]);
History::login($acc[Emp::$ID]);
}
} else {
$res['e'] = 2;
History::login_bad($acc[Emp::$ID]);
}
} else {
$res['e'] = 1;
}
return $res;
}
static function hash($acc){return md5(\Config::$SALT.$acc[self::$ID].\Config::$SALT.\Config::$SALT.$acc[self::$PASSWORD]); }
static function remind($acc){return md5(\Config::$SALT.$acc[self::$ID].\Config::$SALT.\Config::$SALT.$acc[self::$PASSWORD]); }
static function getRemindHash($key,$emp) {return md5($key.SALT.$emp[\Profile::$PASSWORD].SALT.$key); }
static function checkRemind($emp_id,$key,$hash){
$res = null;
$emp_id = intval($emp_id);
$emp = self::getByID($emp_id);
$key = intval($key);
$hash2 = static::getRemindHash($key,$emp);
if($key + 60*60*24 < time()){
$res = 'В целях безопасности время на смену пароля ограничено и действие подтверждающих данных уже истекло. Начните восстановление пароля заново.';
} else if(strcmp($hash,$hash2)!=0) {
$res = 'Неверные подтверждающие коды.';
}
return $res;
}
static function getRemindLink($emp){
$key = time();
$id = $emp[self::$ID];
$hash = static::getRemindHash($key,$emp);
return \Site::sectionUrl('new_pass/'.$id.'/'.$key.'/'.$hash.'/', true);
}
static function getMyProfileFormPassword(){
$data = self::$data;
$form = (new \ModuleBZ\Form())
->addRow((new Row())
->addColumn(((new Password())
->setName('old')
->setClassAll('c-1-3')
->setLabel($c = 'Старый пароль')
->setPlaceholder($c )
))
->addColumn(((new Password())
->setName('pass1')
->setClassAll('c-1-3')
->setLabel($c = 'Новый пароль')
->setPlaceholder($c )
))
->addColumn(((new Password())
->setName('pass2')
->setClassAll('c-1-3')
->setLabel($c = 'Новый пароль')
->setPlaceholder($c )
))
)
->addRow((new Row())
->addColumn(((new Submit())
->setName('save')
->setValue('1')
->setPlaceholder('Сохранить')
->setClassName('green')
->setClassAll('c-100')
))
)
;
return $form->toJSON();
}
static function getMyProfileForm(){
$data = self::$data;
$form = (new \ModuleBZ\Form())
->addRow((new Row())
/*
->addColumn(((new Text())
->setName(self::$NAME)
->setValue($data[self::$NAME])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$NAME))
->setPlaceholder($c )
->setDisabled(true)
))
->addColumn(((new Text())
->setName(self::$LOGIN)
->setValue($data[self::$LOGIN])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$LOGIN))
->setPlaceholder($c )
->setDisabled(true)
))
*/
->addColumn(((new Text())
->setName(self::$PHONE)
->setValue($data[self::$PHONE])
->setClassAll('c-1-3')
->setLabel($c = V::get(Vars::$PHONE))
->setPlaceholder($c )
// ->setMask('+7 (999) 999-99-99')
))
->addColumn(((new Text())
->setName(self::$SKYPE)
->setValue($data[self::$SKYPE])
->setClassAll('c-1-3')
->setLabel($c = V::get(Vars::$SKYPE))
))
->addColumn(((new Text())
->setName(self::$DISCORD)
->setValue($data[self::$DISCORD])
->setClassAll('c-1-3')
->setLabel($c = V::get(Vars::$DISCORD))
))
)
->addRow((new Row())
->addColumn(((new Submit())
->setName('save')
->setValue('1')
->setPlaceholder('Сохранить')
->setClassName('green')
->setClassAll('c-100')
))
)
;
return $form->toJSON();
}
static $my_groups;
static function isMeGroup($group_id){
$groups = (self::$my_groups ? : Group::get(self::$AUTH_ID));
return in_array($group_id,$groups);
}
static function isGroup($emp_id,$group_id){
$groups = (Group::get($emp_id));
return in_array($group_id,$groups);
}
static function isMeTopManager(){
return self::isMeGroup(eEmpGroup::TOP);
}
static function isMeAnyRoleDirector(){
$res = false;
$r = Post::select([
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(Post::$EMP,'=',Emp::$AUTH_ID),
\Where::_operator(Post::$IS_DIRECTOR,'=',1),
]))
],true);
foreach ($r as $role){
if($role[Post::$IS_DIRECTOR]){
$res = true;
}
}
return $res;
}
static function isMeAnyDirector(){
$res = false;
$r = Project::select([
\Query::WHERE => new \Where(\WHere::_and([
\Where::_operator(Project::$DIRECTOR,'=',self::$AUTH_ID),
\Where::_operator(Project::$REMOVED,'=',0),
])),
\Query::COUNT => 1,
]);
if(\DB::numRows($r)) $res = true;
return $res;
}
static function isViewAnalysisProject(){
$res = false;
$r = Member::select($qq = [
\Query::SELECT => ['COUNT(*) as cc'],
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(Member::$EMP,'=',Emp::$AUTH_ID),
\Where::_operator(Member::$ACTIVE,'=',1),
\Where::_in(Member::$ROLE,[
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,
]),
])),
\Query::COUNT,
]
);
$res = intval(\DB::fetch($r)['cc'])>0;
return $res;
}
static function isMeAnyDepartmentDirector(){
$res = false;
$r = Post::select([
\Query::WHERE => new \Where(\WHere::_and([
\Where::_operator(Post::$EMP,'=',self::$AUTH_ID),
\Where::_operator(Post::$IS_DIRECTOR,'=',1),
])),
\Query::COUNT => 1,
]);
if(\DB::numRows($r)) $res = true;
return $res;
}
static function isViewAll(){
return self::isMeGroup(eEmpGroup::ALL);
}
static function isAdmin(){
return Rules::isAdmin();
// return self::$data[self::$TYPE]==eEmpType::ADMIN;
}
static function isWorkInPeriod($emp,$begin,$end){
$isBegin = (($emp[self::$DATE_HIRE] && $begin && $emp[self::$DATE_HIRE]<=$begin) || !$emp[self::$DATE_HIRE]);
$isEnd = (($emp[self::$ARCHIVE_DATE] && $end && $emp[self::$ARCHIVE_DATE]>=$end) || !$emp[self::$ARCHIVE_DATE]);
return $isBegin || $isEnd;
}
static function checkTelegram(){
$res = false;
if(Emp::$IS_AUTH){
if(Emp::$data[Emp::$TG_ACC]){
$res = boolval(Emp::$data[Emp::$TG_ACC]);
} else {
if(self::isTelegram()) {
Telegram::getUpdates();
$data = Emp::getByID(intval(Emp::$AUTH_ID));
$res = boolval($data[Emp::$TG_ACC]);
}
}
}
return $res;
}
static function isTelegram($emp = null){
if(!$emp) $emp = self::$data;
$emp_id = $emp[Emp::$ID];
return Rules::isAdmin()
|| Emp::isMeAnyDirector()
|| Rules::isGroupFinanceEditor()
|| Rules::isGroupFinanceViewer()
|| Rules::isGroupProjectEditor()
|| Rules::isGroupProjectFinance()
|| Rules::isGroupStaff()
;
return (
self::isGroup($emp_id,eEmpGroup::GENERAL)
|| self::isGroup($emp_id,eEmpGroup::STAFF)
|| self::isGroup($emp_id,eEmpGroup::TOP)
|| $emp[self::$TYPE]==eEmpType::ADMIN
);
}
static function isSuperView(){
return in_array(self::$data[self::$TYPE],[
eEmpType::ADMIN,
self::isMeGroup(eEmpGroup::GENERAL)
//eEmpType::TOP,
//eEmpType::DIRECTOR,
]);
}
public static function afterUadd($values, $id, $result) {
parent::afterUadd($values, $id, $result);
$C = self::getByID($id);
if($values['password'] ){
// || (isset($values[self::$EMAIL]) and $C[self::$EMAIL]!=$values[self::$EMAIL])
$C[self::$PASSWORD] = $values['password'];
$hash = self::hash($C);
self::updateById($id,[self::$PASSWORD=>$hash]);
}
if(isset($values['staffing'])){
self::updateById($id,[self::$STAFFING=>je($values['staffing'])]);
}
if(isset($values[self::$EMAIL])){
self::updateById($id,[self::$LOGIN=>self::getEmail($values)]);
}
//if(isset($values['group'])){
Group::set($id,$values['group']);
//}
if(isset($values[self::$ARCHIVE])){
$C = self::getByID($id);
if($values[self::$ARCHIVE]) {
if (!$C[self::$ARCHIVE_DATE]) {
self::updateById($id, [self::$ARCHIVE_DATE => date('Y-m-d')]);
Merakomis::sendMailAdmin('Сотрудник '.Emp::getName($C).' был архивирован','Архивирование сотрудника');;
}
}
}
if(isset($values["has_children"])){
$hasChildren = intval($values["has_children"]);
self::updateById($id,[
self::$HAS_CHILDREN => $values["has_children"],
]);
$child_ids = [];
if($hasChildren) {
foreach ($values['children'] as $child) {
$data = [
Children::$NAME => $child['name'],
Children::$DATE => $child['date'],
Children::$EMP => $id,
];
if ($child['id']) {
$child_ids[] = $child['id'];
Children::updateById($child['id'], $data);
} else {
$r = Children::insert($data);
$child_ids[] = $r->id;
}
}
}
$x = Children::delete(new \Where(\Where::_and([
\Where::_operator(Children::$EMP,'=',$id),
$child_ids ? \Where::_not([
\Where::_in(Children::$ID,$child_ids)
]): null
])));
}
if(isset($values['posts'])){
$directors = [];
$r = Post::select([
\Query::WHERE => new \Where(\Where::_operator(Post::$EMP,'=',$id))
]);
while($l = \DB::fetch($r)){
$directors[$l[Post::$DEPARTMENT]] = $l[Post::$IS_DIRECTOR];
}
Post::delete(new \Where(\Where::_operator(Post::$EMP,'=',$id)));
foreach ($values['posts'] as $post_id){
Post::insert([
Post::$EMP=>$id,
Post::$DEPARTMENT=>$post_id,
Post::$IS_DIRECTOR=>intval($directors[$post_id]),
]);
}
self::updateById($id,[
self::$STAFFING=>je($values['staffing']),
]);
}
if(isset($values['remove_tg'])){
if($values['remove_tg']){
self::updateById($id,[
self::$TG_ACC=>0,
]);
}
}
self::generateFot($id,$values);
}
static function getIdsForSubEmps($pid){
$s = Department::getStructure();
$res = $s[$pid];
foreach($s[$pid] as $id){
if($s[$id]){
$res = array_merge($res,self::getIdsForSubEmps($id));
}
}
return $res;
}
static function getSubEmps($emp_id){
$res = [];
$s = Department::getStructure();
$roles = self::getRoles($emp_id);
$dep_ids = [];
foreach ($roles as $role){
if($role[Post::$IS_DIRECTOR]) {
$p = $role['path'];
$id = array_pop($p);
$dep_ids = array_merge($dep_ids,self::getIdsForSubEmps($id));
$dep_ids[] = $id;
}
}
$x = ['directors','employees'];
foreach ($dep_ids as $dep_id){
$d = $s['base'][$dep_id];
foreach ($x as $type) {
foreach ($d[$type] as $role) {
//foreach ($empList['roles'] as $role) {
if ($role['emp']['id']) {
$res[] = intval($role['emp']['id']);
}
//}
}
}
}
$res = array_unique($res);
return $res;
}
static $CACHED_ROLES = [];
static function getRolesCached($_emp_id){
if(self::$CACHED_ROLES[$_emp_id]) return self::$CACHED_ROLES[$_emp_id];
$res = [];
$posts = Post::getAll();
foreach ($posts as $k=>$v){
$emp_id = intval($v[Post::$EMP]);
$dep_id = $v[Post::$DEPARTMENT];
$path = Department::getPath($dep_id);
$res[$emp_id][$k]['path'] = $path;
}
self::$CACHED_ROLES = $res;
return $res[$_emp_id];
}
static function getMemberRoles($emp_id){
$emp_id = intval($emp_id);
$res = [];
$r = Member::select([
\Query::SELECT => ['DISTINCT '.Member::$ROLE],
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(Member::$EMP,'=',$emp_id),
\Where::_operator(Member::$ACTIVE,'=',1),
]))
],false);
while($l = \DB::fetch($r)){
$res[] = $l[Member::$ROLE];
}
return $res;
}
static function getRoles($emp_id){
$key = 'getRoles'.$emp_id;
if(self::$CACHE[$key]) return self::$CACHE[$key];
$emp_id = intval($emp_id);
$res = Post::select([
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(Post::$EMP,'=',$emp_id)
]))
],true);
foreach ($res as $k=>$v){
$dep_id = $v[Post::$DEPARTMENT];
$path = Department::getPath($dep_id);
$res[$k]['path'] = $path;
}
return self::$CACHE[$key] = $res;
}
static function getEmail($v){
return ($v[self::$EMAIL] ? $v[self::$EMAIL].'@merakom.ru' : '' );
}
public static function beforeUadd(array $values = []): array {
$res = [];
if($c = $values[self::$EMAIL]){
if(strpos($c,'@')!==false){
$res[self::$EMAIL][] = 'Нельзя ввести имейл расположенный на отличных от домена @merakom.ru. Введите значение до @merakom.ru';
}
}
return $res;
}
public static function getFormInputs(\ModuleBZ\Form &$form, array $data, $C, bool $isEdit) {
$s = Department::getStructure();
$img = null;
if($c = $C[self::$IMAGE]) $img = Image::imageResize( Image::getByID($c)[Image::$URL], 128);
$a = Staffing::select([
\Query::SORT => [Staffing::$NAME=>'ASC']
]);
$staffing = json_decode($C[self::$STAFFING],true)?:[];
$staffing_list = [];
foreach ($a as $v){
$staffing_id = intval($v[Staffing::$ID]);
if(in_array($staffing_id,$staffing) || $v[Staffing::$VIS]){
$staffing_list[] = ['id'=>$staffing_id,'title'=>$v[Staffing::$NAME]];
//$staffing_list[] = ['id'=>$staffing_id,'title'=>je($v)];
}
}
$posts = [];
$post_list = [];//Post::getNameList();
$a = Post::getAll();
$s = Department::getStructure();
foreach ($s['base'] as $dep){
$title = [];
$dep_id = $dep[Department::$ID];
$deps = Department::getPath($dep_id);
foreach ($deps as $did){
$title[] = Department::getName($s['base'][$did]);
}
//$title[] = Post::getName($v);
$post_list[] = [
//'id'=>$v[Post::$ID],
'id'=>$dep_id,
'title'=>implode(" ".self::$DEP_SEP." ",$title),
];
}
if($C) {
$r = Post::select([
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(Post::$EMP, '=',$C[Emp::$ID])
]))
]);
while ($l = \DB::fetch($r)) {
$posts[] = $l[Post::$DEPARTMENT];
}
}
$children = [];
if($isEdit) {
$a = Children::getForEmp($C[Emp::$ID]);
foreach ($a as $v){
$children[] = [
'id'=>intval($v[Children::$ID]),
'name'=>$v[Children::$NAME],
'date'=>$v[Children::$DATE],
];
}
}
$row = ((new Row())
->addColumn(
(new Column())->setClassAll('c-20 ')
->addRow((new Row())
->addColumn((new Column())->setClassAll('c-100 green_title')->addTitle((new Title('Основная информация'))))
->addColumn((new ImagePicker())
->setClassAll('c-50')
->setName(self::$IMAGE)
->setLabel(V::get(Vars::$IMAGE))
->setUploadUrl(\Site::sectionUrl(substr(Image::UPLOAD_URL_ACCOUNT,1),true))
->setAjaxData(['token'=>Merakomis::getUploadToken()])
->setSrc($img?:'')
->setValue($C[self::$IMAGE])
->setAsBg(true)
->setClassName('btn blue')
)
->addColumn(((new Radio())
->setName(self::$SEX)
->setValue($C[self::$SEX])
->setClassAll('c-50')
->setLabel($c = V::get(Vars::$SEX))
->setOptions([
['id'=>-1,'title'=>'Женский'],
['id'=>1,'title'=>'Мужской'],
])
->setPlaceholder($c)
))
->addColumn(((new Text())
->setName(self::$NAME)
->setValue($C[self::$NAME])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$NAME))
->setPlaceholder($c)
))
->addColumn(((new DatePicker())
->setName(self::$BIRTHDATE)
->setValue($C[self::$BIRTHDATE]?:null)
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$BIRTHDATE))
->setPlaceholder($c))
)
->addColumn(((new Text())
->setName(self::$EMAIL)
->setValue($C[self::$EMAIL])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$EMAIL).'. Значение до @merakom.ru')
->setPlaceholder($c)
))
->addColumn(((new Text())
->setName(self::$PHONE)
->setValue($C[self::$PHONE])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$PHONE))
->setPlaceholder($c)
// ->setMask('+7 (999) 999-99-99')
))
->addColumn(((new Text())
->setName(self::$SKYPE)
->setValue($C[self::$SKYPE])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$SKYPE))
->setPlaceholder($c)
))
->addColumn(((new Text())
->setName(self::$DISCORD)
->setValue($C[self::$DISCORD])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$DISCORD))
->setPlaceholder($c)
))
)
)
->addColumn(
(new Column())->setClassAll('c-60 ')
->addRow((new Row())
->addColumn((new Column())->setClassAll('c-100 green_title')->addTitle((new Title('Кадры'))))
->addColumn(
(new Column())->setClassAll('c-1-3')->addTitle((new Title('Трудоустройство')))
->addRow((new Row())
->addColumn(((new Select())
->setName('staffing')
->setValue($staffing)
->setClassAll('c-100')
->setLabel(V::get(Vars::$STAFFING))
->setPlaceholder(V::get(Vars::$STAFFING))
->setOptions($staffing_list)
->setMultiple(true)
->setSearch(true)
))
->addColumn(((new Select())
->setName('posts')
->setValue($posts)
->setClassAll('c-100')
->setLabel(V::get(Vars::$ROLES))
->setPlaceholder(V::get(Vars::$ROLES))
->setOptions($post_list)
->setMultiple(true)
->setSearch(true)
))
->addColumn(((new Select())
->setName(self::$CITY)
->setValue(intval($C[self::$CITY]))
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$CITY))
->setPlaceholder($c)
->setOptions(City::getNameList([
'zero'=>true,
\Query::WHERE => new \Where(\Where::_or([
\Where::_operator(City::$VIS,'=',1),
$isEdit ? \Where::_operator(City::$ID,'=',intval($C[self::$CITY])) : null,
]))
]))
->setSearch(true)
))
->addColumn(((new Select())
->setName(self::$ORG)
->setValue(intval($C[self::$ORG]))
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$ORG))
->setPlaceholder($c)
->setOptions(Org::getNameList([
'zero'=>true,
\Query::WHERE => new \Where(\Where::_or([
\Where::_operator(Org::$VIS,'=',1),
$isEdit ? \Where::_operator(Org::$ID,'=',intval($C[self::$ORG])) : null,
]))
]))
))
->addColumn(((new Select())
->setName(self::$ORG_TYPE)
->setValue(intval($C[self::$ORG_TYPE]))
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$ORG_TYPE))
->setPlaceholder($c)
->setOptions(OrgType::getNameList([
'zero'=>true,
\Query::WHERE => new \Where(\Where::_or([
\Where::_operator(OrgType::$VIS,'=',1),
$isEdit ? \Where::_operator(OrgType::$ID,'=',intval($C[self::$ORG_TYPE])) : null,
]))
]))
))
->addColumn(((new DatePicker())
->setName(self::$DATE_HIRE)
->setValue($C[self::$DATE_HIRE]?:null)
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$DATE_HIRE))
->setPlaceholder($c))
)
->addColumn(((new Select())
->setName(self::$STATUS)
->setValue(intval($C[self::$STATUS]))
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$STATUS))
->setPlaceholder($c)
->setOptions(EmpStatus::getNameList([
'zero'=>true,
\Query::WHERE => new \Where(\Where::_or([
\Where::_operator(EmpStatus::$VIS,'=',1),
$isEdit ? \Where::_operator(EmpStatus::$ID,'=',intval($C[self::$STATUS])) : null,
]))
]))
))
->addColumn(((new Text())
->setName(self::$SALARY)
//->setValue($C[self::$SALARY])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$SALARY))
->setPlaceholder($c)
))
->addColumn(((new Switcher())
->setName(self::$IS_FREELANCER)
->setClassAll('c c-50 green_switcher')
->setPlaceholder(V::get(Vars::$IS_FREELANCER))
->setChecked(boolval($C[self::$IS_FREELANCER]))
))
->addColumn(((new Switcher())
->setName(self::$ARCHIVE)
->setClassAll('c c-50 orange_switcher')
->setPlaceholder(V::get(Vars::$ARCHIVE))
->setChecked(boolval($C[self::$ARCHIVE]))
))
)
)
->addColumn(
(new Column())->setClassAll('c-1-3')->addTitle((new Title('Образование')))
->addRow((new Row())
->addColumn(((new Text())
->setName(self::$EDUCATION)
->setValue($C[self::$EDUCATION])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$EDUCATION))
->setPlaceholder($c)
))
->addColumn(((new Text())
->setName(self::$DIPLOMA)
->setValue($C[self::$DIPLOMA])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$DIPLOMA))
->setPlaceholder($c)
))
->addColumn(((new Text())
->setName(self::$DIPLOMA_POST)
->setValue($C[self::$DIPLOMA_POST])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$DIPLOMA_POST))
->setPlaceholder($c)
))
->addColumn(((new DatePicker())
->setName(self::$DIPLOMA_DATE)
->setValue($C[self::$DIPLOMA_DATE]?:null)
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$DIPLOMA_DATE))
->setPlaceholder($c)
))
->addColumn((new Column())->setClassAll('c-100')->addTitle((new Title('Дети'))))
->addColumn(((new Switcher())
->setName('has_children')
->setChecked(boolval($C[self::$HAS_CHILDREN]))
->setClassAll('c-100 green_switcher')
//->setLabel($c = V::get(Vars::$HAS_CHILDREN))
->setPlaceholder('Есть дети')
))
->addColumn(((new InputChildren())
->setName('children')
->setValue($children)
->setClassAll('c-100')
//->setLabel($c = 'Дети')
->setPlaceholder($c)
->setVisible($isEdit ? boolval($C[self::$HAS_CHILDREN]) : true)
))
)
)
->addColumn(
(new Column())->setClassAll('c-1-3')->addTitle((new Title('Аттестация')))
->addRow((new Row())
->addColumn(((new Text())
->setName(self::$NOPRIZ)
->setValue($C[self::$NOPRIZ])
->setClassAll('c-100')
->setPlaceholder($c = V::get(Vars::$NOPRIZ))
->setLabel($c)
//->setChecked(boolval($C[self::$NOPRIZ]))
))
->addColumn(((new Text())
->setName(self::$NOSTROI)
->setValue($C[self::$NOSTROI])
->setClassAll('c-100')
->setPlaceholder($c = V::get(Vars::$NOSTROI))
->setLabel($c)
//->setChecked(boolval($C[self::$NOSTROI]))
))
->addColumn(((new Text())
->setName(self::$TECHNADZOR)
->setValue($C[self::$TECHNADZOR])
->setClassAll('c-100 ')
->setPlaceholder($c = V::get(Vars::$TECHNADZOR))
->setLabel($c)
//->setChecked(boolval($C[self::$TECHNADZOR]))
))
->addColumn(((new Textarea())
->setName(self::$COMMENT)
->setValue($C[self::$COMMENT])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$COMMENT))
->setPlaceholder($c)
->setAutoHeight(true)
))
)
)
)
)
);
//if(Emp::isSuperView()) {
if(Emp::isAdmin()) {
$row2 = (new Row())
->addColumn(((new Text())
->setName('password')
// ->setValue($C[self::$PASS])
->setClassAll('c-100')
->setLabel(V::get(Vars::$PASS) . ' (вводить, только если новый)')
->setPlaceholder(V::get(Vars::$PASS))
))
->addColumn(((new Select())
->setName(self::$TYPE)
->setValue(intval($C[self::$TYPE])?:($isEdit?0:eEmpType::EMP))
->setClassAll('c-100')
->setLabel(V::get(Vars::$TYPE))
->setPlaceholder(V::get(Vars::$TYPE))
->setOptions(eEmpType::getNameList())
))
->addColumn(((new Select())
->setName('group')
->setValue($isEdit ? Group::get($C[self::$ID]) : [])
->setClassAll('c-100')
->setLabel($c = 'Группы')
->setPlaceholder($c)
->setOptions(eEmpGroup::getNameList())
->setMultiple(true)
))
->addColumn(((new Textarea())
->setName(self::$DESCRIPTION)
->setValue($C[self::$DESCRIPTION])
->setClassAll('c-100')
->setLabel($c = V::get(Vars::$DESCRIPTION))
->setPlaceholder($c)
->setAutoHeight(true)
))
->addColumn(((new Switcher())
->setName(self::$ACTIVE)
->setClassAll('c c-100 green_switcher')
->setPlaceholder(V::get(Vars::$ACTIVE))
->setChecked(boolval($C[self::$ACTIVE]))
))
->addColumn(((new Switcher())
->setName(self::$ACCEPT)
->setClassAll('c c-100 green_switcher')
->setPlaceholder(V::get(Vars::$ACCEPT))
->setChecked(boolval($C[self::$ACCEPT]))
));
if($C[self::$TG_ACC]){
$row2
->addColumn(((new Switcher())
->setName('remove_tg')
->setClassAll('c c-100 green_switcher')
->setPlaceholder('Открепить телеграм аккаунт')
->setChecked(false)
));
}
$row->addColumn(
(new Column())->setClassAll('c-20')
->addRow((new Row())
->addColumn((new Column())->setClassAll('c-100 green_title')->addTitle((new Title('Администрирование'))))
->addColumn(
(new Column())->setClassAll('c-100')->addTitle((new Title('Доступ')))
->addRow($row2)
)
)
)
;
} else if(Rules::isGroupStaff()){
$row2 = (new Row())
->addColumn(((new Switcher())
->setName(self::$ACTIVE)
->setClassAll('c c-100 green_switcher')
->setPlaceholder(V::get(Vars::$ACTIVE))
->setChecked(boolval($C[self::$ACTIVE]))
));
$row->addColumn(
(new Column())->setClassAll('c-20')
->addRow((new Row())
->addColumn((new Column())->setClassAll('c-100 green_title')->addTitle((new Title('Администрирование'))))
->addColumn(
(new Column())->setClassAll('c-100')->addTitle((new Title('Доступ')))
->addRow($row2)
)
)
)
;
}
$form->addRow($row);
}
static $absences_today;
static function getAbsencesToday(){
if(isset(self::$absences_today)) return self::$absences_today;
$a = Absence::select([
\Query::LEFT_JOINS => [
[DAbsence::$table_name,DAbsence::$ID,Absence::$ABSENCE],
],
\Query::WHERE => new \Where(\Where::_and([
\Where::_operator(Absence::$DATE,'=',date('Y-m-d')),
]
))],true);
self::$absences_today = [];
foreach ($a as $v){
self::$absences_today[$v[Absence::$EMP]] = $v;
}
return self::$absences_today;
}
static function getSexName($v){
return $v[self::$SEX]==1 ? 'Мужской' : ($v[self::$SEX]==-1?'Женский':'-');
}
static function getStaffingList($v){
$a = Staffing::getAllCache();
$ids = json_decode($v[self::$STAFFING],true);
$res = [];
foreach ($ids as $id){
$res[] = Staffing::getName($a[$id]);
}
return $res;
}
static function getDepartmentList($v){
//$roles = self::getRoles($v[self::$ID]);
$roles = self::getRolesCached($v[self::$ID]);
$s = Department::getStructure();
$res = [];
$sep = '→';
$i = 1;
foreach ($roles as $role){
$deps = [];
/*
foreach ($role['path'] as $dep_id){
$deps[] = Department::getName($s['base'][$dep_id]);
}
$res[] = ($i++).'. '.implode(" $sep ",$deps);
*/
$dep_id = array_pop($role['path']);
$deps[] = Department::getName($s['base'][$dep_id]);
$res[] = implode(" $sep ",$deps);
}
return $res;
//return implode("\n",$res);
}
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::$IMAGE,
C::TYPE => eColumnType::INT,
C::DEFAULT => 0,
//C::TH => V::get(Vars::$IMAGE),
C::EXPORT => false,
C::TH => ' ',
C::HIDDEN => !boolval($_POST['data']['my_company']),
C::FUNC_VALUE_DATA => function($v){
$img_id = intval($v[self::$IMAGE]);
$img = $img_id ? Image::getByID(intval($v[self::$IMAGE])) : null;
return je([
'img'=>$img_id,
'avatar'=>$img ? Image::imageResize($img[Image::$URL],100,100,90,['crop'=>'center']) : null,
'image' =>$img ? Image::imageResize($img[Image::$URL],200,0) : null,
]);
}
]),
new C([
C::VAR_NAME => &self::$ARCHIVE,
C::TYPE => eColumnType::TINYINT,
C::LENGTH => 1,
C::DEFAULT => 0,
C::COL_DEFAULT => 0,
C::FILTER_TYPE => eFilterType::BOOLEAN,
//C::TH => ' ',//V::get(Vars::$ARCHIVE),
C::TH => V::get(Vars::$ARCHIVE),
//C::HIDDEN => true,
C::TH_CLASS => 'hide',
C::TD_CLASS => 'hide',
C::FUNC_VALUE_DATA => function($v){
return Merakomis::boolString($v[self::$ARCHIVE]);
}
]),
new C([
C::VAR_NAME => &self::$ABSENCE,
C::TYPE => eColumnType::NONE,
C::TH => ' ',
C::HIDDEN => true,
C::EXPORT => false,
C::FUNC_VALUE_DATA => function($v){
$a = self::getAbsencesToday()[$v[self::$ID]];
return [
'name'=>$a ? $a[DAbsence::$NAME] : '',
];
},
// C::HIDDEN => !boolval($_POST['data']['my_company']),
]),
new C([
C::VAR_NAME => &self::$NAME,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => 1023,
C::TH => V::get(Vars::$NAME),
C::FILTER_TYPE => eFilterType::TEXT,
C::FUNC_VALUE => function($v){
return $v[self::$NAME];
},
C::FUNC_EXPORT_DATA => function($v){
return $v[self::$NAME];
},
C::FUNC_VALUE_DATA => function($v){
/*
if($_POST['data']['my_company']) {
return $v[self::$ID];
}
*/
$a = self::getAbsencesToday()[$v[self::$ID]];
return [
'id'=>$v[self::$ID],
'name'=>$v[self::$NAME]?:"-",
'archive'=> intval($v[self::$ARCHIVE]),
'absence'=>$a ? $a[DAbsence::$NAME] : '',
];
}
]),
new C([
C::VAR_NAME => &self::$LOGIN,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => 127,
C::HIDDEN => true,
C::TH => V::get(Vars::$LOGIN),
]),
new C([
C::VAR_NAME => &self::$EMAIL,
C::TYPE => eColumnType::VARCHAR,
C::FILTER_TYPE => eFilterType::TEXT,
C::LENGTH => 127,
C::HIDDEN => true,
C::TH => V::get(Vars::$EMAIL),
C::FUNC_VALUE_DATA => function($v){
return self::getEmail($v);
}
]),
new C([
C::VAR_NAME => &self::$STAFFING,
C::TYPE => eColumnType::TEXT,
C::DEFAULT => '[]',
C::TD_CLASS => 'pre_wrap',
C::TH => V::get(Vars::$STAFFING),
C::FUNC_FILTER_QUERY => function($v){
return $v ? \Where::_operator(self::$STAFFING,'LIKE','%"'.$v.'"%') : null;
},
C::FUNC_VALUE_DATA => function($v){
return implode("\n",self::getStaffingList($v));
/*
$ids = json_decode($v[self::$STAFFING],true);
$res = [];
if($ids){
$a = Staffing::getByIDS($ids);
foreach ($a as $vv){
$res[] = Staffing::getName($vv);
}
}
return implode("\n",$res);
//return eEmpType::getName($v[self::$TYPE]);
*/
},
C::FILTER_TYPE => eFilterType::SELECT,
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return Staffing::getNameList(['zero'=>true]);
}
]),
new C([
C::VAR_NAME => &self::$ROLES,
C::TYPE => eColumnType::INT,
C::TH => V::get(Vars::$ROLES),
C::TD_CLASS => 'pre_wrap',
C::FILTER_TYPE => eFilterType::SELECT,
C::FUNC_FILTER_QUERY => function($v){
if(!$v) return null;
$s = Department::getStructure();
$recurse = function($now) use ($s){
global $recurse;
$res = $s[$now]?:[];
foreach ($res as $v){
if($s[$v]){
$res = array_merge($res,$recurse($v));
}
}
return $res;
};
//$ids = $s[$v]?:[];
//$ids[] = intval($v);
$ids = $recurse($v);
$ids[] = $v;
return \Where::_inQuery(self::$ID,[
\Query::TABLES => [Post::$table_name],
\Query::SELECT => [Post::$EMP],
//\Query::WHERE => new \Where(\Where::_operator(Post::$DEPARTMENT,'=',intval($v)))
\Query::WHERE => new \Where(\Where::_in(Post::$DEPARTMENT,$ids))
]);
},
C::FUNC_VALUE_DATA => function($v){
return implode("\n",self::getDepartmentList($v));
$roles = self::getRoles($v[self::$ID]);
$s = Department::getStructure();
$res = [];
$sep = '→';
$i = 1;
foreach ($roles as $role){
$deps = [];
/*
foreach ($role['path'] as $dep_id){
$deps[] = Department::getName($s['base'][$dep_id]);
}
$res[] = ($i++).'. '.implode(" $sep ",$deps);
*/
$dep_id = array_pop($role['path']);
$deps[] = Department::getName($s['base'][$dep_id]);
$res[] = implode(" $sep ",$deps);
}
return implode("\n",$res);
return '';
},
C::FUNC_FILTER_SELECT_OPTIONS => function(){
$res = [];
$s = Department::getStructure();
$sep = '→';
$i = 1;
foreach ($s['base'] as $dep_id => $dep){
$path = Department::getPath($dep_id);
$res[] = ['id'=>$dep_id,'title'=>Department::getName($dep)];
}
return $res;
//return eEmpType::getNameList();
}
]),
new C([
C::VAR_NAME => &self::$GROUP,
C::TYPE => eColumnType::NONE,
C::TH => V::get(Vars::$GROUP),
C::TD_CLASS => 'pre_wrap',
C::FILTER_TYPE => eFilterType::SELECT,
C::HIDDEN => true,
C::FUNC_FILTER_QUERY => function($v){
if(!$v) return null;
return \Where::_inQuery(self::$ID,[
\Query::TABLES => [Group::$table_name],
\Query::SELECT => [Group::$EMP],
\Query::WHERE => new \Where(\Where::_operator(Group::$GROUP,'=',intval($v)))
]);
},
C::FUNC_VALUE_DATA => function($v){
$ids = Group::get($v[self::$ID]);
if($ids){
$res = [];
foreach ($ids as $id){
$res[] = eEmpGroup::getName($id);
}
return implode(", ",$res);
}
return '';
},
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return eEmpGroup::getNameList();
}
]),
new C([
C::VAR_NAME => &self::$CITY,
C::TYPE => eColumnType::INT,
C::FILTER_TYPE => eFilterType::SELECT,
C::DEFAULT => 0,
C::TH => V::get(Vars::$CITY),
C::FUNC_VALUE_DATA => function($v){
return City::getName( City::getByIDCached(intval($v[self::$CITY])) );
},
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return City::getNameList();
},
]),
new C([
C::VAR_NAME => &self::$IS_FREELANCER,
C::TYPE => eColumnType::TINYINT,
C::FILTER_TYPE => eFilterType::BOOLEAN,
C::DEFAULT => 0,
// C::HIDDEN => true,
C::TH => V::get(Vars::$IS_FREELANCER),
//C::TH => 'Удалёнка',
C::FUNC_VALUE_DATA => function($v){
return Merakomis::fbool($v[self::$IS_FREELANCER]);
},
]),
new C([
C::VAR_NAME => &self::$ORG,
C::TYPE => eColumnType::TINYINT,
C::LENGTH => 1,
C::DEFAULT => 1,
C::TH => V::get(Vars::$ORG),
C::FILTER_TYPE => eFilterType::SELECT,
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return Org::getNameList();
},
C::FUNC_VALUE_DATA => function($v){
return Org::getName(Org::getByIDCached(intval($v[self::$ORG])));
},
]),
new C([
C::VAR_NAME => &self::$ORG_TYPE,
C::TYPE => eColumnType::TINYINT,
C::LENGTH => 1,
C::DEFAULT => 1,
//C::TH => V::get(Vars::$ORG_TYPE),
C::TH => 'Вид',
C::FILTER_TYPE => eFilterType::SELECT,
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return OrgType::getNameList();
},
C::FUNC_VALUE_DATA => function($v){
return OrgType::getName(OrgType::getByIDCached(intval($v[self::$ORG_TYPE])));
},
]),
new C([
C::VAR_NAME => &self::$DATE_HIRE,
C::TYPE => eColumnType::DATE,
C::NULL => true,
// C::HIDDEN => true,
C::TH => V::get(Vars::$DATE_HIRE),
C::FILTER_TYPE => eFilterType::DATE,
//C::FUNC_VALUE_DATA => function($v){return Merakomis::fdate($v[self::$DATE_HIRE]);},
]),
new C([
C::VAR_NAME => &self::$STATUS,
C::TYPE => eColumnType::TINYINT,
C::LENGTH => 1,
C::DEFAULT => '0',
C::TH => V::get(Vars::$STATUS),
C::FILTER_TYPE => eFilterType::SELECT,
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return EmpStatus::getNameList();
},
C::FUNC_VALUE_DATA => function($v){
return EmpStatus::getName(EmpStatus::getByIDCached(intval($v[self::$STATUS])));
},
]),
new C([
C::VAR_NAME => &self::$PASSWORD,
C::TYPE => eColumnType::VARCHAR,
C::LENGTH => 127,
C::TH => V::get(Vars::$PASS),
C::HIDDEN => true,
]),
new C([
C::VAR_NAME => &self::$TYPE,
C::TYPE => eColumnType::TINYINT,
C::DEFAULT => eEmpType::EMP,
C::TH => V::get(Vars::$TYPE),
C::HIDDEN => true,
C::FUNC_VALUE_DATA => function($v){
return eEmpType::getName($v[self::$TYPE]);
},
C::FILTER_TYPE => eFilterType::SELECT,
C::FUNC_FILTER_SELECT_OPTIONS => function(){
return eEmpType::getNameList();
}
]),
new C([
C::VAR_NAME => &self::$BIRTHDATE,
C::TYPE => eColumnType::DATE,
C::NULL => true,
C::HIDDEN => true,
C::TH => V::get(Vars::$BIRTHDATE),
C::FILTER_TYPE => eFilterType::DATE,
C::FUNC_VALUE_DATA => function($v){
return Merakomis::fdate($v[self::$BIRTHDATE]);
},
]),
new C([
C::VAR_NAME => &self::$PHONE,
C::TYPE => eColumnType::TEXT,
C::DEFAULT => '',
C::TH => V::get(Vars::$PHONE),
C::HIDDEN => true,
]),
new C([
C::VAR_NAME => &self::$SKYPE,
C::TYPE => eColumnType::TEXT,
C::FILTER_TYPE => eFilterType::TEXT,
C::DEFAULT => '',
C::TH => V::get(Vars::$SKYPE),
C::HIDDEN => true,
]),
new C([
C::VAR_NAME => &self::$DISCORD,
C::TYPE => eColumnType::TEXT,
C::FILTER_TYPE => eFilterType::TEXT,
C::DEFAULT => '',
C::TH => V::get(Vars::$DISCORD),
C::HIDDEN => true,
]),
new C([
C::VAR_NAME => &self::$EDUCATION,
C::TYPE => eColumnType::TEXT,
C::DEFAULT => '',
C::TH => V::get(Vars::$EDUCATION),
C::HIDDEN => true,
C::FILTER_TYPE => eFilterType::TEXT,
]),
new C([
C::VAR_NAME => &self::$DIPLOMA,
C::TYPE => eColumnType::TEXT,
C::DEFAULT => '',
C::TH => V::get(Vars::$DIPLOMA),
C::HIDDEN => true,
C::FILTER_TYPE => eFilterType::TEXT,
]),
new C([
C::VAR_NAME => &self::$DIPLOMA_DATE,
C::TYPE => eColumnType::DATE,
C::NULL => true,
C::TH => V::get(Vars::$DIPLOMA_DATE),
C::HIDDEN => true,
C::FILTER_TYPE => eFilterType::DATE,
]),
new C([
C::VAR_NAME => &self::$DIPLOMA_POST,
C::TYPE => eColumnType::TEXT,
C::DEFAULT => '',
C::TH => V::get(Vars::$DIPLOMA_POST),
C::HIDDEN => true,
C::FILTER_TYPE => eFilterType::TEXT,
]),
new C([
C::VAR_NAME => &self::$NOPRIZ,
C::TYPE => eColumnType::TEXT,
C::TH => V::get(Vars::$NOPRIZ),
C::HIDDEN => true,
C::FILTER_TYPE => eFilterType::TEXT,
]),
new C([
C::VAR_NAME => &self::$NOSTROI,
C::TYPE => eColumnType::TEXT,
C::TH => V::get(Vars::$NOSTROI),
C::HIDDEN => true,
C::FILTER_TYPE => eFilterType::TEXT,
]),
new C([
C::VAR_NAME => &self::$TECHNADZOR,
C::TYPE => eColumnType::TEXT,
C::TH => V::get(Vars::$TECHNADZOR),
C::HIDDEN => true,
C::FILTER_TYPE => eFilterType::TEXT,
]),
new C([
C::VAR_NAME => &self::$DESCRIPTION,
C::TYPE => eColumnType::TEXT,
C::TH => V::get(Vars::$DESCRIPTION),
C::HIDDEN => true,
]),
new C([
C::VAR_NAME => &self::$COMMENT,
C::TYPE => eColumnType::TEXT,
C::TH => V::get(Vars::$COMMENT),
C::HIDDEN => true,
]),
new C([
C::VAR_NAME => &self::$ACCEPT,
C::TYPE => eColumnType::TINYINT,
C::LENGTH => 1,
C::DEFAULT => 0,
C::HIDDEN => true,
C::FILTER_TYPE => eFilterType::BOOLEAN,
C::TH => $_POST['data']['mini'] ? 'Подтв.' : V::get(Vars::$ACCEPT),
C::FUNC_VALUE_DATA => function($v){
return Merakomis::boolString($v[self::$ACCEPT]);
}
]),
new C([
C::VAR_NAME => &self::$ACTIVE,
C::TYPE => eColumnType::TINYINT,
C::LENGTH => 1,
C::DEFAULT => 1,
C::COL_DEFAULT => 1,
C::HIDDEN => true,
C::FILTER_TYPE => eFilterType::BOOLEAN,
C::TH => $_POST['data']['mini'] ? 'Акт.' : V::get(Vars::$ACTIVE),
C::FUNC_VALUE_DATA => function($v){
return Merakomis::boolString($v[self::$ACTIVE]);
}
]),
new C([
C::VAR_NAME => &self::$REMOVED,
C::TYPE => eColumnType::TINYINT,
C::LENGTH => 1,
C::DEFAULT => 0,
C::HIDDEN => true,
C::EXPORT => false,
]),
new C([
C::VAR_NAME => &self::$ARCHIVE_DATE,
C::TYPE => eColumnType::DATE,
C::NULL => true,
//C::DEFAULT => 'NULL',
C::TH => V::get(Vars::$ARCHIVE_DATE),
//C::FUNC_VALUE_DATA => function($v){return Merakomis::fdate($v[self::$ARCHIVE_DATE]);},
C::FILTER_TYPE => eFilterType::DATE,
C::HIDDEN => true,
]),
new C([
C::VAR_NAME => &self::$SEX,
C::TYPE => eColumnType::TINYINT,
C::NULL => true,
//C::DEFAULT => 'NULL',
C::TH => V::get(Vars::$SEX),
C::FUNC_VALUE_DATA => function($v){
return self::getSexName($v);
return $v[self::$SEX]===null ? '' : ($v[self::$SEX]?'Мужской':'Женский');
},
//C::FILTER_TYPE => eFilterType::DATE,
C::HIDDEN => true,
]),
new C([
C::VAR_NAME => &self::$SALARY,
C::TYPE => eColumnType::DOUBLE,
C::NULL => true,
//C::DEFAULT => 'NULL',
C::LENGTH => '10,2',
C::TH => V::get(Vars::$SALARY),
C::FUNC_VALUE_DATA => function($v){
return Merakomis::fprice($v[self::$SALARY]);
},
C::FILTER_TYPE => eFilterType::NUMBER,
C::HIDDEN => true,
C::EXPORT => false,
]),
new C([
C::VAR_NAME => &self::$HAS_CHILDREN,
C::TYPE => eColumnType::TINYINT,
C::DEFAULT => '0',
C::LENGTH => '1',
C::TH => V::get(Vars::$HAS_CHILDREN),
C::FUNC_VALUE_DATA => function($v){
return Merakomis::fbool($v[self::$HAS_CHILDREN]);
},
C::FILTER_TYPE => eFilterType::BOOLEAN,
C::HIDDEN => true,
]),
new C([
C::VAR_NAME => &static::$TG_ACC,
C::TYPE => eColumnType::VARCHAR,
C::DEFAULT => 0,
C::HIDDEN => true,
C::EXPORT => false,
]),
/*
new C([
C::VAR_NAME => &static::$FOT,
C::TYPE => eColumnType::NONE,
C::DEFAULT => 0,
C::HIDDEN => true,
C::EXPORT => false,
C::TH => ' ',
C::FUNC_VALUE_DATA => function($v){
return '/money/fot/'.$v[self::$ID];
}
]),
*/
new C([
C::VAR_NAME => &static::$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::LENGTH => 11,
C::TH => V::get(Vars::$ACCOUNT),
C::DEFAULT => intval(\Site::$owner_id),
c::HIDDEN=>true,
c::FUNC_VALUE => function($v){
if($id = $v[self::$ACCOUNT]) {
return \Account::getName( \Account::getByID($id) );
} else return '-';
},
]),
new C([
C::VAR_NAME => &self::$CREATED,
C::TYPE => eColumnType::INT,
C::LENGTH => 11,
C::TH => V::get(Vars::$CREATED),
C::DEFAULT => time(),
c::FUNC_VALUE_DATA => function($v){return self::formatDate($v[self::$CREATED]);},
c::HIDDEN=>true,
C::FILTER_TYPE => eFilterType::DATE,
]),
new C([
C::VAR_NAME => &self::$UPDATED,
C::TYPE => eColumnType::INT,
C::DEFAULT => time(),
C::TH => V::get(Vars::$UPDATED),
c::FUNC_VALUE_DATA => function($v){return self::formatDate($v[self::$UPDATED]);},
c::HIDDEN=>true,
C::FILTER_TYPE => eFilterType::DATE,
]),
];
}
}
new Emp();
///