diff --git a/application/controllers/system/infocenter/InfoCenter.php b/application/controllers/system/infocenter/InfoCenter.php index 4662fbc40..f16c4472e 100644 --- a/application/controllers/system/infocenter/InfoCenter.php +++ b/application/controllers/system/infocenter/InfoCenter.php @@ -74,6 +74,7 @@ class InfoCenter extends Auth_Controller 'saveFormalGeprueft' => 'infocenter:rw', 'getLastPrestudentWithZgvJson' => 'infocenter:r', 'getZgvInfoForPrestudent' => 'infocenter:r', + 'saveBewPriorisierung' => 'infocenter:rw', 'saveZgvPruefung' => 'infocenter:rw', 'saveAbsage' => 'infocenter:rw', 'saveFreigabe' => 'infocenter:rw', @@ -81,6 +82,7 @@ class InfoCenter extends Auth_Controller 'updateNotiz' => 'infocenter:rw', 'reloadNotizen' => 'infocenter:r', 'reloadLogs' => 'infocenter:r', + 'reloadZgvPruefungen' => 'infocenter:r', 'outputAkteContent' => 'infocenter:r', 'getParkedDate' => 'infocenter:r', 'park' => 'infocenter:rw', @@ -280,6 +282,22 @@ class InfoCenter extends Auth_Controller $this->load->view('system/infocenter/studiengangZgvInfo.php', $data); } + /** + * Saves application priority for a prestudent + */ + public function saveBewPriorisierung() + { + $prestudent_id = $this->input->post('prestudentid'); + $change = $this->input->post('change'); + + if (!is_numeric($change) || !is_numeric($prestudent_id)) + $result = error('Parameteres missing'); + else + $result = $this->PrestudentModel->changePrio($prestudent_id, intval($change)); + + $this->output->set_content_type('application/json')->set_output(json_encode($result)); + } + /** * Saves a ZGV for a prestudent, includes Ort, Datum, Nation for bachelor and master * @param $prestudent_id @@ -543,6 +561,19 @@ class InfoCenter extends Auth_Controller $this->load->view('system/infocenter/logs.php', array('logs' => $logs)); } + /** + * Loads Zgv Prüfung view for a person, helper for reloading after ajax request + * @param $person_id + */ + public function reloadZgvPruefungen($person_id) + { + $prestudentdata = $this->_loadPrestudentData($person_id); + + $prestudentdata[self::FHC_CONTROLLER_ID] = $this->getControllerId(); + + $this->load->view('system/infocenter/zgvpruefungen.php', $prestudentdata); + } + /** * Outputs content of an Akte, sends appropriate headers (so the document can be downloaded) * @param $akte_id @@ -1058,6 +1089,8 @@ class InfoCenter extends Auth_Controller show_error($prestudenten->retval); } + $interessentenCount = array(); + foreach ($prestudenten->retval as $prestudent) { $prestudent = $this->PrestudentModel->getPrestudentWithZgv($prestudent->prestudent_id); @@ -1079,43 +1112,121 @@ class InfoCenter extends Auth_Controller //if prestudent is not interessent or is already bestaetigt, then show only as information, non-editable $zgvpruefung->infoonly = !isset($zgvpruefung->prestudentstatus) || isset($zgvpruefung->prestudentstatus->bestaetigtam) || $zgvpruefung->prestudentstatus->status_kurzbz != 'Interessent'; + //numeric application priority and arrows for changing + $zgvpruefung->changeup = false; + $zgvpruefung->changedown = false; + + if (isset($zgvpruefung->prestudentstatus->status_kurzbz) && $zgvpruefung->prestudentstatus->status_kurzbz == 'Interessent') + { + if (isset($zgvpruefung->prestudentstatus->studiensemester_kurzbz)) + { + $studiensemester = $zgvpruefung->prestudentstatus->studiensemester_kurzbz; + $zgvpruefung->changeup = $this->PrestudentModel->checkPrioChange($zgvpruefung->prestudent_id, $studiensemester, -1); + $zgvpruefung->changedown = $this->PrestudentModel->checkPrioChange($zgvpruefung->prestudent_id, $studiensemester, 1); + if (array_key_exists($studiensemester, $interessentenCount)) + $interessentenCount[$studiensemester]++; + else + $interessentenCount[$studiensemester] = 1; + } + } + $zgvpruefungen[] = $zgvpruefung; } - // Interessenten come first, otherwise by bewerbungsdatum desc, then by prestudent_id desc - usort($zgvpruefungen, function ($a, $b) { - $bewdatesort = isset($a->prestudentstatus) && isset($b->prestudentstatus) ? strcmp($b->prestudentstatus->bewerbung_abgeschicktamum, $a->prestudentstatus->bewerbung_abgeschicktamum) : 0; - $defaultsort = $bewdatesort === 0 ? (int)$b->prestudent_id - (int)$a->prestudent_id : $bewdatesort; - if (!isset($a->prestudentstatus->status_kurzbz) || !isset($b->prestudentstatus->status_kurzbz)) - return $defaultsort; - elseif ($a->prestudentstatus->status_kurzbz === 'Interessent' && $b->prestudentstatus->status_kurzbz === 'Interessent') - { - //infoonly Interessenten come after new Interessenten - if ($a->infoonly === $b->infoonly) - return $defaultsort; - elseif ($a->infoonly) - return 1; - elseif ($b->infoonly) - return -1; - } - elseif ($a->prestudentstatus->status_kurzbz === 'Interessent') - return -1; - elseif ($b->prestudentstatus->status_kurzbz === 'Interessent') - return 1; - else - return $defaultsort; - }); + $this->load->model('organisation/studiensemester_model', 'StudiensemesterModel'); + + $this->_sortPrestudents($zgvpruefungen); $statusgruende = $this->StatusgrundModel->loadWhere(array('status_kurzbz' => 'Abgewiesener'))->retval; $data = array ( 'zgvpruefungen' => $zgvpruefungen, + 'numberinteressenten' => $interessentenCount, 'statusgruende' => $statusgruende ); return $data; } + /** + * Helper function for sorting prestudents + * @param $zgvpruefungen + */ + private function _sortPrestudents(&$zgvpruefungen) + { + usort($zgvpruefungen, function ($a, $b) { + //sort: + // 1: Studiensemester + if (isset($a->prestudentstatus->studiensemester_kurzbz) || isset($b->prestudentstatus->studiensemester_kurzbz)) + { + if (!isset($a->prestudentstatus->studiensemester_kurzbz)) + return 1; + elseif(!isset($b->prestudentstatus->studiensemester_kurzbz)) + return -1; + + $starta = $this->StudiensemesterModel->load($a->prestudentstatus->studiensemester_kurzbz); + if (!hasData($starta)) + { + show_error($starta->retval); + } + + $startb = $this->StudiensemesterModel->load($b->prestudentstatus->studiensemester_kurzbz); + if (!hasData($startb)) + { + show_error($startb->retval); + } + + $starta = date_format(date_create($starta->retval[0]->start), 'Y-m-d'); + $startb = date_format(date_create($startb->retval[0]->start), 'Y-m-d'); + + if ($starta > $startb) + return -1; + elseif ($starta < $startb) + return 1; + } + // 2: Status + if ($a->prestudentstatus->status_kurzbz !== $b->prestudentstatus->status_kurzbz) + { + if ($a->prestudentstatus->status_kurzbz === 'Interessent') + return -1; + elseif ($b->prestudentstatus->status_kurzbz === 'Interessent') + return 1; + } + + // 3: Priorisierung, Nulls last + if (isset($a->priorisierung) || isset($b->priorisierung)) + { + if (!isset($a->priorisierung)) + return 1; + elseif (!isset($b->priorisierung)) + return -1; + elseif ($a->priorisierung > $b->priorisierung) + return 1; + elseif ($a->priorisierung < $b->priorisierung) + return -1; + } + + // 4: Bewerbungsdatum + $starta = isset($a->prestudentstatus->bewerbung_abgeschicktamum) ? $a->prestudentstatus->bewerbung_abgeschicktamum : null; + $startb = isset($b->prestudentstatus->bewerbung_abgeschicktamum) ? $b->prestudentstatus->bewerbung_abgeschicktamum : null; + + if (isset($starta) || isset($startb)) + { + if (!isset($starta)) + return 1; + elseif(!isset($startb)) + return -1; + elseif ($starta > $startb) + return -1; + elseif ($starta < $startb) + return 1; + } + + // 5: prestudentid + return (int)$b->prestudent_id - (int)$a->prestudent_id; + }); + } + /** * Helper function for redirecting to initial page for person from a prestudent-specific page * @param $prestudent_id diff --git a/application/models/crm/Prestudent_model.php b/application/models/crm/Prestudent_model.php index 4cfe08e9a..55215744e 100644 --- a/application/models/crm/Prestudent_model.php +++ b/application/models/crm/Prestudent_model.php @@ -278,4 +278,229 @@ class Prestudent_model extends DB_Model return $this->execQuery($qry, $parametersArray); } + + /** + * Returns a list with Bewerber (applicants) + * @param $person_id person who sent application(s) + * @param string $studiensemester_kurzbz + * @param bool $abgeschickt optional, wether application was filled out and sent + * @param bool $bestaetigt optional, wether application was confirmed by infocenter + * @return array with Bewerber + */ + public function getBewerber($person_id, $studiensemester_kurzbz = null, $abgeschickt = null, $bestaetigt = null) + { + $bewerber = array(); + $prestudents = $this->loadWhere(array('person_id' => $person_id)); + + if (!hasData($prestudents)) + return $bewerber; + + $this->load->model('crm/prestudentstatus_model', 'PrestudentstatusModel'); + + foreach ($prestudents->retval as $prestudent) + { + $lastStatus = $this->PrestudentstatusModel->getLastStatus($prestudent->prestudent_id, $studiensemester_kurzbz); + + if (!hasData($lastStatus)) + continue; + + $lastStatus = $lastStatus->retval[0]; + + if ($lastStatus->status_kurzbz !== 'Interessent') + continue; + + $bewerbung_abgeschicktamum = $lastStatus->bewerbung_abgeschicktamum; + $bestaetigtam = $lastStatus->bestaetigtam; + + $abgeschicktcond = true; + if (($abgeschickt === false && isset($bewerbung_abgeschicktamum)) || ($abgeschickt === true && !isset($bewerbung_abgeschicktamum))) + $abgeschicktcond = false; + + $bestaetigtcond = true; + if (($bestaetigt === false && isset($bestaetigtam)) || ($bestaetigt === true && !isset($bestaetigtam))) + $bestaetigtcond = false; + + if ($bestaetigtcond && $abgeschicktcond) + { + $prestudent->lastStatus = $lastStatus; + $bewerber[] = $prestudent; + } + } + + return $bewerber; + } + + /** + * Checks if application priority can be changed for a prestudent + * @param $prestudent_id + * @param $studiensemester Semester in which Prestudent applied + * @param $change increase priority (< 0) or decrease priority (> 0) + * @return bool wether priority can be changed + */ + public function checkPrioChange($prestudent_id, $studiensemester, $change) + { + if (!is_numeric($change)) + return false; + + $this->addSelect('person_id, priorisierung'); + $prestudent = $this->load($prestudent_id); + + if (!hasData($prestudent)) + return false; + + $person_id = $prestudent->retval[0]->person_id; + + $bewerberarr = $this->getBewerber($person_id, $studiensemester); + + if (count($bewerberarr) <= 1) + return false; + + if (!isset($prestudent->retval[0]->priorisierung)) + { + if ($change < 0) + return true; //null values can be changed to priority numbers, when there are other bewerber + else + return false; + } + + $priomin = 0; + $priomax = PHP_INT_MAX; + $currprio = intval($prestudent->retval[0]->priorisierung); + + foreach ($bewerberarr as $bewerber) + { + if (is_numeric($bewerber->priorisierung)) + { + $bewprio = intval($bewerber->priorisierung); + if ($bewprio < $priomax) + $priomax = $bewprio; + + if ($bewprio > $priomin) + $priomin = $bewprio; + } + } + + if (($currprio === $priomax && $change < 0)|| ($currprio === $priomin && $change > 0)) + { + return false; + } + + return true; + } + + /** + * Changes application priority for a prestudent + * Swaps priorities with nearest neighbour (nearest bewerber/prestudent) + * for the same studiensemester in order to move priority up/down + * @param $prestudent_id + * @param $change increase priority (< 0) or decrease priority (> 0) + * @return bool wether change of priority was sucessfull + */ + public function changePrio($prestudent_id, $change) + { + $this->addSelect('person_id, priorisierung'); + $prestudent = $this->load($prestudent_id); + + if (!hasData($prestudent)) + return false; + + $this->load->model('prestudentstatus_model', 'PrestudentstatusModel'); + $lastStatus = $this->PrestudentstatusModel->getLastStatus($prestudent_id, null, 'Interessent'); + + if (!hasData($lastStatus)) + return false; + + $studiensemester_kurzbz = $lastStatus->retval[0]->studiensemester_kurzbz; + + if (!$this->checkPrioChange($prestudent_id, $studiensemester_kurzbz, $change)) + return false; + + $person_id = $prestudent->retval[0]->person_id; + $currprio = intval($prestudent->retval[0]->priorisierung); + + $difftonext = PHP_INT_MAX; + $neighbour = null; + + $bewerberarr = $this->getBewerber($person_id, $studiensemester_kurzbz ); + + foreach ($bewerberarr as $bewerber) + { + if (is_numeric($bewerber->priorisierung)) + { + $bewprio = intval($bewerber->priorisierung); + + $diff = 0; + if ($change < 0 && ($bewprio < $currprio || is_null($prestudent->retval[0]->priorisierung))) //prio up + { + $diff = $currprio - $bewprio; + } + elseif ($change > 0 && $bewprio > $currprio) + { + $diff = $bewprio - $currprio; + } + + if ($diff !== 0 && $diff < $difftonext) + { + $difftonext = $diff; + $neighbour = $bewerber; + } + } + } + + if (is_null($prestudent->retval[0]->priorisierung)) + { + //if null value before, add lowest prio + $newprio = isset($neighbour->priorisierung) ? intval($neighbour->priorisierung) + 1 : 1; + + $result = $this->PrestudentModel->update( + $prestudent_id, + array( + 'priorisierung' => $newprio + ) + ); + + if (isError($result)) + { + return false; + } + else + { + return true; + } + } + else + { + $this->db->trans_start(false); + //prio swap + $resultFirst = $this->PrestudentModel->update( + $prestudent_id, + array( + 'priorisierung' => intval($neighbour->priorisierung) + ) + ); + + + $resultSecond = $this->PrestudentModel->update( + $neighbour->prestudent_id, + array( + 'priorisierung' => $currprio + ) + ); + + // Transaction complete! + $this->db->trans_complete(); + + // Check if everything went ok during the transaction + if ($this->db->trans_status() === false || isError($resultFirst) || isError($resultSecond)) + { + $this->db->trans_rollback(); + return false; + } + else + { + $this->db->trans_commit(); + return true; + } + } + } } diff --git a/application/models/crm/Prestudentstatus_model.php b/application/models/crm/Prestudentstatus_model.php index db98ddff6..946fe4e14 100644 --- a/application/models/crm/Prestudentstatus_model.php +++ b/application/models/crm/Prestudentstatus_model.php @@ -37,10 +37,11 @@ class Prestudentstatus_model extends DB_Model array_push($parametersArray, $studiensemester_kurzbz); $query .= ' AND studiensemester_kurzbz = ?'; } + if ($status_kurzbz != '') { array_push($parametersArray, $status_kurzbz); - $query .= ' AND status_kurzbz = ?'; + $query .= ' AND tbl_prestudentstatus.status_kurzbz = ?'; } $query .= ' ORDER BY datum DESC, insertamum DESC, ext_id DESC LIMIT 1'; diff --git a/application/views/system/infocenter/infocenterDetails.php b/application/views/system/infocenter/infocenterDetails.php index 2fbfa7987..b4c30c2c5 100755 --- a/application/views/system/infocenter/infocenterDetails.php +++ b/application/views/system/infocenter/infocenterDetails.php @@ -71,6 +71,8 @@ p->t('ui', 'freigeben')) ?> + + @@ -118,7 +120,7 @@ p->t('infocenter', 'zgv').' - '.ucfirst($this->p->t('lehre', 'pruefung'))?> -