Unterbrechung bei laufender Unterbrechung

This commit is contained in:
cgfhtw
2024-02-21 09:19:56 +01:00
parent 658212a6eb
commit c034efb8b0
4 changed files with 155 additions and 67 deletions
@@ -86,7 +86,7 @@ class Unterbrechung extends FHC_Controller
$data = getData($result);
$data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($data->studiensemester_kurzbz);
$data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($prestudent_id, $data->studiensemester_kurzbz);
$this->outputJsonSuccess($data);
}
@@ -136,7 +136,7 @@ class Unterbrechung extends FHC_Controller
$datum_wiedereinstieg = $this->input->post('datum_wiedereinstieg');
$dms_id = null;
$result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id);
$result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester, $datum_wiedereinstieg);
if (isError($result)) {
return $this->outputJsonError(['db' => getError($result)]);
}
+57 -63
View File
@@ -1302,7 +1302,7 @@ class AntragLib
* retval -2 means other Antrag pending;
* retval -3 means in blacklist stg
*/
public function getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester_kurzbz = null)
public function getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester_kurzbz = null, $datum_wiedereinstieg = null)
{
$result = $this->_ci->PrestudentModel->load($prestudent_id);
if (isError($result))
@@ -1320,18 +1320,10 @@ class AntragLib
if (!hasData($result))
return success(0);
$result = current(getData($result));
$prestudent_stdsem = $result->studiensemester_kurzbz;
$datumStatus = $result->datum;
if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist'))) {
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_UNTERBRECHUNG,
'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED
]);
if (isError($result))
return $result;
if (hasData($result))
return success(-1);
if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist'))
&& $result->status_kurzbz != 'Unterbrecher') {
return success(0);
}
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere(['prestudent_id' => $prestudent_id]);
@@ -1339,7 +1331,8 @@ class AntragLib
return $result;
if (!hasData($result))
return success(1);
$result= getData($result);
$result = getData($result);
foreach ($result as $antrag)
{
if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG || $antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL)
@@ -1349,11 +1342,11 @@ class AntragLib
elseif($antrag->status == Studierendenantragstatus_model::STATUS_APPROVED && $antrag->datum > $datumStatus)
return success(-2);
}
if ($studiensemester_kurzbz && $antrag->typ == Studierendenantrag_model::TYP_UNTERBRECHUNG)
if ($antrag->typ == Studierendenantrag_model::TYP_UNTERBRECHUNG)
{
// NOTE(chris): check if this is an old or canceled one
if ($antrag->studiensemester_kurzbz == $studiensemester_kurzbz && $antrag->status != Studierendenantragstatus_model::STATUS_CANCELLED)
return success(-1);
// NOTE(chris): Ignore canceled ones
if ($antrag->status == Studierendenantragstatus_model::STATUS_CANCELLED)
continue;
}
if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG)
{
@@ -1362,6 +1355,17 @@ class AntragLib
}
}
if (!$studiensemester_kurzbz) {
$sems = $this->getSemesterForUnterbrechung($prestudent_id, $prestudent_stdsem);
if (!count(array_filter($sems, function ($item) {
return !$item['disabled'];
})))
return success(-1);
} else {
if ($this->_ci->StudierendenantragModel->hasRunningUnterbrechungBetween($prestudent_id, $studiensemester_kurzbz, $datum_wiedereinstieg))
return success(-1);
}
return success(1);
}
@@ -1552,53 +1556,43 @@ class AntragLib
return success($resultDetails);
}
public function getSemesterForUnterbrechung($studiensemester_kurzbz)
/**
* Rearrange the free semester slots for a new Unterbrechung
*
* @param integer $prestudent_id
* @param string $studiensemester_kurzbz
*
* @return array
*/
public function getSemesterForUnterbrechung($prestudent_id, $studiensemester_kurzbz)
{
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$semester = [];
$result = $this->_ci->StudiensemesterModel->getNextFrom($studiensemester_kurzbz);
if (!hasData($result))
return $semester;
$nextSem = current(getData($result));
$semester[0] = [
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'wiedereinstieg' => [$nextSem]
];
$result = $this->_ci->StudiensemesterModel->getNextFrom($nextSem->studiensemester_kurzbz);
if (!hasData($result))
return $semester;
$currSemester = current(getData($result));
$followingSemester = [$currSemester];
$max = $this->_ci->config->item('unterbrecher_semester_max_length');
if(!$max || $max < 1)
$max = 2;
for ($i = 1; $i < $max; $i++) {
$result = $this->_ci->StudiensemesterModel->getNextFrom($currSemester->studiensemester_kurzbz);
if (!hasData($result))
break;
$currSemester = current(getData($result));
$followingSemester[] = $currSemester;
}
$semester[1] = [
'studiensemester_kurzbz' => $nextSem->studiensemester_kurzbz,
'wiedereinstieg' => $followingSemester
];
//remove last Semester of the array
array_pop($followingSemester);
foreach ($followingSemester as $sem)
$semester[0]['wiedereinstieg'][] = $sem;
return $semester;
$result = $this->_ci->StudierendenantragModel->getFreeSlotsForUnterbrechung($prestudent_id, $studiensemester_kurzbz);
if (isError($result))
return [];
$result = getData($result);
if (!$result)
return [];
return array_reduce($result, function ($carry, $item) {
if (!isset($carry[$item->von]))
$carry[$item->von] = [
'studiensemester_kurzbz' => $item->von,
'wiedereinstieg' => [],
'disabled' => true
];
$carry[$item->von]['wiedereinstieg'][] = [
'studiensemester_kurzbz' => $item->bis,
'start' => $item->ende,
'disabled' => (boolean)$item->studierendenantrag_id
];
if ($carry[$item->von]['disabled'] && !$item->studierendenantrag_id) {
$carry[$item->von]['disabled'] = false;
}
return $carry;
}, []);
return $result;
}
public function getAktivePrestudentenInStgs($studiengaenge, $query)
@@ -287,4 +287,98 @@ class Studierendenantrag_model extends DB_Model
return $this->loadWhere($where);
}
/**
* Checks if the Prestudent has an active Unterbrechung between
* the start of the given semester and the given enddate.
* If the enddate is omitted the end of the given semester is used.
*
* @param integer $prestudent_id
* @param string $studiensemester_kurzbz
* @param string $enddate (optional)
*
* @return boolean
*/
public function hasRunningUnterbrechungBetween($prestudent_id, $studiensemester, $enddate = null)
{
$start = '(SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=' . $this->db->escape($studiensemester) . ')';
$end = $enddate
? $this->db->escape($enddate)
: '(SELECT ende FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=' . $this->db->escape($studiensemester) . ')';
$this->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$this->db->where([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_UNTERBRECHUNG,
'campus.get_status_studierendenantrag(studierendenantrag_id) !=' => Studierendenantragstatus_model::STATUS_CANCELLED,
'start < ' . $end => null,
'datum_wiedereinstieg > ' . $start => null,
]);
return (boolean)$this->db->count_all_results($this->dbTable);
}
/**
* Gets free semester slots for a new Unterbrechung.
*
* @param integer $prestudent_id
* @param string $studiensemester_kurzbz (optional)
*
* @return stdClass
*/
public function getFreeSlotsForUnterbrechung($prestudent_id, $studiensemester = null)
{
$max_starters = 2;
$max_length = max(
2,
(integer)$this->config->item('unterbrecher_semester_max_length')
);
$subquery = '';
if ($studiensemester)
$subquery = 'SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=?';
else
$subquery = 'SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=public.get_stdsem_prestudent (?, null)';
$sql = "WITH numbered_sems AS (
SELECT
a.studiensemester_kurzbz AS von,
b.studiensemester_kurzbz AS bis,
a.start AS start,
b.start AS ende,
ROW_NUMBER() OVER (
PARTITION BY a.studiensemester_kurzbz
ORDER BY b.start
) AS row_number
FROM public.tbl_studiensemester a
LEFT JOIN public.tbl_studiensemester b ON (b.start > a.ende)
),
last_sems AS (
SELECT *
FROM numbered_sems
WHERE numbered_sems.row_number <= ?
)
SELECT s.von, s.bis, s.start, s.ende, studierendenantrag_id
FROM last_sems s
LEFT JOIN (
SELECT studierendenantrag_id, start, datum_wiedereinstieg AS ende
FROM campus.tbl_studierendenantrag
LEFT JOIN public.tbl_studiensemester USING(studiensemester_kurzbz)
WHERE typ=?
AND campus.get_status_studierendenantrag(studierendenantrag_id) != ?
AND prestudent_id=?
) a ON (s.start < a.ende AND s.ende > a.start)
WHERE s.start >= (" . $subquery . ")
ORDER BY s.start, s.ende
LIMIT ?;";
return $this->execQuery($sql, [
$max_length,
self::TYP_UNTERBRECHUNG,
Studierendenantragstatus_model::STATUS_CANCELLED,
$prestudent_id,
$studiensemester ?: $prestudent_id,
$max_length * $max_starters
]);
}
}
@@ -256,7 +256,7 @@ export default {
:id="'studierendenantrag-form-abmeldung-' + uuid + '-stsem'"
@input="currentWiedereinstieg = ''"
>
<option v-for="(stsem, index) in data.studiensemester" :key="index" :value="index">
<option v-for="(stsem, index) in data.studiensemester" :key="index" :value="index" :disabled="stsem.disabled">
{{stsem.studiensemester_kurzbz}}
</option>
</select>
@@ -280,7 +280,7 @@ export default {
</div>
<div v-else>
<select v-model="currentWiedereinstieg" class="form-select">
<option v-for="sem in data.studiensemester[stsem].wiedereinstieg" :key="sem.studiensemester_kurzbz" :value="sem.start">
<option v-for="sem in data.studiensemester[stsem].wiedereinstieg" :key="sem.studiensemester_kurzbz" :value="sem.start" :disabled="sem.disabled">
{{sem.studiensemester_kurzbz}}
</option>
</select>