+ +
+ +
diff --git a/application/config/navigation.php b/application/config/navigation.php index 56d142d08..3680930d0 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -31,6 +31,14 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 20, 'requiredPermissions' => 'admin:w' + ), + 'bismeldestichtagsverwaltung' => array( + 'link' => site_url('codex/Bismeldestichtag'), + 'icon' => '', + 'description' => 'BIS-Meldestichtagsverwaltung', + 'expand' => true, + 'sort' => 30, + 'requiredPermissions' => 'admin:w' ) ) ), diff --git a/application/controllers/codex/Bismeldestichtag.php b/application/controllers/codex/Bismeldestichtag.php new file mode 100644 index 000000000..2723b2f7c --- /dev/null +++ b/application/controllers/codex/Bismeldestichtag.php @@ -0,0 +1,140 @@ + 'admin:r', + 'getStudiensemester' => 'admin:r', + 'getBismeldestichtage' => 'admin:r', + 'addBismeldestichtag' => 'admin:rw', + 'deleteBismeldestichtag' => 'admin:rw' + ) + ); + + // Load models + $this->load->model('codex/Bismeldestichtag_model', 'BismeldestichtagModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + // Loads phrases system + $this->loadPhrases( + array( + 'bismeldestichtag' + ) + ); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * Everything has a beginning + */ + public function index() + { + $this->load->view('codex/bismeldestichtag.php'); + } + + public function getStudiensemester() + { + // load semester list + $semList = array(); + $this->StudiensemesterModel->addSelect('studiensemester_kurzbz'); + $this->StudiensemesterModel->addOrder('start', 'DESC'); + $semRes = $this->StudiensemesterModel->load(); + + if (hasData($semRes)) + { + $semList = getData($semRes); + } + + // load current semester + $currSem = null; + $semRes = $this->StudiensemesterModel->getAkt(); + + if (hasData($semRes)) + { + $currSem = getData($semRes)[0]->studiensemester_kurzbz; + } + + // output data + $this->outputJsonSuccess( + array('semList' => $semList, 'currSem' => $currSem) + ); + } + + public function getBismeldestichtage() + { + $this->BismeldestichtagModel->addSelect( + 'meldestichtag_id, meldestichtag, + tbl_bismeldestichtag.studiensemester_kurzbz, sem.start AS semester_start, + tbl_bismeldestichtag.insertamum, tbl_bismeldestichtag.insertvon, tbl_bismeldestichtag.updateamum, tbl_bismeldestichtag.updatevon' + ); + $this->BismeldestichtagModel->addJoin('public.tbl_studiensemester sem', 'studiensemester_kurzbz', 'LEFT'); + $this->BismeldestichtagModel->addOrder('semester_start'); + $this->BismeldestichtagModel->addOrder('meldestichtag', 'DESC'); + $this->BismeldestichtagModel->addOrder('meldestichtag_id', 'DESC'); + $this->outputJson($this->BismeldestichtagModel->load()); + } + + public function addBismeldestichtag() + { + // get request data + $request = $this->getPostJSON(); + + // check request data + if (!property_exists($request, 'meldestichtag') || isEmptyString($request->meldestichtag)) + $this->terminateWithJsonError('Error occured: Meldestichtag missing'); + if (!property_exists($request, 'studiensemester_kurzbz') || isEmptyString($request->studiensemester_kurzbz)) + $this->terminateWithJsonError('Error occured: Studiensemester missing'); + + $meldestichtag = $request->meldestichtag; + $studiensemester_kurzbz = $request->studiensemester_kurzbz; + + // check if Bismeldestichtag already exists + $this->BismeldestichtagModel->addSelect('1'); + $bismeldestichtagRes = $this->BismeldestichtagModel->loadWhere( + array('meldestichtag' => $meldestichtag, 'studiensemester_kurzbz' => $studiensemester_kurzbz) + ); + + // return success if already exists + if (hasData($bismeldestichtagRes)) + $this->outputJsonSuccess('Bismeldestichtag already exists'); + else + { + // insert new if Stichtag does not exist + $this->outputJson($this->BismeldestichtagModel->insert( + array( + 'meldestichtag' => $request->meldestichtag, + 'studiensemester_kurzbz' => $request->studiensemester_kurzbz, + 'insertvon' => getAuthUID() + ) + )); + } + } + + public function deleteBismeldestichtag() + { + // get request data + $request = $this->getPostJSON(); + + // check request data + if (!property_exists($request, 'meldestichtag_id')) + $this->terminateWithJsonError('Error occured: Meldestichtag Id missing'); + + $meldestichtag_id = $request->meldestichtag_id; + + // deletetion + $this->outputJson($this->BismeldestichtagModel->delete($meldestichtag_id)); + } +} diff --git a/application/controllers/components/Antrag/Leitung.php b/application/controllers/components/Antrag/Leitung.php index f6b184351..8d333d5b8 100644 --- a/application/controllers/components/Antrag/Leitung.php +++ b/application/controllers/components/Antrag/Leitung.php @@ -33,54 +33,28 @@ class Leitung extends FHC_Controller public function getActiveStgs() { - $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe'); - $stgsNeuanlage = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); - - $stgs = []; - - if ($studiengaenge) { - $result = $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); - - if (isError($result)) - return $this->outputJson($result); - $antraege = getData($result) ?: []; - - foreach ($antraege as $antrag) { - if (!isset($stgs[$antrag->studiengang_kz])) { - $stgs[$antrag->studiengang_kz] = new stdClass(); - $stgs[$antrag->studiengang_kz]->bezeichnung = $antrag->bezeichnung; - $stgs[$antrag->studiengang_kz]->orgform = $antrag->orgform; - $stgs[$antrag->studiengang_kz]->studiengang_kz = $antrag->studiengang_kz; - } - } + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe') ?: []; + $studiengaenge = array_merge($studiengaenge, $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []); + + $result = $this->StudierendenantragModel->loadStgsWithAntraege($studiengaenge); + if (isError($result)) { + $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); } - - if ($stgsNeuanlage) { - $result = $this->StudierendenantragModel->loadForStudiengaenge($stgsNeuanlage); - - if (isError($result)) - return $this->outputJson($result); - $antraege = getData($result) ?: []; - - foreach ($antraege as $antrag) { - if (!isset($stgs[$antrag->studiengang_kz])) { - $stgs[$antrag->studiengang_kz] = new stdClass(); - $stgs[$antrag->studiengang_kz]->bezeichnung = $antrag->bezeichnung; - $stgs[$antrag->studiengang_kz]->orgform = $antrag->orgform; - $stgs[$antrag->studiengang_kz]->studiengang_kz = $antrag->studiengang_kz; - } - } - } - - $this->outputJsonSuccess($stgs); + $this->outputJson($result); } - public function getAntraege($studiengang = null) + public function getAntraege($studiengang = null, $extra = null) { + if ($studiengang && $studiengang == 'todo') { + $studiengang = $extra; + $extra = true; + } else { + $extra = false; + } - if($studiengang) + if ($studiengang) { $studiengaenge = [$studiengang]; - else { + } else { $studiengaenge =$this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe'); if(!is_array($studiengaenge)) $studiengaenge = []; @@ -96,7 +70,9 @@ class Leitung extends FHC_Controller $antraege = []; if ($studiengaenge) { - $result = $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); + $result = $extra + ? $this->StudierendenantragModel->loadActiveForStudiengaenge($studiengaenge) + : $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); if (isError($result)) { $this->output->set_status_header(500); return $this->outputJson('Internal Server Error'); diff --git a/application/controllers/components/Antrag/Wiederholung.php b/application/controllers/components/Antrag/Wiederholung.php index 515771224..418d05f45 100644 --- a/application/controllers/components/Antrag/Wiederholung.php +++ b/application/controllers/components/Antrag/Wiederholung.php @@ -76,10 +76,9 @@ class Wiederholung extends FHC_Controller if (isError($result)) { return $this->outputJsonError(getError($result)); } - $data = getData($result); - $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id); + $result = $this->antraglib->getFailedExamForPrestudent($prestudent_id, $data->datum, $data->studiensemester_kurzbz); // NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt() $pruefungsdata = current(getData($result)); diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index 2e72041ff..131cfdced 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -286,7 +286,6 @@ class AntragJob extends JOB_Controller $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed( [ - null, Studierendenantragstatus_model::STATUS_REQUESTSENT_1, Studierendenantragstatus_model::STATUS_REQUESTSENT_2 ], @@ -346,6 +345,7 @@ class AntragJob extends JOB_Controller $dateDeadline = new DateTime(); $dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline)); + $this->StudierendenantragModel->addSelect('tbl_studierendenantrag.studierendenantrag_id'); $this->StudierendenantragModel->addSelect('prestudent_id'); $this->StudierendenantragModel->addSelect('studiensemester_kurzbz'); $this->StudierendenantragModel->addSelect('s.insertamum'); @@ -370,50 +370,62 @@ class AntragJob extends JOB_Controller foreach ($antraege as $antrag) { - $result = $this->prestudentlib->setAbbrecher( - $antrag->prestudent_id, - $antrag->studiensemester_kurzbz, - 'AntragJob', - 'abbrecherStgl', - $antrag->insertamum, - null, - $antrag->insertvon ?: $insertvon - ); + $result = $this->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag->studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_DEREGISTERED, + 'insertvon' => 'AntragJob' + ]); if (isError($result)) $this->logError(getError($result)); - else - { - $count++; - $result = $this->PrestudentModel->load($antrag->prestudent_id); - if(!hasData($result)) { - $this->logWarning('No Prestudent found'); - continue; - } - $prestudent = current(getData($result)); - $result = $this->StudiengangModel->load($prestudent->studiengang_kz); - if(!hasData($result)) { - $this->logWarning('No Studiengang found'); - continue; - } - $studiengang = current(getData($result)); - $result = $this->PersonModel->loadPrestudent($antrag->prestudent_id); - if(!hasData($result)) - { - $this->logWarning('No Person found'); - continue; - } - $person = current(getData($result)); - $email = $studiengang->email; - $dataMail = array( - 'prestudent' => $antrag->prestudent_id, - 'studiensemester' => $antrag->studiensemester_kurzbz, - 'name' => trim($person->vorname . ' '. $person->nachname), - ); + else { + $deregisterStatus = getData($result); - if(!sendSanchoMail('Sancho_Mail_Antrag_A_Assist', $dataMail, $email, 'Einspruchsfrist abgelaufen')) - { - $this->logWarning("Failed to send Notification to " . $email); + $result = $this->prestudentlib->setAbbrecher( + $antrag->prestudent_id, + $antrag->studiensemester_kurzbz, + 'AntragJob', + 'abbrecherStgl', + $antrag->insertamum, + null, + $antrag->insertvon ?: $insertvon + ); + if (isError($result)) { + $this->StudierendenantragstatusModel->delete($deregisterStatus); + $this->logError(getError($result)); + } else { + $count++; + $result = $this->PrestudentModel->load($antrag->prestudent_id); + if(!hasData($result)) { + $this->logWarning('No Prestudent found'); + continue; + } + $prestudent = current(getData($result)); + $result = $this->StudiengangModel->load($prestudent->studiengang_kz); + if(!hasData($result)) { + $this->logWarning('No Studiengang found'); + continue; + } + $studiengang = current(getData($result)); + $result = $this->PersonModel->loadPrestudent($antrag->prestudent_id); + if(!hasData($result)) + { + $this->logWarning('No Person found'); + continue; + } + $person = current(getData($result)); + $email = $studiengang->email; + $dataMail = array( + 'prestudent' => $antrag->prestudent_id, + 'studiensemester' => $antrag->studiensemester_kurzbz, + 'name' => trim($person->vorname . ' '. $person->nachname), + ); + + if(!sendSanchoMail('Sancho_Mail_Antrag_A_Assist', $dataMail, $email, 'Einspruchsfrist abgelaufen')) + { + $this->logWarning("Failed to send Notification to " . $email); + } } + } } $this->logInfo($count . "/" . count($antraege) . " Students set to Abbrecher"); diff --git a/application/controllers/jobs/ReihungstestJob.php b/application/controllers/jobs/ReihungstestJob.php index 431ac5b04..c31ed54c9 100644 --- a/application/controllers/jobs/ReihungstestJob.php +++ b/application/controllers/jobs/ReihungstestJob.php @@ -467,7 +467,7 @@ class ReihungstestJob extends JOB_Controller $this->PrestudentstatusModel->addJoin('public.tbl_person', 'person_id'); $yesterdays_applicants_arr = $this->PrestudentstatusModel->loadWhere(' - status_kurzbz = \'Interessent\' AND + status_kurzbz IN (\'Interessent\', \'Bewerber\') AND typ = \'b\' AND bestaetigtam = current_date - 1 '); @@ -730,33 +730,27 @@ class ReihungstestJob extends JOB_Controller tbl_reihungstest.reihungstest_id, tbl_studienplan.studienplan_id, tbl_reihungstest.studiensemester_kurzbz, - tbl_studienordnung.studiengang_kz + tbl_studienordnung.studiengang_kz, + tbl_studienplan.orgform_kurzbz FROM public.tbl_reihungstest - JOIN public.tbl_rt_studienplan ON(tbl_rt_studienplan.reihungstest_id=tbl_reihungstest.reihungstest_id) - JOIN lehre.tbl_studienplan USING(studienplan_id) - JOIN lehre.tbl_studienordnung USING(studienordnung_id) + JOIN public.tbl_rt_studienplan ON(tbl_rt_studienplan.reihungstest_id=tbl_reihungstest.reihungstest_id) + JOIN lehre.tbl_studienplan USING(studienplan_id) + JOIN lehre.tbl_studienordnung USING(studienordnung_id) WHERE - NOT EXISTS( - SELECT 1 FROM lehre.tbl_studienplan_semester - WHERE studienplan_id=tbl_rt_studienplan.studienplan_id - AND tbl_studienplan_semester.studiensemester_kurzbz=tbl_reihungstest.studiensemester_kurzbz + EXISTS ( + SELECT studienplan_id + FROM lehre.tbl_studienordnung sordnung + JOIN lehre.tbl_studienplan USING (studienordnung_id) + JOIN lehre.tbl_studienplan_semester USING (studienplan_id) + WHERE sordnung.studiengang_kz = tbl_studienordnung.studiengang_kz + AND tbl_studienplan_semester.studiensemester_kurzbz = tbl_reihungstest.studiensemester_kurzbz + AND tbl_studienplan.studienplan_id NOT IN + ( + SELECT studienplan_id FROM tbl_rt_studienplan WHERE reihungstest_id = tbl_reihungstest.reihungstest_id + ) ) - AND tbl_reihungstest.datum >= now() - AND NOT EXISTS( - SELECT - 1 - FROM - public.tbl_rt_studienplan rtstp - JOIN lehre.tbl_studienplan stp USING(studienplan_id) - JOIN lehre.tbl_studienordnung sto USING(studienordnung_id) - JOIN lehre.tbl_studienplan_semester stpsem USING(studienplan_id) - WHERE - sto.studiengang_kz=tbl_studienordnung.studiengang_kz - AND rtstp.reihungstest_id=tbl_reihungstest.reihungstest_id - AND stpsem.studiensemester_kurzbz=tbl_reihungstest.studiensemester_kurzbz - ) - "; + AND tbl_reihungstest.datum >= now()"; $db = new DB_Model(); $result_rt = $db->execReadOnlyQuery($qry); @@ -766,7 +760,9 @@ class ReihungstestJob extends JOB_Controller // find an active studyplan for the same degree program with is valid in this semester $result_stpl = $this->StudienplanModel->getStudienplaeneBySemester( $row_rt->studiengang_kz, - $row_rt->studiensemester_kurzbz + $row_rt->studiensemester_kurzbz, + null, + $row_rt->orgform_kurzbz ); if (hasData($result_stpl)) { diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php index 1922bacda..3cba756cf 100644 --- a/application/controllers/lehre/anrechnung/RequestAnrechnung.php +++ b/application/controllers/lehre/anrechnung/RequestAnrechnung.php @@ -152,10 +152,10 @@ class requestAnrechnung extends Auth_Controller return $this->outputJsonError($this->p->t('anrechnung', 'antragBereitsGestellt')); } - // Exit if application is not for actual studysemester - if (!self::_applicationIsForActualSS($studiensemester_kurzbz)) + // Exit if application is a past ( < actual ) studysemester + if (self::_applicationIsPastSS($studiensemester_kurzbz)) { - return $this->outputJsonError($this->p->t('anrechnung', 'antragNurImAktSS')); + return $this->outputJsonError($this->p->t('anrechnung', 'antragNichtFuerVerganganeSS')); } // Upload document @@ -312,18 +312,21 @@ class requestAnrechnung extends Auth_Controller } /** - * Check if applications' study semester is actual study semester. + * Check if applications' study semester is < actual study semester. * * @param $studiensemester_kurzbz * @return bool */ - private function _applicationIsForActualSS($studiensemester_kurzbz) + private function _applicationIsPastSS($studiensemester_kurzbz) { $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); $result = $this->StudiensemesterModel->getNearest(); - $actual_ss = getData($result)[0]->studiensemester_kurzbz; + $actual_ss = getData($result)[0]; - return $studiensemester_kurzbz == $actual_ss; + $result = $this->StudiensemesterModel->load($studiensemester_kurzbz); + $anrechnung_ss = getData($result)[0]; + + return $anrechnung_ss->ende < $actual_ss->start; } private function _LVhasBlockingGrades($studiensemester_kurzbz, $lehrveranstaltung_id) diff --git a/application/controllers/system/messages/FASMessages.php b/application/controllers/system/messages/FASMessages.php index 55d1da25f..e2169af9b 100644 --- a/application/controllers/system/messages/FASMessages.php +++ b/application/controllers/system/messages/FASMessages.php @@ -37,7 +37,7 @@ class FASMessages extends Auth_Controller // Loads the view to write a new message with a template $this->load->view( - 'system/messages/htmlWriteTemplate', + 'system/messages/FAShtmlWriteTemplate', $this->CLMessagesModel->prepareHtmlWriteTemplatePrestudents($prestudents) ); } @@ -53,7 +53,7 @@ class FASMessages extends Auth_Controller // Loads the view to write a new message with a template $this->load->view( - 'system/messages/htmlWriteTemplate', + 'system/messages/FAShtmlWriteTemplate', $this->CLMessagesModel->prepareHtmlWriteTemplatePrestudents($prestudents, $message_id, $recipient_id) ); } diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index ff4d5dc63..335bfab27 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -62,6 +62,24 @@ class AntragLib 'insertvon' => $insertvon ]); + // NOTE(chris): remove "preabbrecher" statusgrund for Stgl-Abmeldungen if set + $res = $this->_ci->StudierendenantragModel->load($antrag_id); + if (hasData($res) && current(getData($res))->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) { + $this->_ci->PrestudentstatusModel->addSelect('tbl_status_grund.statusgrund_kurzbz'); + $res = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail(current(getData($res))->prestudent_id, '', 'Student'); + if (hasData($res) && current(getData($res))->statusgrund_kurzbz == 'preabbrecher') { + $prestudentstatus = current(getData($res)); + $this->_ci->PrestudentstatusModel->update([ + 'prestudent_id' => $prestudentstatus->prestudent_id, + 'status_kurzbz'=>$prestudentstatus->status_kurzbz, + 'studiensemester_kurzbz'=>$prestudentstatus->studiensemester_kurzbz, + 'ausbildungssemester'=>$prestudentstatus->ausbildungssemester + ], [ + 'statusgrund_id' => null + ]); + } + } + return $result; } @@ -967,6 +985,7 @@ class AntragLib $studiengang_kz = $result->studiengang_kz; $orgform_kurzbz = $result->orgform_kurzbz; $ausbildungssemester = $result->ausbildungssemester; + $sprache = $result->sprache; // NOTE(chris): check permission $allowedStgs = $this->_ci->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []; @@ -1012,11 +1031,12 @@ class AntragLib $semA, $ausbildungssemester + 1, $antrag->prestudent_id, - $antrag->studiensemester_kurzbz + $sprache ); if (isError($result)) return $result; $lvsA = $result->retval; // NOTE(chris): don't use getData() because we want to differenciate [] and null + $repeat_last = false; if ($lvsA) { foreach($lvsA as $lv) { @@ -1027,6 +1047,81 @@ class AntragLib $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; } } + } elseif ($lvsA === null) { + // NOTE(chris): We are repeating the last semester + $repeat_last = true; + + $result = $this->_ci->PrestudentstatusModel->getStatusByFilter($antrag->prestudent_id, 'Student', $ausbildungssemester - 1); + if (isError($result)) + return $result; + + $stdsems = getData($result) ?: []; + $stdsem = null; + + $result = $this->_ci->StudiensemesterModel->load($antrag->studiensemester_kurzbz); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_stdsem', ['studiensemester_kurzbz' => $antrag->studiensemester_kurzbz])); + $asem = current(getData($result)); + + foreach ($stdsems as $sem) { + $result = $this->_ci->StudiensemesterModel->load($sem->studiensemester_kurzbz); + if (isError($result)) + return $result; + if (hasData($result)) { + if (current(getData($result))->start < $asem->start) { + $stdsem = $sem->studiensemester_kurzbz; + break; + } + } + } + + // NOTE(chris): if we don't find a status in the previous semester there is something wrong + if (!$stdsem) + return error($this->_ci->p->t('studierendenantrag', 'error_no_status_in_prev_sem')); + + $result = $this->getLvsByStgStsemAndSem( + $studiengang_kz, + $orgform_kurzbz, + $semA, + $ausbildungssemester - 1, + $antrag->prestudent_id, + $sprache + ); + if (isError($result)) + return $result; + + $lvsA = getData($result) ?: []; + + $result = $this->getLvsByStgStsemAndSem( + $studiengang_kz, + $orgform_kurzbz, + $stdsem, + $ausbildungssemester - 1, + $antrag->prestudent_id, + $sprache + ); + if (isError($result)) + return $result; + + $lvsAtest = getData($result) ?: []; + + if (count(array_intersect(array_map(function ($a) { + return $a->lehrveranstaltung_id; + }, $lvsA), array_map(function ($a) { + return $a->lehrveranstaltung_id; + }, $lvsAtest)))) { + foreach ($lvsA as $lv) { + if (isset($lvszugewiesen[$lv->lehrveranstaltung_id]) && ($lvszugewiesen[$lv->lehrveranstaltung_id]->note == 0)) { + $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; + $lv->antrag_zugelassen = true; + } + + } + } else { + $lvsA = null; + } } $result = $this->getLvsByStgStsemAndSem( @@ -1035,7 +1130,7 @@ class AntragLib $semB, $ausbildungssemester, $antrag->prestudent_id, - $antrag->studiensemester_kurzbz + $sprache ); if (isError($result)) return $result; @@ -1050,10 +1145,14 @@ class AntragLib // TODO(manu): eventuelle Änderungen taggen } - return success([ + $result = [ '1' . $semA => $lvsA, '2' . $semB => $lvsB ?: [] - ]); + ]; + if ($repeat_last) + $result['repeat_last'] = true; + + return success($result); } public function getLvsByStgStsemAndSem( @@ -1062,7 +1161,7 @@ class AntragLib $studiensemester_kurzbz, $ausbildungssemester, $prestudent_id, - $note_stsem + $sprache ) { $this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel'); @@ -1091,19 +1190,31 @@ class AntragLib 'semester' => $ausbildungssemester ])); } - if (count($result) > 1) - return error($this->_ci->p->t('studierendenantrag', 'error_multiple_studienplan', [ - 'studiengang_kz' => $studiengang_kz, - 'studiensemester_kurzbz' => $studiensemester_kurzbz, - 'semester' => $ausbildungssemester - ])); + if (count($result) > 1) { + $langmap = array_unique(array_map(function ($a) { + return $a->sprache; + }, $result)); + if ($sprache + && count($langmap) == count($result) + && in_array($sprache, $langmap) + ) { + $result = array_filter($result, function ($a) use ($sprache) { + return $a->sprache == $sprache; + }); + } else { + return error($this->_ci->p->t('studierendenantrag', 'error_multiple_studienplan', [ + 'studiengang_kz' => $studiengang_kz, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'semester' => $ausbildungssemester + ])); + } + } $studienplan = current($result); return $this->_ci->StudienplanModel->getStudienplanLehrveranstaltungForPrestudent( $studienplan->studienplan_id, $ausbildungssemester, - $prestudent_id, - $note_stsem + $prestudent_id ); } @@ -1388,6 +1499,8 @@ class AntragLib $resultDetails->grund = $resultAntrag->grund; $resultDetails->studierendenantrag_id = $resultAntrag->studierendenantrag_id; $resultDetails->typ = $resultAntrag->typ; + $resultDetails->datum = $resultAntrag->datum; + $resultDetails->studiensemester_kurzbz = $resultAntrag->studiensemester_kurzbz; return success($resultDetails); } @@ -1489,9 +1602,9 @@ class AntragLib ); } - public function getFailedExamForPrestudent($prestudent_id) + public function getFailedExamForPrestudent($prestudent_id, $max_date = null, $studiensemester_kurzbz = null) { - return $this->_ci->PruefungModel->loadWhereCommitteeExamFailedForPrestudent($prestudent_id); + return $this->_ci->PruefungModel->loadWhereCommitteeExamFailedForPrestudent($prestudent_id, $max_date, $studiensemester_kurzbz); } public function saveLvs($lvArray) @@ -1605,6 +1718,7 @@ class AntragLib if ($student_uid) { $email = $this->_ci->StudentModel->getEmailFH($student_uid); + $vorlage = 'Sancho_Mail_Antrag_W_Student'; $sem_not_allowed = $sem_to_repeat = ''; $list_not_allowed = $list_to_repeat = $this->_ci->p->t('studierendenantrag', 'mail_part_error_no_lvs'); @@ -1612,6 +1726,12 @@ class AntragLib $result = $this->getLvsForAntrag($antrag_id); if (hasData($result)) { $lvs = getData($result); + $repeat_last = false; + if (isset($lvs['repeat_last'])) { + $repeat_last = true; + unset($lvs['repeat_last']); + $vorlage .= '_Lst'; + } foreach ($lvs as $sem => $lv_list) { $lvs_filtered = array_filter($lv_list, function ($el) { return property_exists($el, 'antrag_zugelassen') && $el->antrag_zugelassen; @@ -1634,7 +1754,7 @@ class AntragLib // NOTE(chris): Sancho mail sendSanchoMail( - 'Sancho_Mail_Antrag_W_Student', + $vorlage, [ 'antrag_id' => $antrag_id, 'stg' => $stg->bezeichnung, diff --git a/application/models/codex/Bismeldestichtag_model.php b/application/models/codex/Bismeldestichtag_model.php new file mode 100644 index 000000000..1a45f0fbd --- /dev/null +++ b/application/models/codex/Bismeldestichtag_model.php @@ -0,0 +1,14 @@ +dbTable = 'bis.tbl_bismeldestichtag'; + $this->pk = 'meldestichtag_id'; + } +} diff --git a/application/models/crm/Reihungstest_model.php b/application/models/crm/Reihungstest_model.php index ec1982ea6..86ebfd0af 100644 --- a/application/models/crm/Reihungstest_model.php +++ b/application/models/crm/Reihungstest_model.php @@ -322,7 +322,7 @@ class Reihungstest_model extends DB_Model JOIN lehre.tbl_studienplan ON (tbl_prestudentstatus.studienplan_id = tbl_studienplan.studienplan_id) LEFT JOIN bis.tbl_zgv ON (ps.zgv_code = tbl_zgv.zgv_code) WHERE rt_id = ? - AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) = \'Interessent\' + AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) IN (\'Interessent\', \'Bewerber\') AND tbl_prestudentstatus.studiensemester_kurzbz = rt.studiensemester_kurzbz AND bewerbung_abgeschicktamum IS NOT NULL AND bestaetigtam IS NOT NULL @@ -411,7 +411,7 @@ class Reihungstest_model extends DB_Model JOIN lehre.tbl_studienplan ON (tbl_prestudentstatus.studienplan_id = tbl_studienplan.studienplan_id) LEFT JOIN bis.tbl_zgv ON (ps.zgv_code = tbl_zgv.zgv_code) WHERE rt.studiengang_kz = ? - AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) = \'Interessent\' + AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) IN (\'Interessent\', \'Bewerber\') AND tbl_prestudentstatus.studiensemester_kurzbz = rt.studiensemester_kurzbz AND bewerbung_abgeschicktamum IS NOT NULL AND bestaetigtam IS NOT NULL @@ -462,7 +462,7 @@ class Reihungstest_model extends DB_Model LEFT JOIN bis.tbl_zgv ON (ps.zgv_code = tbl_zgv.zgv_code) LEFT JOIN PUBLIC.tbl_ort ON (tbl_rt_person.ort_kurzbz = tbl_ort.ort_kurzbz) WHERE rt_id = ? - AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) = \'Interessent\' + AND get_rolle_prestudent(prestudent_id, rt.studiensemester_kurzbz) IN (\'Interessent\', \'Bewerber\') AND tbl_prestudentstatus.studiensemester_kurzbz = rt.studiensemester_kurzbz AND bewerbung_abgeschicktamum IS NOT NULL AND bestaetigtam IS NOT NULL diff --git a/application/models/education/Pruefung_model.php b/application/models/education/Pruefung_model.php index e1d668293..50109d2f1 100644 --- a/application/models/education/Pruefung_model.php +++ b/application/models/education/Pruefung_model.php @@ -139,6 +139,8 @@ class Pruefung_model extends DB_Model $this->db->where_not_in("n.note", $note_blacklist); $this->db->where_in("p.pruefungstyp_kurzbz", ['kommPruef','zusKommPruef']); + $this->addOrder('p.datum', 'DESC'); + return $this->load(); } @@ -201,12 +203,19 @@ class Pruefung_model extends DB_Model * * @return stdClass */ - public function loadWhereCommitteeExamFailedForPrestudent($prestudent_id) + public function loadWhereCommitteeExamFailedForPrestudent($prestudent_id, $max_date = null, $studiensemester_kurzbz = null) { $this->withDetailsForStudierendenAntrag(); $this->db->where('ps.prestudent_id', $prestudent_id); + if ($max_date !== null) { + $this->db->where('p.datum <', $max_date); + } + if ($studiensemester_kurzbz !== null) { + $this->db->where('le.studiensemester_kurzbz', $studiensemester_kurzbz); + } + return $this->loadWhereCommitteeExamsFailed(); } diff --git a/application/models/education/Studierendenantrag_model.php b/application/models/education/Studierendenantrag_model.php index a11df6981..23d69b13b 100644 --- a/application/models/education/Studierendenantrag_model.php +++ b/application/models/education/Studierendenantrag_model.php @@ -26,9 +26,10 @@ class Studierendenantrag_model extends DB_Model return $this->loadForStudiengaenge($studiengaenge, $typ, $this->StudierendenantragstatusModel::STATUS_CREATED); } - public function loadForStudiengaenge($studiengaenge, $typ = null, $status = null) + public function loadForStudiengaenge($studiengaenge, $typ = null, $status = null, $sql = null) { - $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + if ($sql == null) + $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; $this->addSelect('UPPER(stg.typ) || UPPER(stg.kurzbz) || \' \' || stg.bezeichnung AS bezeichnung'); $this->addSelect('bezeichnung_mehrsprachig[(' . $sql . ')] AS orgform', false); @@ -73,6 +74,44 @@ class Studierendenantrag_model extends DB_Model return $this->loadWhere($where); } + public function loadActiveForStudiengaenge($studiengaenge) + { + // NOTE(chris): get language before changing things in the global db object because getUserLanguage() might use it and it should not have been tampered with + $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + + $this->db->group_start(); + $this->db->where_not_in('s.studierendenantrag_statustyp_kurzbz', [ + Studierendenantragstatus_model::STATUS_CANCELLED, + Studierendenantragstatus_model::STATUS_APPROVED, + Studierendenantragstatus_model::STATUS_REJECTED, + Studierendenantragstatus_model::STATUS_OBJECTION_DENIED, + Studierendenantragstatus_model::STATUS_DEREGISTERED + ]); + $this->db->or_group_start(); + $this->db->where('s.studierendenantrag_statustyp_kurzbz', Studierendenantragstatus_model::STATUS_APPROVED); + $this->db->where('tbl_studierendenantrag.typ', Studierendenantrag_model::TYP_ABMELDUNG_STGL); + $this->db->group_end(); + $this->db->group_end(); + + return $this->loadForStudiengaenge($studiengaenge, null, null, $sql); + } + + public function loadStgsWithAntraege($studiengaenge) + { + $this->addDistinct(); + $this->addSelect('UPPER(stg.typ) || UPPER(stg.kurzbz) || \' \' || stg.bezeichnung AS bezeichnung'); + $this->addSelect('p.studiengang_kz'); + + $this->addJoin('public.tbl_prestudent p', 'prestudent_id'); + $this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz'); + + $this->addOrder('UPPER(stg.typ) || UPPER(stg.kurzbz) || \' \' || stg.bezeichnung'); + + $this->db->where_in('p.studiengang_kz', $studiengaenge); + + return $this->load(); + } + public function isInStudiengang($studierendenantrag_id, $studiengaenge) { $this->addJoin('public.tbl_prestudent', 'prestudent_id'); @@ -124,6 +163,7 @@ class Studierendenantrag_model extends DB_Model $this->addSelect('p.studiengang_kz'); $this->addSelect('stg.bezeichnung'); $this->addSelect('s.ausbildungssemester'); + $this->addSelect('plan.sprache'); $this->addSelect('COALESCE(plan.orgform_kurzbz, s.orgform_kurzbz, stg.orgform_kurzbz) AS orgform_kurzbz'); $this->addJoin( diff --git a/application/models/education/Studierendenantraglehrveranstaltung_model.php b/application/models/education/Studierendenantraglehrveranstaltung_model.php index 47a07ecfe..4318c773e 100644 --- a/application/models/education/Studierendenantraglehrveranstaltung_model.php +++ b/application/models/education/Studierendenantraglehrveranstaltung_model.php @@ -65,20 +65,40 @@ class Studierendenantraglehrveranstaltung_model extends DB_Model 'stat.studierendenantrag_status_id = campus.get_status_id_studierendenantrag(a.studierendenantrag_id)' ); $this->addJoin('public.tbl_student s', 'prestudent_id'); - $this->addJoin( - 'lehre.tbl_zeugnisnote z', - 'z.lehrveranstaltung_id=lv.lehrveranstaltung_id AND z.student_uid=s.student_uid AND z.studiensemester_kurzbz=a.studiensemester_kurzbz', - 'LEFT' - ); + + // NOTE(chris): last offizell note + $this->addJoin('( + SELECT z.* + FROM lehre.tbl_zeugnisnote z + LEFT JOIN public.tbl_studiensemester zs + USING(studiensemester_kurzbz) + JOIN ( + SELECT zi.lehrveranstaltung_id, zi.student_uid, MAX(zis.start) AS start + FROM lehre.tbl_zeugnisnote zi + LEFT JOIN lehre.tbl_note zin + USING(note) + LEFT JOIN public.tbl_studiensemester zis + USING(studiensemester_kurzbz) + WHERE zin.aktiv AND zin.offiziell + GROUP BY zi.lehrveranstaltung_id, zi.student_uid + ) zx + ON ( + z.lehrveranstaltung_id=zx.lehrveranstaltung_id + AND z.student_uid=zx.student_uid + AND zs.start = zx.start + )) z', 'z.lehrveranstaltung_id=lv.lehrveranstaltung_id AND z.student_uid=s.student_uid', 'LEFT'); $this->addJoin('lehre.tbl_note zn', 'z.note = zn.note', 'LEFT'); + $this->load->config('studierendenantrag'); + $note_intern_angerechntet = $this->config->item('wiederholung_note_angerechnet'); + return $this->loadWhere([ 'ps.prestudent_id' => $prestudent_id, 'a.typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG, 'stat.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, 'n.note <> ' => 0, $this->dbTable . '.studiensemester_kurzbz' => $studiensemester_kurzbz, - '(n.note<>19 OR (z.note IS NOT NULL AND zn.positiv))' => null + '(n.note<>' . $this->db->escape($note_intern_angerechntet) . ' OR (z.note IS NOT NULL AND zn.positiv))' => null ]); } } diff --git a/application/models/education/Studierendenantragstatus_model.php b/application/models/education/Studierendenantragstatus_model.php index b4bf3938b..c134cc4ee 100644 --- a/application/models/education/Studierendenantragstatus_model.php +++ b/application/models/education/Studierendenantragstatus_model.php @@ -14,6 +14,7 @@ class Studierendenantragstatus_model extends DB_Model const STATUS_REQUESTSENT_2 = 'ZweiteAufforderungVersandt'; const STATUS_OBJECTED = 'Beeinsprucht'; const STATUS_OBJECTION_DENIED = 'EinspruchAbgelehnt'; + const STATUS_DEREGISTERED = 'Abgemeldet'; /** * Constructor diff --git a/application/models/organisation/Studienplan_model.php b/application/models/organisation/Studienplan_model.php index 66ec06ba8..8422f4607 100644 --- a/application/models/organisation/Studienplan_model.php +++ b/application/models/organisation/Studienplan_model.php @@ -60,7 +60,7 @@ class Studienplan_model extends DB_Model )); } - public function getStudienplanLehrveranstaltungForPrestudent($studienplan_id, $semester, $prestudent_id, $note_stsem) + public function getStudienplanLehrveranstaltungForPrestudent($studienplan_id, $semester, $prestudent_id) { $lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage()); $sql = 'SELECT student_uid FROM public.tbl_student WHERE prestudent_id=' . $this->escape($prestudent_id); @@ -75,11 +75,27 @@ class Studienplan_model extends DB_Model $this->addJoin('lehre.tbl_studienplan_lehrveranstaltung', 'studienplan_id'); $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); - $this->addJoin( - 'lehre.tbl_zeugnisnote zn', - 'zn.lehrveranstaltung_id=lv.lehrveranstaltung_id AND zn.student_uid=(' . $sql . ') AND zn.studiensemester_kurzbz=' . $this->escape($note_stsem), - 'LEFT' - ); + // NOTE(chris): last offizell note + $this->addJoin('( + SELECT z.* + FROM lehre.tbl_zeugnisnote z + LEFT JOIN public.tbl_studiensemester zs + USING(studiensemester_kurzbz) + JOIN ( + SELECT zi.lehrveranstaltung_id, zi.student_uid, MAX(zis.start) AS start + FROM lehre.tbl_zeugnisnote zi + LEFT JOIN lehre.tbl_note zin + USING(note) + LEFT JOIN public.tbl_studiensemester zis + USING(studiensemester_kurzbz) + WHERE zin.aktiv AND zin.offiziell + GROUP BY zi.lehrveranstaltung_id, zi.student_uid + ) zx + ON ( + z.lehrveranstaltung_id=zx.lehrveranstaltung_id + AND z.student_uid=zx.student_uid + AND zs.start = zx.start + )) zn', 'zn.lehrveranstaltung_id=lv.lehrveranstaltung_id AND zn.student_uid=( ' . $sql . ')', 'LEFT'); $this->addJoin('lehre.tbl_note n', 'n.note=zn.note', 'LEFT'); $this->addOrder('lehre.tbl_studienplan_lehrveranstaltung.sort'); diff --git a/application/views/codex/bismeldestichtag.php b/application/views/codex/bismeldestichtag.php new file mode 100644 index 000000000..37af16cc6 --- /dev/null +++ b/application/views/codex/bismeldestichtag.php @@ -0,0 +1,75 @@ + 'Bismeldestichtage', + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'vue3' => true, + 'filtercomponent' => true, + 'navigationcomponent' => true, + 'tabulator5' => true, + 'customCSSs' => array('vendor/vuejs/vuedatepicker_css/main.css'), + 'customJSs' => array('vendor/vuejs/vuedatepicker_js/vue-datepicker.iife.js'), + 'customJSModules' => array('public/js/apps/Bismeldestichtag/Bismeldestichtag.js') + ); + + $this->load->view('templates/FHC-Header', $includesArray); +?> +
p->t('uhstat', 'uhstat1AnmeldungEinleitungstext') ?>
++ p->t('uhstat', 'uhstat1EinleitungSvnrtext') ?> +