public function updateUser($uid, $fname, $role, $depid) { $res = 0; $this->select(' REPLACE INTO bid.users (id, login, fullname, role_id, department_id) VALUES (:uid, :login, :fname, :rid, :depid)', ['uid' => $uid, 'login' => makeSortName($fname), 'fname' => $fname, 'rid' => $role, 'depid' => $depid], $res); return $res !== 0; }
public function actionEdit() { // Получим номер запрашиваемой заявки, ее статус и цех-создатель // для проверки возможности редактирования $req_id = get_param($this->arguments, 0); $req_id = filter_var($req_id, FILTER_VALIDATE_INT, ['options' => ['min_range' => 1, 'default' => -1]]); $this->render('', false); $ticket = $this->model->getTicketInfo($req_id); $my_dep = get_param($this->authdata, 'depid'); //if (get_param($this->authdata, 'role_id') === Configuration::$ROLE_NSS) $this->render('info', false); if (!$ticket) { $this->preparePopup('Заявка не найдена', 'alert-warning'); $this->redirect('/contents/'); } elseif (get_param($ticket, 'status') == STATUS_DRAFT) { if (get_param($ticket, 'department_id') != $my_dep) { $this->preparePopup('Редактировать черновики чужого цеха запрещено'); $this->redirect('/contents/'); } } $this->data['title'] = 'Редактирование заявки '; $this->data['t_number'] = get_param($ticket, 'number'); $this->data['t_cdate'] = sqldate2human(get_param($ticket, 'dt_create'), 'd.m.Y'); $this->data['t_message'] = get_param($ticket, 'message'); $this->data['t_id'] = $req_id; $this->data['parent'] = ''; $departments = $this->model->getDepartments(); $tdepid = get_param($ticket, 'department_id'); $deplist = array_column($departments, 'title', 'id'); // цех создатель $this->data['t_department'] = get_param($deplist, $tdepid, '?'); // цех согласователь $agree = get_param($ticket, 'agree'); $adepid = get_param($agree, 'department_id', -1); $adepname = get_param($deplist, $adepid, null); // Название цеха, кто должен согласовать $ares = get_param($agree, 'result'); // null - пока не указанно; 0 - отказ; 1 - добро //$this->data['departments'] = generateOptions($departments, $adepid, 'Не требуется'); // Список отделов с заблокировкой текущего цеха и отметкой выбранного $this->data['departments'] = CHtml::createTag('option', ['value' => ''], 'Не требуется'); foreach ($deplist as $id => $title) { $param = []; $param['value'] = $id; if ($id == $my_dep) { $param['disabled'] = true; } if ($id == $adepid) { $param['selected'] = true; } $this->data['departments'] .= CHtml::createTag('option', $param, $title); } // пользователь создавший заявку $uid = get_param($ticket, 'user_id'); $user = $this->model->getUserName($uid); $this->data['t_user'] = get_param($user, 'fullname', '?'); // Информация по выбранному узлу $nodes = $this->model->getNodes(); $nodeid = get_param($ticket, 'node_id'); $nlist = array_column($nodes, 'title', 'id'); $this->data['nodename'] = get_param($nlist, $nodeid, '?'); // получим список устройств узла, и нарисуем чекбокс-лист // но изменим порядок, чтобы спервы отрисовались отмеченные в заявке устройства $dlist = $this->model->getDevices($nodeid); $dlist = array_column($dlist, 'name', 'id'); $devs = get_param($ticket, 'devices', []); $this->data['tstart'] = sqldate2human(get_param($ticket, 'dt_start')); $this->data['tstop'] = sqldate2human(get_param($ticket, 'dt_stop')); $this->data['resolutions'] = ''; $ticket_status = intval(get_param($ticket, 'status', -1)); if ($ticket_status === STATUS_DRAFT) { // кнопка удаления заявки доступна только из черновика $this->data['buttons'] = join(PHP_EOL, [CHtml::createLink('Удалить', "/ticket/delete/{$req_id}/", ['class' => 'btn btn-danger']), CHtml::createButton('Сохранить черновик', ['class' => 'btn btn-default btn-save', 'data-confirm' => 0, 'title' => 'Сохранить заявку в качестве черновика'])]); } // СУПЕР ХАК // если у нас вторым аргументом пришел "clone", то в силу вступает МАГИЯ... if (get_param($this->arguments, 1) === 'clone') { if ($ticket_status !== STATUS_OPEN) { $this->preparePopup('Продливать можно только открытую заявку'); $this->redirect(['back' => 1]); } elseif (!$this->isGrantToMe('ACE_PROLONG', $tdepid)) { $this->preparePopup('Не достаточно прав для продления заявки', 'alert-warning'); $this->redirect(['back' => 1]); } // по сути, мы открывем текущую заявку подменив ей статус на черновик, // что даст возможность редактирования ё параметров, но идентификатор заявки занулим, // что приведет к созданию новой заявки при сохранении $ticket_status = STATUS_DRAFT; $this->data['t_id'] = null; $this->data['t_message'] = sprintf("[Продление заявки #%s]\n%s", get_param($ticket, 'number'), get_param($ticket, 'message')); $this->data['button_delete'] = ''; // кнопку удаления убираем $this->data['t_number'] = '-'; $this->data['tstart'] = sqldate2human(get_param($ticket, 'dt_stop')); $this->data['tstop'] = ''; $this->data['parent'] = $req_id; $this->data['t_department'] = get_param($deplist, $my_dep, '?'); $this->data['buttons'] = ''; // Удаляем забитые выше кнопки удаления и сохранения черновика. При клонировании они не нужны } $devices = ''; // обходим перечень устройств указанных в заявке foreach ($devs as $item_id) { // получаем название из списка $devname = get_param($dlist, $item_id, '???'); $this->data['mark'] = 1; $this->data['dev_name'] = $devname; $this->data['dev_id'] = $item_id; $this->data['dev_class'] = mb_strlen($devname) >= 35 ? 'col-md-12' : 'col-md-6'; $devices .= $ticket_status === STATUS_DRAFT ? $this->renderPartial('device-item') : $devname . PHP_EOL; } if ($ticket_status !== STATUS_DRAFT) { $devices = nl2br($devices); } if (!count($dlist)) { $devices = $this->renderPartial('no-device'); } elseif (!(count($devs) || $ticket_status === STATUS_DRAFT)) { $devices = "Устройства не указаны"; } $review = get_param($ticket, 'review'); /* AGREE FORM */ if ($agree) { if ($ares === null) { //if ($my_role === Configuration::$ROLE_USER && $my_dep === $adepid) { if ($this->isGrantToMe('ACE_AGREE', $adepid)) { $this->data['panel_content'] = $this->renderPartial('form-agree'); $this->scripts[] = 'agree-ticket'; } else { $this->data['panel_content'] = "<em>Ожидание решения руководителя цеха</em>"; } } else { $this->data['ag_res'] = get_param($agree, 'result') ? 'Согласованно' : 'Отказанно'; $this->data['ag_class'] = 'strong'; $this->data['ag_user'] = makeSortName(get_param($agree, 'fullname', '-')); $this->data['ag_date'] = sqldate2human(get_param($agree, 'dt_stamp')); $this->data['panel_content'] = $this->renderPartial('agree-info'); } } else { $this->data['panel_content'] = "<em>Не требуется</em>"; } $this->data['panel_title'] = "Резолюция цеха {$adepname}"; $this->data['resolutions'] .= $this->renderPartial('resolution-panel'); /* AGREE FORM */ /* REVIEW FORM */ // форму рассмотрения нужно рисовать только в случае если согласование получено, либо оно не требуется вовсе if (!$agree || $ares !== null) { $this->data['panel_title'] = 'Резолюция главного инженера'; if (!$review) { // Если результата согласования нет //if ($my_role === Configuration::$ROLE_ME) { if ($this->isGrantToMe('ACE_ACCEPT')) { // Рисуем форму и подгружаем скрипт-обработчик $this->data['panel_content'] = $this->renderPartial('form-review'); $this->scripts[] = 'review-ticket'; } else { $this->data['panel_content'] = "<em>Ожидание...</em>"; } } else { // Покажем результат согласования ГИ $this->data['ag_class'] = ''; $this->data['ag_res'] = get_param($review, 'result'); $this->data['ag_user'] = get_param($review, 'fullname'); $this->data['ag_date'] = sqldate2human(get_param($review, 'dt_stamp')); $reason = get_param($review, 'reason', null); $this->data['ag_reason'] = nl2br(html_entity_decode($reason)) ?: null; $this->data['panel_content'] = $this->renderPartial('review-info'); } $this->data['resolutions'] .= $this->renderPartial('resolution-panel'); } /* REVIEW FORM */ //$this->scripts[] = 'debug-reload'; if ($ticket_status >= STATUS_OPEN) { // Панелька исполнителей $history = $this->model->getTicketHistory($req_id, [STATUS_OPEN, STATUS_COMPLETE, STATUS_CLOSE]); $items = ''; foreach ($history as $action) { $items .= CHtml::createTag('li', ['class' => 'list-group-item clearfix'], [CHtml::createTag('div', ['class' => 'col-xs-4 strong'], get_param($action, 'action')), CHtml::createTag('div', ['class' => 'col-xs-4'], makeSortName(get_param($action, 'fullname'))), CHtml::createTag('div', ['class' => 'col-xs-4'], sqldate2human(get_param($action, 'dt_stamp')))]); } $this->data['resolutions'] .= CHtml::createTag('ul', ['class' => 'list-group text-center'], $items); } // Пожарные $fire_person = $this->model->getFireDispatcher(); // Список диспетчеров для выпадающиго списка $fire_column = array_column($fire_person, 'title', 'id'); $dfire_o = get_param($ticket, 'fire_o') ?: -1; $dfire_c = get_param($ticket, 'fire_c') ?: -1; $this->data['fire_o'] = CHtml::createTag('input', ['class' => 'form-control', 'readonly' => true, 'type' => 'text', 'value' => get_param($fire_column, $dfire_o, '-')]); $this->data['fire_c'] = CHtml::createTag('input', ['class' => 'form-control', 'readonly' => true, 'type' => 'text', 'value' => get_param($fire_column, $dfire_c, '-')]); $this->data['navbtn'] = ''; /** * Получим весь список заявок с таким же статусом, воспользовавшись моделью Списка * для того, чтобы сформировать кнопки "следующая" и "предыдущая" * для реализации очередной "хотелки" */ if ($ticket_status < STATUS_ARCHIVE) { $cmod = new ContentsModel(); $all = array_column($cmod->getTicketListByStatus($ticket_status, $my_dep), 'id'); $idx = array_search($req_id, $all); $prev = get_param($all, $idx - 1); $next = get_param($all, $idx + 1); // Нашли предыдущую и слудующую, рисуем кнопки $this->data['navbtn'] = CHtml::createTag('div', ['class' => 'btn-group'], [CHtml::createTag('a', ['class' => 'btn btn-default strong' . ($prev ? '' : ' disabled'), 'href' => $prev ? $this->createActionUrl("edit/{$prev}") : '#'], [CHtml::createIcon('chevron-left'), 'Предыдущая']), CHtml::createButton(sprintf("%d из %d", $idx + 1, count($all)), ['class' => 'btn btn-default strong', 'disabled' => true, 'style' => 'color: #000']), CHtml::createTag('a', ['class' => 'btn btn-default strong' . ($next ? '' : ' disabled'), 'href' => $next ? $this->createActionUrl("edit/{$next}") : '#'], ['Следующая', CHtml::createIcon('chevron-right')])]); } $template = 'ticket-preview'; switch ($ticket_status) { case STATUS_DRAFT: $template = 'new-ticket'; $this->data['nodes'] = generateOptions($nodes, $nodeid, false); // дорисуем все устройства выбранного узла // которые не были отмеченны в заявке, // тчобы их можно было при необходимости выбрать foreach ($dlist as $key => $value) { if (!in_array($key, $devs)) { $this->data['mark'] = 0; $this->data['dev_name'] = $value; $this->data['dev_id'] = $key; $this->data['dev_class'] = mb_strlen($value) >= 35 ? 'col-md-12' : 'col-md-6'; $devices .= $this->renderPartial('device-item'); } } $this->data['buttons'] .= CHtml::createButton('Отправить на согласование', ['class' => 'btn btn-primary btn-save', 'data-confirm' => 1]); $this->scripts[] = 'ticket-validate'; break; case STATUS_AGREE: $this->data['title'] = 'Согласование заявки'; /** todo: Проверить возможность текущего статуса * Возможно согласование уже получено, или вовсе не требуется. * Следовательно заявка находится в статусе согласования не может * */ if (!$adepid || $ares !== null) { // Если id цеха, который должен согласовывать, не указан, или согласование уже получено (!= null) // то статус у заявки неверный, и его желательно исправить $this->preparePopup('Ошибочный статус заявки. Обратитесь в отдел АСУ.', 'alert-warning'); $template = 'incorrect-status'; // Я пока не уверен, что менять статус заяви автоматически - есть хорошо... // $this->model->setTicketStatus($req_id, STATUS_REVIEW, 0); } // Если текущий пользователь - Руководитель, то добавим ему кнопку сохранения, // чтобы он мог увековечить результат своего согласования //if (($my_role === Configuration::$ROLE_USER && $my_dep === $adepid) || $my_role === Configuration::$ROLE_NSS) { if ($this->isGrantToMe('ACE_AGREE', $adepid)) { $this->data['buttons'] = CHtml::createButton('Сохранить', ['class' => 'btn btn-primary', 'id' => 'save-btn']); // Скрипт уже будет продгружен на этапе формирования формы } break; case STATUS_REVIEW: $this->data['title'] = 'Рассмотрение заявки'; /** todo Проверить правильность текущего статуса * А именно: если должно быть согласование, то оно должно быть получено (result !== null) * Она не должна быть открытой или закрытой... Вобщем я хз как 100% быть уверенным */ if ($agree && $ares === null) { // Заявка должна быть согласована, но результата согласования нет // соответственно в текущем статусе она быть не может $this->preparePopup('Ошибочный статус заявки. Обратитесь в отдел АСУ.', 'alert-warning'); $template = 'incorrect-status'; //$this->model->setTicketStatus($req_id, $agree ? STATUS_AGREE : STATUS_DRAFT, 0); } //if ($my_role === Configuration::$ROLE_ME) { if ($this->isGrantToMe('ACE_ACCEPT')) { $this->data['buttons'] = CHtml::createButton('Сохранить', ['class' => 'btn btn-primary', 'id' => 'save-btn']); } break; case STATUS_ACCEPT: $this->data['title'] = 'Обработка заявки'; if (!$review) { // Нет согласования главного инженера $this->preparePopup('Ошибочный статус заявки. Обратитесь в отдел АСУ.', 'alert-warning'); $template = 'incorrect-status'; //$this->model->setTicketStatus($req_id, STATUS_ACCEPT, 0); } if ($this->isGrantToMe('ACE_DELETE')) { $this->data['buttons'] .= CHtml::createButton('Удалить заявку', ['class' => 'btn btn-danger', 'id' => 'delete-btn', 'data-toggle' => 'modal', 'data-target' => '#popup-dialog', 'href' => "/ticket/inputreason/{$req_id}/"]); //$this->scripts[] = 'delete-ticket'; } //if ($my_role === Configuration::$ROLE_NSS) { if ($this->isGrantToMe('ACE_OPEN')) { $this->data['fire_o'] = CHtml::createTag('select', ['class' => 'selectpicker show-tick form-control', 'data-style' => 'btn-default strong'], generateOptions($fire_person, null, 'Не требуется')); $this->data['buttons'] .= CHtml::createLink('Открыть заявку', "/ticket/start/{$req_id}/", ['class' => 'btn btn-primary', 'data-fire' => '', 'id' => 'action-btn']); $this->scripts[] = 'fire-select'; } break; case STATUS_OPEN: $this->data['title'] = 'Прикрытие заявки'; //if ($my_role === Configuration::$ROLE_USER && $my_dep === $tdepid) { if ($this->isGrantToMe('ACE_COMPLETE', $tdepid)) { $this->data['buttons'] = CHtml::createTag('div', ['class' => 'btn-group'], [CHtml::createLink('Продлить заявку', 'clone/', ['class' => 'btn btn-default']), CHtml::createButton('Прикрыть заявку', ['id' => 'btn-close', 'class' => 'btn btn-primary'])]); $this->scripts[] = 'handle-open'; } break; case STATUS_COMPLETE: $this->data['title'] = 'Закрытие заявки'; // Добавим панельку с информацией о том, кто открыл заявку //if ($my_role === Configuration::$ROLE_NSS) { if ($this->isGrantToMe("ACE_CLOSE")) { $this->data['fire_c'] = CHtml::createTag('select', ['class' => 'selectpicker show-tick form-control', 'data-style' => 'btn-default strong'], generateOptions($fire_person, null, 'Не требуется')); $this->data['buttons'] = CHtml::createLink('Закрыть заявку', "/ticket/close/{$req_id}/", ['class' => 'btn btn-primary strong', 'data-fire' => '', 'id' => 'action-btn']); $this->scripts[] = 'fire-select'; } break; case STATUS_REJECT: case STATUS_CLOSE: case STATUS_ARCHIVE: case STATUS_DELETE: $template = 'ticket-preview-history'; $this->data['title'] = 'Просмотр заявки'; $this->data['fire_o'] = get_param($fire_column, $dfire_o, '-'); $this->data['fire_c'] = get_param($fire_column, $dfire_c, '-'); // Для статуса ОТКЛОНЕНА/РАЗРЕШЕНА найдем причину/условие либо в согласовании, либо в разрешении $reason = get_param($agree, 'reason', null); $reason = get_param($review, 'reason', $reason); //nl2br(html_entity_decode( X )) ??? [для краясвкости] $this->data['history'] = ''; $log = $this->model->getTicketHistory($req_id); foreach ($log as $action) { $this->data['history'] .= CHtml::createTag('li', ['class' => 'list-group-item clearfix'], [CHtml::createTag('div', ['class' => 'col-xs-12 strong text-center'], get_param($action, 'action')), CHtml::createTag('div', ['class' => 'col-xs-6'], makeSortName(get_param($action, 'fullname'))), CHtml::createTag('em', ['class' => 'col-xs-6 text-right text-muted'], sqldate2human(get_param($action, 'dt_stamp'))), get_param($action, 'status_id') == STATUS_REJECT ? CHtml::createTag('div', ['class' => 'text-danger strong'], [$reason ? CHtml::createTag('div', ['class' => 'col-xs-4'], 'Причина:') : '', CHtml::createTag('em', ['class' => 'col-xs-8 text-right'], $reason)]) : '', get_param($action, 'status_id') == STATUS_ACCEPT ? CHtml::createTag('em', ['class' => 'text-success strong text-right col-xs-12'], $reason) : '', get_param($action, 'status_id') == STATUS_DELETE ? CHtml::createTag('em', ['class' => 'text-danger strong text-right col-xs-12'], get_param($ticket, 'extra')) : '']); } break; default: $template = 'incorrect-status'; } if ($ticket_status >= STATUS_ACCEPT) { $this->data['resolutions'] .= $this->renderPartial('fire-panel'); } $this->data['devlist'] = $devices; $this->render($template); }
<?php if ($authdata === false) { ?> <li class="last-menu-item"> <a href="/login/"><i class="glyphicon glyphicon-log-in"></i> Вход</a> </li> <?php } else { ?> <li class="navbar-text"><span>Вы вошли как:</span></li> <li class="dropdown last-menu-item"> <a class="dropdown-toggle" data-toggle="dropdown" href="#"> <i class="glyphicon glyphicon-user"></i> <?php echo makeSortName(get_param($authdata, 'fullname', 'n/a')); ?> <span class="caret"></span> </a> <ul class="dropdown-menu dropdown-user"> <li class="dropdown-header text-right strong"> <?php echo get_param($authdata, 'fullname', '-'); ?> </li> <?php if (get_param($authdata, 'admin')) { ?> <li> <a href="/admin/"> <i class="glyphicon glyphicon-cog"></i>