Explorar el Código

updated UserTest

Piotr Labudda hace 9 años
padre
commit
a4b598b102

+ 3 - 2
SE/se-lib/Core/AclHelper.php

@@ -195,8 +195,9 @@ class Core_AclHelper {// Helper class for Acl
     $aclList[] = 'default_objects:AccessOwner';
     $aclList[] = 'default_objects:SystemObject';// tabele i obiekty możliwe do podłączenia do procesu (default_db/*, default_objects/*)
     // $aclList[] = 'default_objects:UserObject';// TODO: tabele i obiekty widoczne dla aktualnego usera
-    $aclList[] = 'default_objects:SystemProcess';// TODO: wszystkie proces init
-    $aclList[] = 'default_objects:UserProcess';// TODO: proces init przypisane do aktualnego usera
+    $aclList[] = 'default_objects:SystemProcess';// wszystkie proces init
+    $aclList[] = 'default_objects:UserProcess';// proces init przypisane do aktualnego usera
+    $aclList[] = 'default_objects:UserTestStats';// TODO: testy stats by user proces init
     $aclList[] = 'default_objects:File';
     $aclList[] = 'default_objects:Korespondencja';
     $aclList[] = 'default_objects:TestPerms';

+ 117 - 78
SE/se-lib/Route/UserTest.php

@@ -13,12 +13,14 @@ class Route_UserTest extends RouteBase {
   public function defaultAction() {
     UI::gora();
     UI::menu();
+    session_write_close();
     try {
       $procesMenu = ProcesMenu::getInstance();
       // $procesMenu->menuAction();// like UI::menu() ?
-      $acl = Core_AclHelper::getAclByNamespace('default_objects/UserProcess');
-      $userProcessList = $acl->getItems();
-      $this->userTestsView($userProcessList);
+      $acl = Core_AclHelper::getAclByNamespace('default_objects/UserTestStats');// default_objects/UserProcess
+      $userTestStatsList = $acl->getItems();
+      UI::setTitle("Testy - Moje");
+      $this->userTestsView($userTestStatsList);
     } catch (Exception $e) {
       UI::alert('danger', $e->getMessage());
     }
@@ -28,93 +30,130 @@ class Route_UserTest extends RouteBase {
   public function adminUserTestAction() {// TODO: replace POST from admin menu to view another user tests
     UI::gora();
     UI::menu();
+    session_write_close();
     try {
       $idUser = V::get('_user_id', 0, $_REQUEST, 'int');
-      $acl = Core_AclHelper::getAclByNamespace('default_objects/UserProcess');
+      $user = [];// $user = Core_AclHelper::getAclByNamespace('default_db/ADMIN_USERS')->getItem($idUser);
+      $user['name'] = "TODO: user name({$idUser})";
+
+      $acl = Core_AclHelper::getAclByNamespace('default_objects/UserTestStats');// default_objects/UserProcess
       $acl->setIdUser($idUser);
-      $userProcessList = $acl->getItems();
-      $this->userTestsView($userProcessList);
+      $userTestStatsList = $acl->getItems();
+      UI::setTitle("Testy - pracownika {$user['name']}");
+      $this->userTestsView($userTestStatsList);
     } catch (Exception $e) {
       UI::alert('danger', $e->getMessage());
     }
     UI::dol();
   }
 
-  public function userTestsView($userProcessList) {
-    DBG::nicePrint($userProcessList, '$userProcessList');
+  public function userTestsView($userTestStatsList) {
+    $activeFiltrProcessId = User::getAcl()->getPermsFiltrProcesId();
+    ?>
+    <style type="text/css">
+    .tbl-wyniki-testow {}
+     .tbl-wyniki-testow td {vertical-align:top;font-size:small;}
+     .tbl-wyniki-testow .proces-box {padding:0 6px;background:#f00;color:#fff;font-weight:bold;font-family:arial;text-decoration:none}
+     .tbl-wyniki-testow .proces-title {padding:0 3px;}
+     .tbl-wyniki-testow .wynik-cell .wyniki-cell-header {height:56px;overflow:hidden;}
+
+     .tbl-wyniki-testow .wynik-cell {padding:0 3px;}
+     .tbl-wyniki-testow .wynik-BRAK_TESTU .proces-box {background-color:silver;}
+     .tbl-wyniki-testow .wynik-BRAK_PYTAN .proces-box {background-color:#51B7D5;}
+     .tbl-wyniki-testow .wynik-DOBRY .proces-box {background-color:lightgreen;}
+     .tbl-wyniki-testow .wynik-DOSTATECZNY .proces-box {background-color:#FFFFB1; color:#777;}
+     .tbl-wyniki-testow .wynik-NIEDOSTATECZNY .proces-box {background-color:#FC5151;}
+     .tbl-wyniki-testow .wynik-IDEALNY .proces-box {background-color:gold;}
+     .tbl-wyniki-testow .wynik-NIEAKTUALNY .proces-box {background-color:silver;}
+    </style>
+    <?php
 
-    // old way
-    $userAcl = User::getAcl();
-    $procesyInitGroup = $this->getUsedProcesInitGroupedList($userAcl);
-    DBG::nicePrint($procesyInitGroup, '$procesyInitGroup');
-    if (empty($procesyInitGroup)) {
-      echo '<p>' . "Brak przypisanych procesów." . '</p>';
-      return;
+    $procesyInitList = [];
+    foreach ($userTestStatsList as $row) {
+      $procesyInitList[ $row['ID'] ] = $row['nazwa'];
     }
-  }
 
-  public function getUsedProcesInitGroupedList($userAcl) {
-		$procesyInitGroup = array();
-		$procesyInitList = $this->getUserProcesInitList($userAcl);
-    DBG::nicePrint($procesyInitList, '$procesyInitList');
-		if (empty($procesyInitList)) {
-			return;
-		}
-		$sqlProcesyInitIds = implode(",", array_keys($procesyInitList));
-		$sql = "select p.`ID`, p.`PARENT_ID`, pp.`DESC` as pp__DESC
-			from `CRM_PROCES` as p
-				join `CRM_PROCES` as pp on(pp.`ID`=p.`PARENT_ID`)
-			where p.`ID` in({$sqlProcesyInitIds})
-		";
-		$groupedProcesyInit = array();
-		$db = DB::getDB();
-		$res = $db->query($sql);
-		while ($r = $db->fetch($res)) {
-			if (!array_key_exists($r->PARENT_ID, $procesyInitGroup)) {
-				$procesyInitGroup[$r->PARENT_ID] = (object)array('nr'=>$r->PARENT_ID, 'label'=>$r->pp__DESC, 'sub'=>array());
-			}
-			$procesyInitGroup[$r->PARENT_ID]->sub[$r->ID] = $procesyInitList[$r->ID];
-			$groupedProcesyInit[] = $r->ID;
-		}
-		$ungroupedProcesyInit = array_diff(array_keys($procesyInitList), $groupedProcesyInit);
-		if (!empty($ungroupedProcesyInit)) {
-			$procesyInitGroup[$r->PARENT_ID] = (object)array('nr'=>null, 'label'=>"Pozostałe", 'sub'=>array());
-			foreach ($ungroupedProcesyInit as $nr) {
-				$procesyInitGroup[$r->PARENT_ID]->sub[$nr] = $procesyInitList[$nr];
-			}
-		}
-		return $procesyInitGroup;
-	}
+    $parentIdList = [];
+    foreach ($userTestStatsList as $row) {
+      $parentIdList[ $row['PARENT_ID'] ] = true;
+    }
 
-  /**
-	 * List of Proces Init for user (skip filters)
-   * TODO: read from CRM_PROCES_idx_GROUP_to_INIT_VIEW ?
-   * TODO: read from CRM_PROCES_idx_USER_to_INIT_VIEW ? - slow
-   * TODO: read from Schema_UserProcessStorageAcl ? - only for current logged in user
-	 */
-	public function getUserProcesInitList($userAcl) {
-		$userProcesInitList = array();
-		$idUserGroupList = $userAcl->fetchGroups();
-		$sqlIdUserGroupList = implode(",", array_keys($idUserGroupList));
-		$sqlIdProcesListSql = <<<SQL
-			select gi.`ID_PROCES`
-				from `CRM_PROCES_idx_GROUP_to_PROCES` gi
-				where gi.`ID_GROUP` in({$sqlIdUserGroupList})
-SQL;
-		$fetchUserProcesInitListSql = <<<SQL
-			select p.`ID`, p.`DESC`
-				from `CRM_PROCES_idx` i
-					join `CRM_PROCES` p on(p.`ID`=i.`idx_PROCES_INIT_ID`)
-				where i.`ID_PROCES` in({$sqlIdProcesListSql})
-				group by p.`ID`
-				order by p.`SORT_PRIO`
-SQL;
-		$db = DB::getDB();
-		$res = $db->query($fetchUserProcesInitListSql);
-		while ($r = $db->fetch($res)) {
-			$userProcesInitList[$r->ID] = $r->DESC;
-		}
-		return $userProcesInitList;
-	}
+    $sqlProcesyInitIds = (!empty($parentIdList)) ? implode(",", array_keys($parentIdList)) : '';
+    $parentProcessList = DB::getPDO()->fetchAll("
+      select p.ID, p.PARENT_ID, p.DESC as nazwa
+			from CRM_PROCES as p
+			where p.ID in({$sqlProcesyInitIds})
+    ");
+    foreach ($parentProcessList as $parentProcess) {
+      UI::startContainer(['class'=>"tbl-wyniki-testow page-header"]);
+      $linkProcessTree = "procesy5.php?task=CRM_PROCES&amp;filtr_id={$parentProcess['ID']}";
+      UI::tag('h3', [], "{$parentProcess['nazwa']} <small><a href=\"{$linkProcessTree}\">{{$parentProcess['ID']}}</a></small>");
+      UI::endContainer();
+
+      UI::startContainer(['class'=>"tbl-wyniki-testow"]);
+      UI::startTag('div', ['class'=>"row"]);
+      $i = 0;
+      foreach ($userTestStatsList as $testStats) {
+        if ($testStats['PARENT_ID'] != $parentProcess['ID']) continue;
+
+        UI::startTag('div', ['class'=>"col-md-3 wynik-cell wynik-{$testStats['wynik_teoretyczny']}"]);
+          UI::startTag('div', ['class'=>"panel panel-default"]);
+            UI::startTag('div', ['class'=>"panel-heading"]);
+              UI::tag('span', ['title'=>htmlspecialchars($testStats['nazwa']), 'data-toggle'=>"tooltip"], V::strShortUtf8($testStats['nazwa'], 80), " ");
+              $linkProcesView = "procesy5.php?task=PROCES_VIEW&id_proces={$testStats['ID']}";
+          	  UI::tag('a', ['href'=>$linkProcesView, 'title'=>"zobacz instrukcję do procesu {$testStats['ID']}", 'target'=>"_blank"], "{{$testStats['ID']}}");
+            UI::endTag('div');// .panel-heading
+            UI::startTag('div', ['class'=>"panel-body"]);
+              UI::startTag('ul', ['style' => "padding-left:20px"]);
+                UI::startTag('li');
+                  if ($activeFiltrProcessId == $testStats['ID']) {
+                    UI::tag('a', ['href'=>"index.php?FUNCTION_INIT=MENU_SELECT_PROCES&_action=setPermsAll", 'style'=>"font-weight:bold"], "Wyłącz filtr uprawnien dla", " ");
+                  } else {
+                    UI::tag('a', ['href'=>"index.php?FUNCTION_INIT=MENU_SELECT_PROCES&_action=setPermsByProces&id_proces={$testStats['ID']}"], "Uruchom filtr uprawnien dla", " ");
+                  }
+                  echo "{$testStats['ID']}";
+                UI::endTag('li');
+
+                UI::startTag('li');
+                  UI::tag('a', ['href'=>"procesy5.php?task=CRM_TESTY__ADD_TEST&test_type=TEORETYCZNY&proces_id={$testStats['ID']}"], "Wykonaj test teoretyczny dla", " ");
+                  echo "{$testStats['ID']}";
+                UI::endTag('li');
+
+                UI::startTag('li');
+                  echo "Test teoretyczny: ";
+                  UI::startTag('span', ['class'=>"proces-box"]);
+                    echo " {$testStats['wynik_teoretyczny']} ";
+                    if ($testStats['wynik_teoretyczny_value']) UI::tag('em', null, $testStats['wynik_teoretyczny_value']);
+                  UI::endTag('span');
+                UI::endTag('li');
+
+                UI::tag('li', ['class'=>"wynik-{$testStats['wynik_praktyczny']}"], "Test praktyczny: {$testStats['wynik_praktyczny']}");
+
+              UI::endTag('ul');
+
+              $tagFixTest = ($testStats['link_popraw_test'])
+                ? "<a class=\"btn btn-xs btn-primary\" href=\"{$testStats['link_popraw_test']}\">popraw</a>"
+                : '';
+              if ($testStats['wynik_unactual']) {
+      					UI::alert('danger', "
+                  <b>Uwaga! Test nieaktualny:</b>
+                  {$tagFixTest}
+                  <br>" . substr($testStats['last_test_end'], 0, 10) . " - zakończenie testu
+      						<br>" . substr($testStats['last_update_date'], 0, 10) . " - ostatnia zmiana w procesie
+                ");
+              }
+            UI::endTag('div');// .panel-body
+          UI::endTag('div');// .panel
+        UI::endTag('div');// .wynik-cell
+        if (++$i >= 4) {
+          $i = 0;
+          UI::endTag('div');// .row
+          UI::startTag('div', ['class'=>"row"]);
+        }
+      }
+      UI::endTag('div');// .row
+      UI::endContainer();
+    }
+  }
 
 }

+ 1 - 11
SE/se-lib/Schema/SystemObjectStorageAcl.php

@@ -58,17 +58,7 @@ class Schema_SystemObjectStorageAcl extends Core_AclSimpleSchemaBase {
     $limit = ($limit < 0) ? 0 : $limit;
     $offset = V::get('limitstart', 0, $params);
     $offset = ($offset < 0) ? 0 : $offset;
-    return ($limit > 0)
-      ? $this->_fixKeyItems(array_splice($items, $offset, $limit))
-      : $this->_fixKeyItems(array_splice($items, $offset));
-  }
-
-  public function _fixKeyItems($items) {
-    $fixed = array();
-    foreach ($items as $item) {
-      $fixed[ $this->_generateUniqueKeyFromNamespace($item['namespace']) ] = $item;
-    }
-    return $fixed;
+    return array_slice($items, $offset, ($limit > 0) ? $limit : null, $preserve_keys = true);
   }
 
   public function _generateUniqueKeyFromNamespace($namespace) {

+ 157 - 0
SE/se-lib/Schema/UserTestStatsStorageAcl.php

@@ -0,0 +1,157 @@
+<?php
+
+Lib::loadClass('Core_AclSimpleSchemaBase');
+Lib::loadClass('Schema_UserProcessStorageAcl');
+Lib::loadClass('ParseOgcFilter');
+Lib::loadClass('ProcesTestyHelper');
+
+class Schema_UserTestStatsStorageAcl extends Core_AclSimpleSchemaBase {
+
+  public $_simpleSchema = [
+    'root' => [
+      '@namespace' => 'default_objects/UserTestStats',
+      'ID' => [ '@type' => 'xsd:integer' ],
+      'PARENT_ID' => [ '@type' => 'xsd:integer' ],
+      'nazwa' => [ '@type' => 'xsd:string', '@alias' => 'DESC' ],
+      'opis' => [ '@type' => 'xsd:string', '@alias' => 'OPIS' ],
+      'link_uruchom_filtr_procesu' => [ '@type' => 'p5:www_link' ],
+      'link_uruchom_test_teoretyczny' => [ '@type' => 'p5:www_link', '@label' => "Wykonaj test teoretyczny"],
+      'wynik_teoretyczny' => [ '@type' => 'xsd:string', '@label' => "Wynik teoretyczny" ],
+      'wynik_teoretyczny_value' => [ '@type' => 'xsd:string', '@label' => "Wynik teoretyczny" ],
+      'wynik_praktyczny' => [ '@type' => 'xsd:string', '@label' => "Wynik praktyczny" ],
+      'wynik_unactual' => [ '@type' => 'xsd:string', '@label' => "Test nieaktualny?" ],
+      'wynik_unactual_id' => [ '@type' => 'xsd:integer', '@label' => "Nr nieaktualnego testu" ],
+      'link_popraw_test' => [ '@type' => 'xsd:integer', '@label' => "Popraw test" ],
+      'last_update_date' => [ '@type' => 'xsd:date' , '@label' => 'Ostatnia zmiana w procesie' ],
+      // 'autor' => [ '@type' => 'xsd:string' , '@alias' => 'A_RECORD_CREATE_AUTHOR' ],
+      // 'utworzono' => [ '@type' => 'xsd:date' , '@alias' => 'A_RECORD_CREATE_DATE' ],
+      // 'zaktualizował' => [ '@type' => 'xsd:string' , '@alias' => 'A_RECORD_UPDATE_AUTHOR' ],
+      // 'zaktualizowano' => [ '@type' => 'xsd:date', '@alias' => 'A_RECORD_UPDATE_DATE' ]
+    ]
+  ];
+  public $_rootTableName = 'CRM_PROCES';
+  public $idUser = null;
+  public $_userProcessAcl = null;// Schema_UserProcessStorageAcl
+
+  public function __construct($simpleSchema = null) {
+    parent::__construct($simpleSchema);
+    $this->idUser = User::getID();// default - current user
+    $this->_userProcessAcl = new Schema_UserProcessStorageAcl();// Core_AclHelper::getAclByNamespace('default_objects/UserProcess')
+    $this->_userProcessAcl->setIdUser($this->idUser);
+  }
+
+  public function setIdUser($idUser) { $this->idUser = intval($idUser); $this->_userProcessAcl->setIdUser($this->idUser); }
+  public function getIdUser() { return $this->idUser; }
+
+  public function getTotal($params = []) { return $this->_userProcessAcl->getTotal(); }
+
+  public function _parseSqlWhere($params = []) { return $this->_userProcessAcl->_parseSqlWhere($params); }
+
+  public function getItems($params = []) {
+    $bupLimit = V::get('limit', 0, $params);
+    $params['limit'] = 0;
+    $items = $this->_userProcessAcl->getItems($params);
+    if (empty($items)) return $items;
+
+    $params['limit'] = $bupLimit;
+
+    $sqlWhereAnd[] = "t.ID_PROCES_INIT in (" . implode(",", array_keys($items)) . ")";
+    // if ($max_age > 0) {
+    //   $sqlWhereAnd[] = "COALESCE(UNIX_TIMESTAMP(t.`TEST_END`), 0) > (UNIX_TIMESTAMP(NOW()) - {$max_age})";
+    // }
+    $sqlWhereAnd = (!empty($sqlWhereAnd)) ? "and " . implode("\n and ", $sqlWhereAnd) : '';
+    $idUser = $this->idUser;
+    $wynikiTeoret = DB::getPDO()->fetchAllByKey("
+      select test.ID
+        ,  test.ID_PROCES_INIT
+        ,  test.OCENA
+        ,  test.A_STATUS
+        ,  test.TEST_TYPE
+        ,  test.TEST_END
+      from CRM_TESTY test
+      where test.ID in(
+        select MAX(t.ID) as ID
+        from CRM_TESTY t
+        where t.`ID_TESTER`='{$idUser}'
+          and t.TEST_TYPE = 'TEORETYCZNY'
+          {$sqlWhereAnd}
+        group by t.ID_PROCES_INIT
+      )
+    ", 'ID_PROCES_INIT');
+    DBG::_('DBG', '>0', "\$wynikiTeoret", $wynikiTeoret, __CLASS__, __FUNCTION__, __LINE__);
+    $wynikiPraktyczne = DB::getPDO()->fetchAllByKey("
+      select test.ID
+        ,  test.ID_PROCES_INIT
+        ,  test.OCENA
+        ,  test.A_STATUS
+        ,  test.TEST_TYPE
+        ,  test.TEST_END
+      from CRM_TESTY test
+      where test.ID in(
+        select MAX(t.ID) as ID
+        from CRM_TESTY t
+        where t.`ID_TESTER`='{$idUser}'
+          and t.TEST_TYPE = 'PRAKTYCZNY'
+          {$sqlWhereAnd}
+        group by t.ID_PROCES_INIT
+      )
+    ", 'ID_PROCES_INIT');
+    DBG::_('DBG', '>0', "\$wynikiPraktyczne", $wynikiPraktyczne, __CLASS__, __FUNCTION__, __LINE__);
+
+    $limit = V::get('limit', 0, $params);
+    $limit = ($limit < 0) ? 0 : $limit;
+    $offset = V::get('limitstart', 0, $params);
+    $offset = ($offset < 0) ? 0 : $offset;
+    $items = array_slice($items, $offset, ($limit > 0) ? $limit : null, $preserve_keys = true);
+    if (empty($items)) return $items;
+
+    $testyLastUpdate = DB::getPDO()->fetchAllByKey("
+      select i.idx_PROCES_INIT_ID as ID, max(p.`A_RECORD_UPDATE_DATE`) as max_update_date
+      from CRM_PROCES p
+        join CRM_PROCES_idx i on(i.ID_PROCES = p.ID)
+      where i.idx_PROCES_INIT_ID in (" . implode(",", array_keys($items)) . ")
+      group by i.idx_PROCES_INIT_ID
+    ", 'ID');
+    DBG::_('DBG', '>0', "\$testyLastUpdate", $testyLastUpdate, __CLASS__, __FUNCTION__, __LINE__);
+
+    array_walk($items, function(&$item, $key) use ($wynikiTeoret, $wynikiPraktyczne, $testyLastUpdate) {
+      $item['link_uruchom_test_teoretyczny'] = Request::getPathUri() . "procesy5.php?task=CRM_TESTY__ADD_TEST&test_type=TEORETYCZNY&proces_id={$item['ID']}";
+
+      $item['wynik_teoretyczny_value'] = (array_key_exists($item['ID'], $wynikiTeoret)) ? $wynikiTeoret[ $item['ID'] ][ 'OCENA' ] : 0;
+      $item['wynik_teoretyczny'] = ProcesTestyHelper::getOcenaLabel($item['wynik_teoretyczny_value']);
+      $wynik_praktyczny_value = (array_key_exists($item['ID'], $wynikiPraktyczne)) ? $wynikiPraktyczne[ $item['ID'] ][ 'OCENA' ] : 0;
+      $item['wynik_praktyczny'] = ProcesTestyHelper::getOcenaLabel($wynik_praktyczny_value);
+      $item['wynik_unactual'] = '';
+      $item['wynik_unactual_id'] = '';
+      $item['link_popraw_test'] = '';
+      $item['last_test_end'] = '';
+      $item['last_update_date'] = (array_key_exists($item['ID'], $testyLastUpdate)) ? $testyLastUpdate[ $item['ID'] ][ 'max_update_date' ] : null;
+      if (array_key_exists($item['ID'], $wynikiTeoret)) {
+        $test = $wynikiTeoret[ $item['ID'] ];
+        $item['last_test_end'] = $test['TEST_END'];
+
+        $max_update_date = DB::getPDO()->fetchValue("
+          select max(p.`A_RECORD_UPDATE_DATE`) as max_update_date
+    			from `CRM_PROCES` as p
+    			where p.`ID` in(
+    				select i.`ID_PROCES`
+    					from `CRM_PROCES_idx` i
+    					where i.`idx_PROCES_INIT_ID`='{$item['ID']}'
+    			)
+        ");
+        if ($item['last_update_date']) {
+          $max_update_date = substr($item['last_update_date'], 0, 10);
+          $test_end = substr($item['TEST_END'], 0, 10);
+          if ($max_update_date > $test_end) {
+            $item['wynik_unactual'] = $max_update_date;
+            $item['wynik_unactual_id'] = $test['ID'];
+            $item['link_popraw_test'] = "procesy5.php?task=CRM_TESTY__ADD_TEST&function_init=fun_CRM_TESTY__ADD_FIX&test_id={$test['ID']}";
+          }
+        }
+      }
+    });
+
+    return $items;
+  }
+
+}