diff --git a/application/controllers/components/Antrag/Leitung.php b/application/controllers/components/Antrag/Leitung.php index 8d333d5b8..437030d08 100644 --- a/application/controllers/components/Antrag/Leitung.php +++ b/application/controllers/components/Antrag/Leitung.php @@ -116,6 +116,96 @@ class Leitung extends FHC_Controller $this->outputJsonSuccess($studierendenantrag_id); } + public function pauseAntrag() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + [ + 'isEntitledToPauseAntrag', + [$this->antraglib, 'isEntitledToPauseAntrag'] + ], + [ + 'antragCanBeManualPaused', + [$this->antraglib, 'antragCanBeManualPaused'] + ] + ], + [ + 'isEntitledToPauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'antragCanBeManualPaused' => $this->p->t( + 'studierendenantrag', + 'error_not_pauseable', + ['id' => $this->input->post('studierendenantrag_id')] + ) + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->pauseAntrag($studierendenantrag_id, getAuthUID()); + + if (isError($result)) + return $this->outputJsonError(['studierendenantrag_id' => getError($result)]); + + $this->outputJsonSuccess($studierendenantrag_id); + } + + public function unpauseAntrag() + { + $this->load->library('form_validation'); + + $_POST = json_decode($this->input->raw_input_stream, true); + + $this->form_validation->set_rules( + 'studierendenantrag_id', + 'Studierenden Antrag', + [ + 'required', + [ + 'isEntitledToUnpauseAntrag', + [$this->antraglib, 'isEntitledToUnpauseAntrag'] + ], + [ + 'antragCanBeManualUnpaused', + [$this->antraglib, 'antragCanBeManualUnpaused'] + ] + ], + [ + 'isEntitledToUnpauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'), + 'antragCanBeManualUnpaused' => $this->p->t( + 'studierendenantrag', + 'error_not_paused', + ['id' => $this->input->post('studierendenantrag_id')] + ) + ] + ); + + if ($this->form_validation->run() == false) + { + return $this->outputJsonError($this->form_validation->error_array()); + } + + $studierendenantrag_id = $this->input->post('studierendenantrag_id'); + + $result = $this->antraglib->unpauseAntrag($studierendenantrag_id, getAuthUID()); + + if (isError($result)) + return $this->outputJsonError(['studierendenantrag_id' => getError($result)]); + + $this->outputJsonSuccess($studierendenantrag_id); + } + public function objectAntrag() { $this->load->library('form_validation'); diff --git a/application/controllers/components/Antrag/Unterbrechung.php b/application/controllers/components/Antrag/Unterbrechung.php index 33bd0035d..f19139e00 100644 --- a/application/controllers/components/Antrag/Unterbrechung.php +++ b/application/controllers/components/Antrag/Unterbrechung.php @@ -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, null); $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)]); } diff --git a/application/controllers/components/Antrag/Wiederholung.php b/application/controllers/components/Antrag/Wiederholung.php index 418d05f45..2c672be54 100644 --- a/application/controllers/components/Antrag/Wiederholung.php +++ b/application/controllers/components/Antrag/Wiederholung.php @@ -161,6 +161,18 @@ class Wiederholung extends FHC_Controller { return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]); } + elseif ($result == -1) + { + $result = $this->PrestudentstatusModel->getLastStatus($prestudent_id); + if (isError($result)) + return $this->outputJsonError(['db' => getError($result)]); + if (!hasData($result)) + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_prestudentstatus', [ + 'prestudent_id' => $prestudent_id + ])]); + if (!in_array(current(getData($result))->status_kurzbz, $this->config->item('antrag_prestudentstatus_whitelist'))) + return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]); + } elseif ($result == -2) { return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_antrag_exists')]); @@ -241,7 +253,8 @@ class Wiederholung extends FHC_Controller if (!hasData($result)) return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $antrag_id])); $antrag = current(getData($result)); - if ($antrag->status != Studierendenantragstatus_model::STATUS_CREATED && $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED) + if ($antrag->status != Studierendenantragstatus_model::STATUS_CREATED + && $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED) return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_locked')); } diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index 131cfdced..717561589 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -19,6 +19,8 @@ class AntragJob extends JOB_Controller // Loads SanchoHelper $this->load->helper('hlp_sancho_helper'); + $this->load->library('AntragLib'); + // Load Model $this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); $this->load->model('education/Studierendenantragstatus_model', 'StudierendenantragstatusModel'); @@ -172,7 +174,16 @@ class AntragJob extends JOB_Controller $cc = $leitung['Details']->email; // NOTE(chris): Sancho mail - if (sendSanchoMail("Sancho_Mail_Antrag_Stgl", $data, $to, 'Anträge - Aktion(en) erforderlich', DEFAULT_SANCHO_HEADER_IMG, DEFAULT_SANCHO_FOOTER_IMG, '', $cc)) + if (sendSanchoMail( + "Sancho_Mail_Antrag_Stgl", + $data, + $to, + 'Anträge - Aktion(en) erforderlich', + DEFAULT_SANCHO_HEADER_IMG, + DEFAULT_SANCHO_FOOTER_IMG, + '', + $cc + )) $count++; } @@ -306,11 +317,64 @@ class AntragJob extends JOB_Controller foreach ($prestudents as $prestudent) { - $result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz, $insertvon); - if (isError($result)) + $result = $this->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $prestudent->studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_DEREGISTERED, + 'insertvon' => 'AntragJob' + ]); + if (isError($result)) { $this->logError(getError($result)); - else - $count++; + } else { + $deregisterStatus = getData($result); + + $result = $this->antraglib->pauseAntrag( + $prestudent->studierendenantrag_id, + Studierendenantragstatus_model::INSERTVON_DEREGISTERED + ); + if (isError($result)) + $this->logError(getError($result)); + + $result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, '', $insertvon); + if (isError($result)) { + $this->StudierendenantragstatusModel->delete($deregisterStatus); + $this->logError(getError($result)); + } else { + $count++; + + $datum_kp = new DateTime($prestudent->datum); + $dataMail = array( + 'name'=> trim($prestudent->vorname . ' '. $prestudent->nachname), + 'vorname' => $prestudent->vorname, + 'nachname' => $prestudent->nachname, + 'pers_kz'=> $prestudent->matrikelnr, + 'stg' => $prestudent->bezeichnung, + 'lvbezeichnung' => $prestudent->lvbezeichnung, + 'datum_kp' => $datum_kp->format('d.m.Y'), + 'studiensemester'=> $prestudent->studiensemester_kurzbz, + 'Orgform'=> $prestudent->orgform, + 'prestudent_id' => $prestudent->prestudent_id, + 'fristablauf' => $dateDeadline->format('d.m.Y') + ); + + $email = $this->StudentModel->getEmailFH($this->StudentModel->getUID($prestudent->prestudent_id)); + // Mail to Student + if (!sendSanchoMail('Sancho_Mail_Antrag_W_DL_Stud', $dataMail, $email, 'Wiederholung: Frist abgelaufen')) { + $this->logWarning("Failed to send Notification to " . $email); + } + + $result = $this->StudiengangModel->load($prestudent->studiengang_kz); + if (!hasData($result)) { + $this->logWarning('No Studiengang found'); + continue; + } + $studiengang = current(getData($result)); + $email = $studiengang->email; + // Mail to Assistenz + if (!sendSanchoMail('Sancho_Mail_Antrag_W_DL_Assist', $dataMail, $email, 'Wiederholung: Frist abgelaufen')) { + $this->logWarning("Failed to send Notification to " . $email); + } + } + } } $this->logInfo($count . " Students set to Abbrecher"); } @@ -326,8 +390,6 @@ class AntragJob extends JOB_Controller { $this->logInfo('Start Job handleAbmeldungenStglDeadline'); - $this->load->library('AntragLib'); - $insertvon = $this->config->item('antrag_job_systemuser'); if (!$insertvon) { $this->logError('Config "antrag_job_systemuser" nicht gesetzt'); @@ -351,7 +413,10 @@ class AntragJob extends JOB_Controller $this->StudierendenantragModel->addSelect('s.insertamum'); $this->StudierendenantragModel->addSelect('s.insertvon'); - $this->StudierendenantragModel->db->where_in('public.get_rolle_prestudent(prestudent_id, studiensemester_kurzbz)', $this->config->item('antrag_prestudentstatus_whitelist')); + $this->StudierendenantragModel->db->where_in( + 'public.get_rolle_prestudent(prestudent_id, studiensemester_kurzbz)', + $this->config->item('antrag_prestudentstatus_whitelist') + ); $result = $this->StudierendenantragModel->getWithLastStatusWhere([ 'typ' => Studierendenantrag_model::TYP_ABMELDUNG_STGL, @@ -380,6 +445,10 @@ class AntragJob extends JOB_Controller else { $deregisterStatus = getData($result); + $result = $this->antraglib->pauseAntrag($antrag->studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_DEREGISTERED); + if (isError($result)) + $this->logError(getError($result)); + $result = $this->prestudentlib->setAbbrecher( $antrag->prestudent_id, $antrag->studiensemester_kurzbz, @@ -425,7 +494,6 @@ class AntragJob extends JOB_Controller $this->logWarning("Failed to send Notification to " . $email); } } - } } $this->logInfo($count . "/" . count($antraege) . " Students set to Abbrecher"); @@ -556,12 +624,6 @@ class AntragJob extends JOB_Controller } } - $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); - $result = $this->PrestudentstatusModel->loadLastWithStgDetails($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz); - if (hasData($result)) { - $ausbildungssemester = current(getData($result))->semester; - } - $dataMail = array( 'name'=> trim($prestudent->vorname . ' '. $prestudent->nachname), 'vorname' => $prestudent->vorname, @@ -578,7 +640,7 @@ class AntragJob extends JOB_Controller 'fristablauf' => $fristende->format('d.m.Y'), 'pre_wiederholer_sem' => $next_sem, 'wiederholer_sem' => $sem_after_next_sem, - 'sem' => $ausbildungssemester + 'sem' => $prestudent->ausbildungssemester ); // NOTE(chris): Sancho mail diff --git a/application/controllers/jobs/ESIJob.php b/application/controllers/jobs/ESIJob.php new file mode 100644 index 000000000..c9a558a46 --- /dev/null +++ b/application/controllers/jobs/ESIJob.php @@ -0,0 +1,165 @@ +load->model('person/Person_model', 'PersonModel'); + $this->load->model('person/Kennzeichen_model', 'KennzeichenModel'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Initialises generateESI job, handles job queue, logs infos/errors + */ + public function generateESI() + { + //$jobType = 'DVUHSendPruefungsaktivitaeten'; + $this->logInfo(ESIScheduler::JOB_TYPE_GENERATE_ESI.' job start'); + + // Gets the latest jobs + $lastJobs = $this->getLastJobs(ESIScheduler::JOB_TYPE_GENERATE_ESI); + + if (isError($lastJobs)) + { + $this->logError(getCode($lastJobs).': '.getError($lastJobs), ESIScheduler::JOB_TYPE_GENERATE_ESI); + } + else + { + $this->updateJobs( + getData($lastJobs), // Jobs to be updated + array(JobsQueueLib::PROPERTY_START_TIME), // Job properties to be updated + array(date('Y-m-d H:i:s')) // Job properties new values + ); + + $person_arr = $this->_getInputObjArray(getData($lastJobs)); + + foreach ($person_arr as $persobj) + { + if (!isset($persobj->person_id)) + $this->logError("Error when generating ESI: invalid parameters"); + else + { + $person_id = $persobj->person_id; + + // check if there already is an active ESI + $this->KennzeichenModel->addSelect('1'); + $activeKennzeichenRes = $this->KennzeichenModel->loadWhere( + array('person_id' => $person_id, 'kennzeichentyp_kurzbz' => ESIScheduler::KENNZEICHENTYP_KURZBZ, 'aktiv' => true) + ); + + if (hasData($activeKennzeichenRes)) + { + $this->logError("Active ESI for person Id $person_id already exists"); + continue; + } + + // get Matrikelnr for person for which ESI should be generated + $this->PersonModel->addSelect('matr_nr'); + $personRes = $this->PersonModel->load($person_id); + + if (!hasData($personRes)) + { + $this->logError("Person with Id $person_id not found"); + continue; + } + + $matr_nr = getData($personRes)[0]->matr_nr; + + if (isEmptyString($matr_nr)) + { + $this->logError("Matrikelnummer for person with Id $person_id is empty"); + continue; + } + + $esi = self::ESI_PREFIX.$matr_nr; + + // check if ESI was already used + $this->KennzeichenModel->addSelect('1'); + $existingKennzeichenRes = $this->KennzeichenModel->loadWhere( + array('person_id' => $person_id, 'kennzeichentyp_kurzbz' => ESIScheduler::KENNZEICHENTYP_KURZBZ, 'inhalt' => $esi) + ); + + if (hasData($existingKennzeichenRes)) + { + $this->logError("ESI $esi for person Id $person_id already exists"); + continue; + } + + // if everything ok, save the esi for the person + $saveEsiResult = $this->KennzeichenModel->insert( + array( + 'person_id' => $person_id, + 'kennzeichentyp_kurzbz' => ESIScheduler::KENNZEICHENTYP_KURZBZ, + 'inhalt' => $esi, + 'aktiv' => true, + 'insertvon' => self::INSERT_VON + ) + ); + + if (isError($saveEsiResult)) + { + $this->logError("Error when sending ESI, person Id $person_id ".getError($saveEsiResult)); + } + } + } + + // Update jobs properties values + $this->updateJobs( + getData($lastJobs), // Jobs to be updated + array(JobsQueueLib::PROPERTY_STATUS, JobsQueueLib::PROPERTY_END_TIME), // Job properties to be updated + array(JobsQueueLib::STATUS_DONE, date('Y-m-d H:i:s')) // Job properties new values + ); + + if (hasData($lastJobs)) $this->updateJobsQueue(ESIScheduler::JOB_TYPE_GENERATE_ESI, getData($lastJobs)); + } + + $this->logInfo(ESIScheduler::JOB_TYPE_GENERATE_ESI.' job stop'); + } + + // -------------------------------------------------------------------------------------------- + // Private methods + + /** + * Extracts input data from jobs. + * @param $jobs + * @return array with jobinput + */ + private function _getInputObjArray($jobs) + { + $mergedUsersArray = array(); + + if (count($jobs) == 0) return $mergedUsersArray; + + foreach ($jobs as $job) + { + $decodedInput = json_decode($job->input); + if ($decodedInput != null) + { + foreach ($decodedInput as $el) + { + $mergedUsersArray[] = $el; + } + } + } + return $mergedUsersArray; + } +} diff --git a/application/controllers/jobs/schedulers/ESIScheduler.php b/application/controllers/jobs/schedulers/ESIScheduler.php new file mode 100644 index 000000000..3ab858937 --- /dev/null +++ b/application/controllers/jobs/schedulers/ESIScheduler.php @@ -0,0 +1,108 @@ +load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * Creates jobs queue entries for generateESI job. + * @param string $studiensemester_kurzbz semester for which ESIs should be generated + */ + public function generateESI($studiensemester_kurzbz = null) + { + // if no semester given, get current studiensemester + if (!isset($studiensemester_kurzbz)) + { + $semRes = $this->StudiensemesterModel->getAkt(); + + if (hasData($semRes)) + { + $studiensemester_kurzbz = getData($semRes)[0]->studiensemester_kurzbz; + } + } + + if (isset($studiensemester_kurzbz)) + { + $this->logInfo('Start job queue scheduler '.self::JOB_TYPE_GENERATE_ESI); + + $qry = " + SELECT + DISTINCT person_id + FROM + public.tbl_person pers + JOIN public.tbl_prestudent ps USING (person_id) + JOIN public.tbl_prestudentstatus pss USING (prestudent_id) + WHERE + pss.studiensemester_kurzbz = ? + AND pers.matr_nr IS NOT NULL + AND pss.status_kurzbz IN ? + AND NOT EXISTS ( -- has no ESI yet + SELECT 1 + FROM + public.tbl_kennzeichen + WHERE + person_id = pers.person_id + AND kennzeichentyp_kurzbz = ? + AND aktiv + ) + AND NOT EXISTS ( -- making sure it's not an incoming + SELECT 1 + FROM + public.tbl_prestudentstatus + WHERE + prestudent_id = ps.prestudent_id + AND status_kurzbz = 'Incoming' + )"; + + $db = new DB_Model(); + $jobInputResult = $db->execReadOnlyQuery($qry, array($studiensemester_kurzbz, $this->_active_status_kurzbz, self::KENNZEICHENTYP_KURZBZ)); + + // If an error occured then log it + if (isError($jobInputResult)) + { + $this->logError(getError($jobInputResult)); + } + elseif (hasData($jobInputResult)) // if persons found + { + // Add the new job to the jobs queue + $addNewJobResult = $this->addNewJobsToQueue( + self::JOB_TYPE_GENERATE_ESI, // job type + $this->generateJobs( // gnerate the structure of the new job + JobsQueueLib::STATUS_NEW, + json_encode(getData($jobInputResult)) + ) + ); + + // If error occurred return it + if (isError($addNewJobResult)) $this->logError(getError($addNewJobResult)); + } + } + else + { + $this->logError('Error when getting Studiensemester'); + } + + $this->logInfo('End job queue scheduler '.self::JOB_TYPE_GENERATE_ESI); + } +} diff --git a/application/controllers/system/MigrateContract.php b/application/controllers/system/MigrateContract.php index c86b1366c..99b894473 100644 --- a/application/controllers/system/MigrateContract.php +++ b/application/controllers/system/MigrateContract.php @@ -29,13 +29,11 @@ class MigrateContract extends CLI_Controller $this->load->model('person/benutzerfunktion_model', 'BenutzerfunktionModel'); $this->matching_ba1_vertragsart = array( - //'101'=>'DV zum Bund', // TODO was tun wir damit - '101'=>'freierdv', // TODO was tun wir damit + '101'=>'externerlehrender', '102'=>'DV anderen Gebietskörperschaft', '103'=>'echterdv', - //'104'=>'Lehr- oder Ausbildungsverhältnis', // TODO was tun wir mit dem? '104'=>'studentischehilfskr', - '105'=>'freierdv', + '105'=>'externerlehrender', '106'=>'Andere Bildungseinrichtung', '107'=>'werkvertrag', '108'=>'studentischehilfskr', diff --git a/application/controllers/system/MigrateSalary.php b/application/controllers/system/MigrateSalary.php index e8771f913..4bd1d3e7d 100644 --- a/application/controllers/system/MigrateSalary.php +++ b/application/controllers/system/MigrateSalary.php @@ -3,7 +3,7 @@ * Job zur einmaligen Import der Gehälter * * Aufruf (Encode / im Filenmae mit %2F): - * php index.ci.php system/MigrateSalary/import filename + * php index.ci.php system/MigrateSalary/import filename * */ /* @@ -34,7 +34,7 @@ class MigrateSalary extends CLI_Controller $this->load->model('vertragsbestandteil/VertragsbestandteilStunden_model','VertragsbestandteilStundenModel'); $this->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model','VertragsbestandteilFreitextModel'); $this->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model','VertragsbestandteilFunktionModel'); - + } // ----------------------------------------------------------------------------------------------------------------- @@ -45,7 +45,7 @@ class MigrateSalary extends CLI_Controller */ public function import($file) { - + // CSV Laden $file = urldecode($file); if($handle = fopen($file, "r")) @@ -108,8 +108,8 @@ class MigrateSalary extends CLI_Controller } else { - if ($data[$i] != '' - && isset($gehaltsarr[$gehaltsindex]) && isset($gehaltsarr[$gehaltsindex]['betrag']) + if ($data[$i] != '' + && isset($gehaltsarr[$gehaltsindex]) && isset($gehaltsarr[$gehaltsindex]['betrag']) && $gehaltsarr[$gehaltsindex]['betrag'] == $data[$i]) { // Gehalt bleibt gleich @@ -138,30 +138,31 @@ class MigrateSalary extends CLI_Controller } } } - + $monat++; } // Zeile zu Ende - Ende Datum setzen wenn nicht für alle Monate ein Eintrag vorhanden ist if($monat < count($monate) && isset($gehaltsarr[$gehaltsindex])) - $gehaltsarr[$gehaltsindex]['ende'] == $monate[$monat-1]; - + $gehaltsarr[$gehaltsindex]['ende'] = $monate[$monat-1]; + } $this->_saveGehalt($lastuser, $gehaltsarr); } } /** - * Ermittelt das passende Dienstverhaeltnis uns speichert den + * Ermittelt das passende Dienstverhaeltnis uns speichert den * Gehaltsbestandteil */ private function _saveGehalt($uid, $gehaltsarr) - { + { $failed = false; $this->db->trans_begin(); foreach($gehaltsarr as $row_gehalt) { + //var_dump($row_gehalt); $auszahlungen = 14; $dvid = ''; $vbsid = ''; @@ -171,16 +172,18 @@ class MigrateSalary extends CLI_Controller //DV und VBS Ermitteln $dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $row_gehalt['beginn']); - if (!hasData($dv)) + // Wenn keiner gefunden wird oder mit Monatsersteln nur ein externer gefunden wird, weitersuchen ob im Monat noch ein + // "richtiger" Vertrag startet + if (!hasData($dv) || getData($dv)[0]->vertragsart_kurzbz='externerLehrender') { $date = new DateTime($row_gehalt['beginn']); $date->modify('last day of this month'); $last_day_this_month = $date->format('Y-m-d'); - // Wenn mit Monatsersten kein DV gefunden wird, wird stattdessen mit Monatsletzten gesucht um DVs zu finden + // Wenn mit Monatsersten kein DV gefunden wird, wird stattdessen mit Monatsletzten gesucht um DVs zu finden // für Personen die erst später im Monat in ihr DV einsteigen - $dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $last_day_this_month); - + $dv = $this->DienstverhaeltnisModel->getDVByPersonUIDOverlapping($uid, $this->OE_DEFAULT, $row_gehalt['beginn'], $last_day_this_month); + if (!hasData($dv)) { echo "\nKein passendes DV gefunden für User ".$uid." und Datum ".$row_gehalt['beginn']." -> ROLLBACK\n"; @@ -189,34 +192,53 @@ class MigrateSalary extends CLI_Controller } else { - // Gehaltsstart wird auf den Start des DV korrigiert wenn nicht der Monatserste - $row_gehalt['beginn'] = getData($dv)[0]->von; + $resultdata = getData($dv); + foreach($resultdata as $dvdata) + { + // Externer DV wird in Monatsmitte zu echten DV - daher weitersuchen bei externenDVs da + // diese sowieso kein Gehalt zugeordnet haben + if($dvdata->vertragsart_kurzbz != 'externerLehrender') + { + $dvid = $dvdata->dienstverhaeltnis_id; + // Gehaltsstart wird auf den Start des DV korrigiert wenn nicht der Monatserste + // nur wenn das Beginndatum vor dem DV-Start liegt da sonst das Datum korrigiert wird + // wenn der Vertragsbestandteil wechselt + if($row_gehalt['beginn'] < $dvdata->von) + $row_gehalt['beginn'] = $dvdata->von; + break; + } + } } } - - $resultdata = getData($dv); - if (count($resultdata) !== 1) + else { - echo "Kein oder Mehrere DVs gefunden -> ROLLBACK"; + $resultdata = getData($dv); + + if (count($resultdata) == 1) + $dvid = $resultdata[0]->dienstverhaeltnis_id; + } + + if ($dvid == '') + { + echo "Kein oder mehrere DVs gefunden -> ROLLBACK"; $failed = true; break; } - $dvid = $resultdata[0]->dienstverhaeltnis_id; - $allin = $this->_isAllIn($dvid, $row_gehalt['beginn']); $db = new DB_Model(); $resultVBS = $this->_getVBS($dvid, $row_gehalt['beginn']); - + if (hasData($resultVBS)) { $vbsid = getData($resultVBS)[0]->vertragsbestandteil_id; + $vbsbis = getData($resultVBS)[0]->bis; } else { - echo "Vertragsbestandteil wurde nicht gefunden -> ROLLBACK"; + echo "Vertragsbestandteil fuer $uid DV $dvid wurde nicht gefunden mit Beginn ".$row_gehalt['beginn']."-> ROLLBACK"; $failed = true; break; } @@ -246,7 +268,7 @@ class MigrateSalary extends CLI_Controller ); if (isset($row_gehalt['ende']) && $row_gehalt['ende']!='') $data['bis'] = $row_gehalt['ende']; - + $resultVBS = $this->VertragsbestandteilModel->Insert($data); if(!isSuccess($resultVBS)) { @@ -286,7 +308,7 @@ class MigrateSalary extends CLI_Controller ); if (isset($row_gehalt['ende']) && $row_gehalt['ende']!='') $data['bis'] = $row_gehalt['ende']; - + $resultVBS = $this->VertragsbestandteilModel->Insert($data); if(!isSuccess($resultVBS)) { @@ -356,16 +378,24 @@ class MigrateSalary extends CLI_Controller $date->modify('last day of this month'); $last_day_this_month = $date->format('Y-m-d'); - // TODO: wenn das Dienstverhaeltnis in diesem Monat endet und nicht der Monatsletzte ist, + // Wenn das Dienstverhaeltnis in diesem Monat endet und nicht der Monatsletzte ist, // dann muss hier das Ende Datum des DV stehen bzw das Ende // oder das Ende des VBS falls die Person in der Monatsmitte Stunden wechselt $data['bis'] = $last_day_this_month; + + // Wenn der Vertragsbestandteil endet bevor das Gehalt endet, dann wir das Gehaltsende auf VBS Ende gesetzt + //echo "Ende des VBS: $vbsbis Ende des Gehalt: ".$data['bis']; + if ($vbsbis != '' && $vbsbis < $data['bis']) + { + $data['bis'] = $vbsbis; + //echo "Gehalt auf vbs ende gesetzt"; + } } $ret = $this->GehaltsbestandteilModel->insert($data, $this->GehaltsbestandteilModel->getEncryptedColumns() ); - } + } if(!$failed) { @@ -375,7 +405,7 @@ class MigrateSalary extends CLI_Controller { echo "ROLLBACK"; $this->db->trans_rollback(); - } + } } /** @@ -386,17 +416,17 @@ class MigrateSalary extends CLI_Controller $db = new DB_Model(); $qry = " - SELECT - * - FROM - hr.tbl_vertragsbestandteil + SELECT + * + FROM + hr.tbl_vertragsbestandteil JOIN hr.tbl_vertragsbestandteil_freitext USING(vertragsbestandteil_id) - WHERE - dienstverhaeltnis_id=".$db->escape($dvid)." - AND vertragsbestandteiltyp_kurzbz='freitext' + WHERE + dienstverhaeltnis_id=".$db->escape($dvid)." + AND vertragsbestandteiltyp_kurzbz='freitext' AND ".$db->escape($datum)." BETWEEN von AND COALESCE(bis, '2999-12-31') AND freitexttyp_kurzbz='allin'"; - + $resultAllIn = $db->execReadOnlyQuery($qry); if (hasData($resultAllIn)) @@ -410,15 +440,15 @@ class MigrateSalary extends CLI_Controller $db = new DB_Model(); $qry = " - SELECT - * - FROM - hr.tbl_vertragsbestandteil - WHERE - dienstverhaeltnis_id=".$db->escape($dvid)." - AND vertragsbestandteiltyp_kurzbz='stunden' + SELECT + * + FROM + hr.tbl_vertragsbestandteil + WHERE + dienstverhaeltnis_id=".$db->escape($dvid)." + AND vertragsbestandteiltyp_kurzbz='stunden' AND ".$db->escape($datum)." BETWEEN von AND COALESCE(bis, '2999-12-31')"; - + $resultVBS = $db->execReadOnlyQuery($qry); return $resultVBS; @@ -430,22 +460,22 @@ class MigrateSalary extends CLI_Controller private function _getUser($svnr) { $db = new DB_Model(); - + $qry = " - SELECT - mitarbeiter_uid - FROM - public.tbl_person + SELECT + mitarbeiter_uid + FROM + public.tbl_person JOIN public.tbl_benutzer using(person_id) JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE tbl_person.svnr = ". $db->escape($svnr)." AND EXISTS( - SELECT - 1 - FROM - hr.tbl_dienstverhaeltnis - WHERE + SELECT + 1 + FROM + hr.tbl_dienstverhaeltnis + WHERE mitarbeiter_uid=tbl_mitarbeiter.mitarbeiter_uid AND oe_kurzbz=". $db->escape($this->OE_DEFAULT)." ) diff --git a/application/core/FHCAPI_Controller.php b/application/core/FHCAPI_Controller.php new file mode 100644 index 000000000..e59740ded --- /dev/null +++ b/application/core/FHCAPI_Controller.php @@ -0,0 +1,255 @@ +config->set_item('error_views_path', VIEWPATH.'errors'.DIRECTORY_SEPARATOR.'json'.DIRECTORY_SEPARATOR); + + global $g_result; + $g_result = $this; + + ob_start(function ($content) { + $http_response_code = http_response_code(); + // NOTE(chris): For security reasons 404 will be displayed the same everywhere + if ($http_response_code == REST_Controller::HTTP_NOT_FOUND) + return $content; + + header('Content-Type: application/json; charset=utf-8'); + + if (!isset($this->returnObj['meta']) || !isset($this->returnObj['meta']['status'])) { + switch ($http_response_code) { + case 200: + $this->setStatus(self::STATUS_SUCCESS); + break; + case 400: + $this->setStatus(self::STATUS_FAIL); + break; + default: + $this->setStatus(self::STATUS_ERROR); + break; + } + } + + #$this->returnObj['test'] = implode('/n', headers_list()); + + return json_encode($this->returnObj); + }); + + // Load libraries + $this->load->library('AuthLib'); + $this->load->library('PermissionLib'); + + // Checks if the caller is allowed to access to this content + $this->_isAllowed($requiredPermissions); + + // For JSON Requests (as opposed to multipart/form-data) get the $_POST variable from the input stream instead + if ($this->input->get_request_header('Content-Type', true) == 'application/json') + $_POST = json_decode($this->security->xss_clean($this->input->raw_input_stream), true); + elseif (isset($_POST['_jsondata'])) { + $_POST = array_merge($_POST, json_decode($_POST['_jsondata'], true)); + unset($_POST['_jsondata']); + } + } + + + // --------------------------------------------------------------- + // Handle Output object + // --------------------------------------------------------------- + + /** + * @param array $data + * @param string $type (optional) + * @return void + */ + public function addError($data, $type = null) + { + if (!isset($this->returnObj['errors'])) + $this->returnObj['errors'] = []; + + $error = []; + + if (is_array($data)) { + if ($type == self::ERROR_TYPE_VALIDATION) + $error['messages'] = $data; + else + $error = $data; + } else { + $error['message'] = $data; + } + + if ($type) + $error['type'] = $type; + + $this->returnObj['errors'][] = $error; + } + + /** + * @param mixed $data + * @return void + */ + public function setData($data) + { + $this->returnObj['data'] = $data; + } + + /** + * @param string $status + * @return void + */ + public function setStatus($status) + { + if (!isset($this->returnObj['meta'])) + $this->returnObj['meta'] = []; + $this->returnObj['meta']['status'] = $status; + } + + + // --------------------------------------------------------------- + // Handle Output object - Shortcut functions + // --------------------------------------------------------------- + + /** + * @param array $errors + * @return void + */ + protected function terminateWithValidationErrors($errors) + { + $this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST); + $this->addError($errors, self::ERROR_TYPE_VALIDATION); + $this->setStatus(self::STATUS_FAIL); + exit(EXIT_ERROR); + } + + /** + * @param mixed $data (optional) + * @return void + */ + protected function terminateWithSuccess($data = null) + { + $this->setData($data); + $this->setStatus(self::STATUS_SUCCESS); + exit; + } + + /** + * @param array $error + * @param string $type (optional) + * @return void + */ + protected function terminateWithError($error, $type = null) + { + $this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR); + $this->addError($error, $type); + $this->setStatus(self::STATUS_ERROR); + exit; + } + + /** + * @param stdclass $result + * @param string $errortype + * @return void + */ + protected function checkForErrors($result, $errortype = self::ERROR_TYPE_GENERAL) + { + // TODO(chris): IMPLEMENT! + if (isError($result)) { + $this->terminateWithError(getError($result), $errortype); + } + return $result->retval; + } + + // TODO(chris): complete list + + + // --------------------------------------------------------------- + // Security + // --------------------------------------------------------------- + + /** + * Checks if the caller is allowed to access to this content with the given permissions + * If it is not allowed will set the HTTP header with code 401 + * Wrapper for permissionlib->isEntitled + * + * @param array $requiredPermissions + * @return void + */ + protected function _isAllowed($requiredPermissions) + { + // Checks if this user is entitled to access to this content + if (!$this->permissionlib->isEntitled($requiredPermissions, $this->router->method)) + { + $this->output->set_status_header(isLogged() ? REST_Controller::HTTP_FORBIDDEN : REST_Controller::HTTP_UNAUTHORIZED); + + $this->addError([ + 'message' => 'You are not allowed to access to this content', + 'controller' => $this->router->class, + 'method' => $this->router->method, + 'required_permissions' => $this->_rpsToString($requiredPermissions, $this->router->method) + ]); + exit; // immediately terminate the execution + } + } + + /** + * Converts an array of permissions to a string that contains them as a comma separated list + * Ex: ", , " + * + * @param array $requiredPermissions + * @param string $method + * @return void + */ + protected function _rpsToString($requiredPermissions, $method) + { + if (!isset($requiredPermissions[$method])) + return ''; + + if (!is_array($requiredPermissions[$method])) + return $requiredPermissions[$method]; + + return implode(', ', $requiredPermissions[$method]); + } +} diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index 298c3652f..7d1b6a5ac 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -62,9 +62,11 @@ class AntragLib 'insertvon' => $insertvon ]); - // NOTE(chris): remove "preabbrecher" statusgrund for Stgl-Abmeldungen if set + // NOTE(chris): remove "preabbrecher" statusgrund and paused stati for sibling Anträge 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->unpauseAntrag($antrag_id, Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL); + $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') { @@ -83,6 +85,67 @@ class AntragLib return $result; } + /** + * @param integer $antrag_id + * @param string $insertvon + * + * @return stdClass + */ + public function pauseAntrag($antrag_id, $insertvon) + { + switch ($insertvon) { + case Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL: + $result = $this->_ci->StudierendenantragstatusModel->stopAntraegeForAbmeldungStgl($antrag_id); + break; + case Studierendenantragstatus_model::INSERTVON_DEREGISTERED: + $result = $this->_ci->StudierendenantragstatusModel->stopAntraegeForAbbruchBy($antrag_id); + break; + default: + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE, + 'insertvon' => $insertvon + ]); + break; + } + + return $result; + } + + /** + * @param integer $antrag_id + * @param string $insertvon + * + * @return stdClass + */ + public function unpauseAntrag($antrag_id, $insertvon) + { + if ($insertvon == Studierendenantragstatus_model::INSERTVON_DEREGISTERED) + return error($this->p->t('studierendenantrag', 'error_no_right')); + if ($insertvon == Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL) { + return $this->_ci->StudierendenantragstatusModel->resumeAntraegeForAbmeldungStgl($antrag_id); + } + // NOTE(chris): get last status that is not pause + $this->_ci->StudierendenantragstatusModel->addOrder('insertamum'); + $this->_ci->StudierendenantragstatusModel->addLimit(1); + $result = $this->_ci->StudierendenantragstatusModel->loadWhere([ + 'studierendenantrag_id' => $antrag_id, + 'studierendenantrag_statustyp_kurzbz !=' => Studierendenantragstatus_model::STATUS_PAUSE + ]); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_no_antragstatus', ['id' => $antrag_id])); + $status = current(getData($result)); + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $antrag_id, + 'studierendenantrag_statustyp_kurzbz' => $status->studierendenantrag_statustyp_kurzbz, + 'insertvon' => $insertvon + ]); + return $result; + } + /** * NOTE(chris): permissions & verification must be handled outside * @@ -169,7 +232,7 @@ class AntragLib if (isError($result)) $errors[] = getError($result); else { - $this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps','studiengang_kz'); + $this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps', 'studiengang_kz'); $result = $this->_ci->StudiengangModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); $stg = ''; $orgform = ''; @@ -190,6 +253,10 @@ class AntragLib $vorlage ='Sancho_Mail_Antrag_A_Approve'; $subject = $this->_ci->p->t('studierendenantrag', 'mail_subject_A_Approve'); + $result = $this->pauseAntrag($studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_DEREGISTERED); + if (isError($result)) + $errors[] = getError($result); + $result = $this->_ci->prestudentlib->setAbbrecher( $antrag->prestudent_id, $antrag->studiensemester_kurzbz, @@ -208,7 +275,13 @@ class AntragLib $data = [ 'student' => $this->_ci->p->t('person', 'studentIn'), 'sem' => $antrag->studiensemester_kurzbz, - 'linkPdf' => base_url('content/pdfExport.php?xml=Antrag' . $antrag->typ . '.xml.php&xsl=Antrag' . $antrag->typ . '&id=' . $antrag->studierendenantrag_id . '&output=pdf') + 'linkPdf' => base_url('content/pdfExport.php?xml=Antrag' . + $antrag->typ . + '.xml.php&xsl=Antrag' . + $antrag->typ . + '&id=' . + $antrag->studierendenantrag_id . + '&output=pdf') ]; if (hasData($result)) { $person = current(getData($result)); @@ -229,6 +302,10 @@ class AntragLib sendSanchoMail($vorlage, $data, $prestudent_status->email, $subject); } } else { // ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) + $result = $this->pauseAntrag($studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL); + if (isError($result)) + $errors[] = getError($result); + $result = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($antrag->prestudent_id, '', 'Student'); if (isError($result)) { @@ -340,6 +417,10 @@ class AntragLib if (isError($result)) return $result; else { + $result = $this->pauseAntrag($studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_DEREGISTERED); + // NOTE(chris): here we should have error handling but at the + // moment there is no way to notify the user for "soft" errors + $result = $this->_ci->prestudentlib->setAbbrecher( $antrag->prestudent_id, $antrag->studiensemester_kurzbz, @@ -471,7 +552,6 @@ class AntragLib '
Details:
' . $error_msg; } else { - $data = getData($data); $result = $this->_ci->StudierendenantragstatusModel->insert([ @@ -582,7 +662,11 @@ class AntragLib 'nachname' => $data['person']->nachname, 'UID' => $data['UID'], 'sem' => $resultAntrag->studiensemester_kurzbz, - 'linkPdf' => base_url('content/pdfExport.php?xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&id=' . $studierendenantrag_id . '&output=pdf'), + 'linkPdf' => base_url( + 'content/pdfExport.php?xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&id=' . + $studierendenantrag_id . + '&output=pdf' + ), 'insertvon' => $approvedBy ], $data['prestudent_status']->email, @@ -699,7 +783,9 @@ class AntragLib 'Orgform' => $data['prestudent_status']->orgform_kurzbz, 'prestudent_id' => $data['prestudent_status']->prestudent_id, 'abmeldungLink' => site_url('lehre/Studierendenantrag/abmeldung/' . $data['prestudent_status']->prestudent_id), - 'abmeldungLinkCIS' => CIS_ROOT . 'index.ci.php/lehre/Studierendenantrag/abmeldung/' . $data['prestudent_status']->prestudent_id + 'abmeldungLinkCIS' => CIS_ROOT . + 'index.ci.php/lehre/Studierendenantrag/abmeldung/' . + $data['prestudent_status']->prestudent_id ], $data['email'], $this->_ci->p->t('studierendenantrag', 'mail_subject_U_Reject') @@ -734,7 +820,7 @@ class AntragLib return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $studierendenantrag_id])); $result['antrag'] = $antrag = current($res); - $this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps','studiengang_kz'); + $this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps', 'studiengang_kz'); $res = $this->_ci->StudiengangModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]); if (hasData($res)) { $result['studiengang'] = current(getData($res)); @@ -862,7 +948,9 @@ class AntragLib $result = $this->_ci->StudierendenantragstatusModel->insert([ 'studierendenantrag_id' => $antrag_id, - 'studierendenantrag_statustyp_kurzbz' => $repeat ? Studierendenantragstatus_model::STATUS_CREATED : Studierendenantragstatus_model::STATUS_PASS, + 'studierendenantrag_statustyp_kurzbz' => $repeat + ? Studierendenantragstatus_model::STATUS_CREATED + : Studierendenantragstatus_model::STATUS_PASS, 'insertvon' => $insertvon ]); @@ -878,8 +966,7 @@ class AntragLib $email = $prestudent_status->email; // NOTE(chris): Sancho mail $lvzuweisungLink = site_url('lehre/Antrag/Wiederholung/assistenz/' . $antrag_id); - if( defined('VILESCI_ROOT') ) - { + if (defined('VILESCI_ROOT')) { $lvzuweisungLink = VILESCI_ROOT . 'index.ci.php/lehre/Antrag/Wiederholung/assistenz/' . $antrag_id; } sendSanchoMail( @@ -888,7 +975,7 @@ class AntragLib 'antrag_id' => $antrag_id, 'stg' => $prestudent_status->stg_bezeichnung, 'Orgform' => $prestudent_status->orgform, - 'lvzuweisungLink' => $lvzuweisungLink + 'lvzuweisungLink' => $lvzuweisungLink ], $email, $this->_ci->p->t('studierendenantrag', 'mail_subject_W_New') @@ -1062,7 +1149,11 @@ class AntragLib if (isError($result)) return $result; if (!hasData($result)) - return error($this->_ci->p->t('studierendenantrag', 'error_no_stdsem', ['studiensemester_kurzbz' => $antrag->studiensemester_kurzbz])); + return error($this->_ci->p->t( + 'studierendenantrag', + 'error_no_stdsem', + ['studiensemester_kurzbz' => $antrag->studiensemester_kurzbz] + )); $asem = current(getData($result)); foreach ($stdsems as $sem) { @@ -1117,7 +1208,6 @@ class AntragLib $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; $lv->antrag_zugelassen = true; } - } } else { $lvsA = null; @@ -1224,10 +1314,10 @@ class AntragLib * @param integer $prestudent_id * * @return \stdClass on success retval 0 means not a student; - * retval 1 means Berechtigt; - * retval -1 means has already an Antrag pending; - * retval -2 means other Antrag pending; - * retval -3 means in blacklist stg + * retval 1 means Berechtigt; + * retval -1 means has already an Antrag pending; + * retval -2 means other Antrag pending; + * retval -3 means in blacklist stg */ public function getPrestudentAbmeldeBerechtigt($prestudent_id) { @@ -1251,12 +1341,24 @@ class AntragLib if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist_abmeldung'))) { $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([ - 'prestudent_id' => $prestudent_id, - 'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED - ], [ - Studierendenantrag_model::TYP_ABMELDUNG, - Studierendenantrag_model::TYP_ABMELDUNG_STGL - ]); + 'prestudent_id' => $prestudent_id, + 's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED + ], [ + Studierendenantrag_model::TYP_ABMELDUNG, + Studierendenantrag_model::TYP_ABMELDUNG_STGL + ]); + if (isError($result)) + return $result; + if (hasData($result)) + return success(-1); + + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([ + 'prestudent_id' => $prestudent_id, + 's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE + ], [ + Studierendenantrag_model::TYP_ABMELDUNG, + Studierendenantrag_model::TYP_ABMELDUNG_STGL + ]); if (isError($result)) return $result; if (hasData($result)) @@ -1297,12 +1399,12 @@ class AntragLib * @param string $studiensemester_kurzbz (optional) * * @return \stdClass on success retval 0 means not a student; - * retval 1 means Berechtigt; + * retval 1 means Berechtigt; * retval -1 means has already an Antrag pending; * 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 +1422,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 +1433,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 +1444,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 +1457,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); } @@ -1406,7 +1512,27 @@ class AntragLib $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([ 'prestudent_id' => $prestudent_id, 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG, - 'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED + 's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED + ]); + if (isError($result)) + return $result; + if (hasData($result)) + return success(-1); + + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([ + 'prestudent_id' => $prestudent_id, + 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG, + 's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_DEREGISTERED + ]); + if (isError($result)) + return $result; + if (hasData($result)) + return success(-1); + + $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([ + 'prestudent_id' => $prestudent_id, + 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG, + 's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE ]); if (isError($result)) return $result; @@ -1457,15 +1583,16 @@ class AntragLib return success($result); } + /** + * Gets details for the latest Antrag of one or more types + * + * @param integer $prestudent_id + * @param array|string $typ + * + * @return \stdClass + */ public function getDetailsForLastAntrag($prestudent_id, $typ = null) { - $result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($prestudent_id); - if (isError($result)) - return $result; - if (!hasData($result)) - return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', ['prestudent_id' => $prestudent_id])); - $resultDetails = current(getData($result)); - $where = [ 'prestudent_id' => $prestudent_id ]; @@ -1494,21 +1621,20 @@ class AntragLib 'prestudent_id' => $prestudent_id ])); - $resultDetails->status = $resultAntrag->status; - $resultDetails->statustyp = $resultAntrag->statustyp; - $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); + return $this->addDetailsToAntrag($resultAntrag); } + /** + * Gets details for a specific Antrag + * + * @param integer $studierendenantrag_id + * + * @return \stdClass + */ public function getDetailsForAntrag($studierendenantrag_id) { $where = [ - 'studierendenantrag_id' => $studierendenantrag_id + 's.studierendenantrag_id' => $studierendenantrag_id ]; $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere($where); @@ -1519,76 +1645,99 @@ class AntragLib return error($this->_ci->p->t('studierendenantrag', "error_no_antrag_found", ['id' => $studierendenantrag_id])); $resultAntrag = current(getData($result)); - $result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($resultAntrag->prestudent_id, $resultAntrag->studiensemester_kurzbz); + return $this->addDetailsToAntrag($resultAntrag); + } + + /** + * Helper function for getDetailsForAntrag and getDetailsForLastAntrag + * + * @param \stdClass $antrag + * + * @return \stdClass + */ + protected function addDetailsToAntrag($antrag) + { + $result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails( + $antrag->prestudent_id, + $antrag->studiensemester_kurzbz, + $antrag->insertamum + ); if (isError($result)) return $result; if (!hasData($result)) { - $result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($resultAntrag->prestudent_id); + $result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails( + $antrag->prestudent_id, + null, + $antrag->insertamum + ); if (isError($result)) return $result; if (!hasData($result)) - return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', $resultAntrag)); + return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudent_in_sem', $antrag)); + $tmp = current(getData($result)); + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $res = $this->_ci->StudiensemesterModel->load($antrag->studiensemester_kurzbz); + if (hasData($res)) + $tmp->studienjahr_kurzbz = current(getData($res))->studienjahr_kurzbz; + else + $tmp->studienjahr_kurzbz = ''; + // NOTE(chris): the semester might not be correct on this fallback so we disable it + $tmp->semester = ''; } - $resultDetails = current(getData($result)); - $resultDetails->status = $resultAntrag->status; - $resultDetails->statustyp = $resultAntrag->statustyp; - $resultDetails->grund = $resultAntrag->grund; - $resultDetails->studierendenantrag_id = $resultAntrag->studierendenantrag_id; - $resultDetails->typ = $resultAntrag->typ; - $resultDetails->dms_id = $resultAntrag->dms_id; - $resultDetails->datum_wiedereinstieg = $resultAntrag->datum_wiedereinstieg; + $result = current(getData($result)); - return success($resultDetails); + $result->status = $antrag->status; + $result->statustyp = $antrag->statustyp; + $result->status_insertvon = $antrag->status_insertvon; + $result->grund = $antrag->grund; + $result->studierendenantrag_id = $antrag->studierendenantrag_id; + $result->typ = $antrag->typ; + $result->datum = $antrag->datum; + $result->dms_id = $antrag->dms_id; + $result->datum_wiedereinstieg = $antrag->datum_wiedereinstieg; + + return success($result); } - 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] = [ + 'studienjahr_kurzbz' => $item->studienjahr_kurzbz, + '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) @@ -1664,7 +1813,6 @@ class AntragLib return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_antrag', ['id' => $antrag_id])); $stg = current($result); - $studiengang_kz = $stg->studiengang_kz; $semester = $stg->ausbildungssemester; $result = $this->_ci->StudierendenantragModel->load($antrag_id); @@ -1726,9 +1874,7 @@ 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'; } @@ -1895,6 +2041,26 @@ class AntragLib return $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag'); } + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function isEntitledToPauseAntrag($antrag_id) + { + return ($this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe') || $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag')); + } + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function isEntitledToUnpauseAntrag($antrag_id) + { + return $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag'); + } + /** * @param integer $antrag_id * @@ -1935,6 +2101,36 @@ class AntragLib return $this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe'); } + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function antragCanBeManualPaused($antrag_id) + { + $this->_ci->StudierendenantragModel->db->where_not_in('campus.get_status_studierendenantrag(studierendenantrag_id)', [ + Studierendenantragstatus_model::STATUS_DEREGISTERED, + Studierendenantragstatus_model::STATUS_APPROVED, + Studierendenantragstatus_model::STATUS_PAUSE + ]); + $result = $this->_ci->StudierendenantragModel->loadWhere([ + 'studierendenantrag_id' => $antrag_id, + 'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG + ]); + + return hasData($result); + } + + /** + * @param integer $antrag_id + * + * @return boolean + */ + public function antragCanBeManualUnpaused($antrag_id) + { + return $this->_ci->StudierendenantragModel->isManuallyPaused($antrag_id); + } + /** * @param integer $antrag_id * @param string|array $status diff --git a/application/libraries/PrestudentLib.php b/application/libraries/PrestudentLib.php index 989e14585..ae4ad59c6 100644 --- a/application/libraries/PrestudentLib.php +++ b/application/libraries/PrestudentLib.php @@ -74,7 +74,7 @@ class PrestudentLib $result = $this->_ci->PrestudentstatusModel->withGrund($statusgrund_kurzbz)->insert([ 'prestudent_id' => $prestudent_id, 'status_kurzbz' => Prestudentstatus_model::STATUS_ABBRECHER, - 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiensemester_kurzbz' => $prestudent_status->studiensemester_kurzbz, 'ausbildungssemester' => $prestudent_status->ausbildungssemester, 'datum' => $datum, 'insertvon' => $insertvon, @@ -135,7 +135,7 @@ class PrestudentLib } //noch nicht eingetragene Zeugnisnoten auf 9 setzen - $result = $this->_ci->ZeugnisnoteModel->getZeugnisnoten($student->student_uid, $studiensemester_kurzbz); + $result = $this->_ci->ZeugnisnoteModel->getZeugnisnoten($student->student_uid, $prestudent_status->studiensemester_kurzbz); if (isError($result)) return $result; $result = getData($result) ?: []; @@ -181,7 +181,7 @@ class PrestudentLib //Studentlehrverband setzen $this->_ci->StudentlehrverbandModel->update([ - 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiensemester_kurzbz' => $prestudent_status->studiensemester_kurzbz, 'student_uid' => $student->student_uid ], [ 'studiengang_kz' => $student->studiengang_kz, diff --git a/application/models/crm/Prestudentstatus_model.php b/application/models/crm/Prestudentstatus_model.php index 08c081153..b3dc45321 100644 --- a/application/models/crm/Prestudentstatus_model.php +++ b/application/models/crm/Prestudentstatus_model.php @@ -267,7 +267,7 @@ class Prestudentstatus_model extends DB_Model return $this->loadWhere($where); } - public function loadLastWithStgDetails($prestudent_id, $studiensemester_kurzbz = null) + public function loadLastWithStgDetails($prestudent_id, $studiensemester_kurzbz = null, $max_date = null) { $this->load->config('studierendenantrag'); @@ -304,7 +304,8 @@ class Prestudentstatus_model extends DB_Model $this->addLimit(1); - $this->db->where_in($this->dbTable . '.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist')); + if ($max_date) + $this->db->where($this->dbTable . '.insertamum <', $max_date); $whereArr = [ $this->dbTable . '.prestudent_id' => $prestudent_id, diff --git a/application/models/education/Pruefung_model.php b/application/models/education/Pruefung_model.php index 50109d2f1..214d6519f 100644 --- a/application/models/education/Pruefung_model.php +++ b/application/models/education/Pruefung_model.php @@ -87,7 +87,13 @@ class Pruefung_model extends DB_Model $this->addJoin('public.tbl_person pers', 'person_id'); $this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid'); $this->addJoin('public.tbl_studiengang g', 'ps.studiengang_kz=g.studiengang_kz'); - $this->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id=ps.prestudent_id AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', 'LEFT'); + $this->addJoin( + 'public.tbl_prestudentstatus pss', + 'pss.prestudent_id=ps.prestudent_id + AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz + AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', + 'LEFT' + ); $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); $this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz'); $this->db->join('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ = ?', 'LEFT', false); @@ -164,8 +170,10 @@ class Pruefung_model extends DB_Model $this->addSelect('ps.prestudent_id'); $this->addSelect('lv.bezeichnung as lvbezeichnung'); $this->addSelect('le.studiensemester_kurzbz'); + $this->addSelect('a.studierendenantrag_id'); $this->addSelect('a.typ'); $this->addSelect('campus.get_status_studierendenantrag(a.studierendenantrag_id) status'); + $this->addSelect('pss.ausbildungssemester'); $this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id'); $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); @@ -174,12 +182,20 @@ class Pruefung_model extends DB_Model $this->addJoin('public.tbl_person pers', 'person_id'); $this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid'); $this->addJoin('public.tbl_studiengang g', 'ps.studiengang_kz=g.studiengang_kz'); - $this->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id=ps.prestudent_id AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', 'LEFT'); + $this->addJoin( + 'public.tbl_prestudentstatus pss', + 'pss.prestudent_id=ps.prestudent_id + AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz + AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', + 'LEFT' + ); $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); $this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz'); - $this->addJoin('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ=' . $this->escape(Studierendenantrag_model::TYP_WIEDERHOLUNG), 'LEFT'); - - $this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist')); + $this->addJoin( + 'campus.tbl_studierendenantrag a', + 'ps.prestudent_id=a.prestudent_id and a.typ=' . $this->escape(Studierendenantrag_model::TYP_WIEDERHOLUNG), + 'LEFT' + ); $this->db->where("g.aktiv", true); @@ -210,7 +226,7 @@ class Pruefung_model extends DB_Model $this->db->where('ps.prestudent_id', $prestudent_id); if ($max_date !== null) { - $this->db->where('p.datum <', $max_date); + $this->db->where('p.datum <=', $max_date); } if ($studiensemester_kurzbz !== null) { $this->db->where('le.studiensemester_kurzbz', $studiensemester_kurzbz); @@ -237,6 +253,8 @@ class Pruefung_model extends DB_Model $this->db->where("b.aktiv", true); + $this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist')); + if (is_array($status)) { if (in_array(null, $status)) { $status = array_filter($status); diff --git a/application/models/education/Studierendenantrag_model.php b/application/models/education/Studierendenantrag_model.php index 23d69b13b..e138d1a1c 100644 --- a/application/models/education/Studierendenantrag_model.php +++ b/application/models/education/Studierendenantrag_model.php @@ -46,6 +46,8 @@ class Studierendenantrag_model extends DB_Model $this->addSelect('datum_wiedereinstieg'); $this->addSelect($this->dbTable . '.typ'); $this->addSelect('st.studierendenantrag_statustyp_kurzbz as status'); + $this->addSelect('s.insertvon as status_insertvon'); + $this->addSelect('s.insertamum as status_insertamum'); $this->addSelect('dms_id'); $this->addSelect('st.bezeichnung[(' . $sql . ')] as statustyp'); @@ -54,7 +56,13 @@ class Studierendenantrag_model extends DB_Model $this->addJoin('public.tbl_person', 'person_id'); $this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz'); $this->addJoin('public.tbl_studiensemester ss', 'studiensemester_kurzbz'); - $this->addJoin('public.tbl_prestudentstatus ps', 'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=ss.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ss.studiensemester_kurzbz)'); + $this->addJoin( + 'public.tbl_prestudentstatus ps', + 'ps.prestudent_id=p.prestudent_id + AND ps.studiensemester_kurzbz=ss.studiensemester_kurzbz + AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ss.studiensemester_kurzbz)', + 'LEFT' + ); $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); $this->addJoin('bis.tbl_orgform of', 'of.orgform_kurzbz=COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, stg.orgform_kurzbz)'); $this->addJoin( @@ -76,7 +84,9 @@ class Studierendenantrag_model extends DB_Model 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 + // 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(); @@ -85,7 +95,8 @@ class Studierendenantrag_model extends DB_Model Studierendenantragstatus_model::STATUS_APPROVED, Studierendenantragstatus_model::STATUS_REJECTED, Studierendenantragstatus_model::STATUS_OBJECTION_DENIED, - Studierendenantragstatus_model::STATUS_DEREGISTERED + Studierendenantragstatus_model::STATUS_DEREGISTERED, + Studierendenantragstatus_model::STATUS_PAUSE ]); $this->db->or_group_start(); $this->db->where('s.studierendenantrag_statustyp_kurzbz', Studierendenantragstatus_model::STATUS_APPROVED); @@ -133,12 +144,18 @@ class Studierendenantrag_model extends DB_Model $lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage()); $this->addSelect('*'); - $this->addSelect('campus.get_status_studierendenantrag(studierendenantrag_id) status'); + $this->addSelect($this->dbTable . '.grund AS grund'); + $this->addSelect('s.studierendenantrag_statustyp_kurzbz status'); + $this->addSelect('s.insertvon status_insertvon'); $this->addSelect('t.bezeichnung[(' . $lang . ')] statustyp'); + $this->addJoin( + 'campus.tbl_studierendenantrag_status s', + 'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id' + ); $this->addJoin( 'campus.tbl_studierendenantrag_statustyp t', - 'campus.get_status_studierendenantrag(studierendenantrag_id)=t.studierendenantrag_statustyp_kurzbz' + 's.studierendenantrag_statustyp_kurzbz=t.studierendenantrag_statustyp_kurzbz' ); if ($types && is_array($types)) { @@ -168,7 +185,11 @@ class Studierendenantrag_model extends DB_Model $this->addJoin( 'public.tbl_prestudentstatus s', - $this->dbTable . '.prestudent_id=s.prestudent_id AND ' . $this->dbTable . '.studiensemester_kurzbz=s.studiensemester_kurzbz' + $this->dbTable . '.prestudent_id=s.prestudent_id + AND ' . + $this->dbTable . '.studiensemester_kurzbz=s.studiensemester_kurzbz + AND ' . + $this->dbTable . '.insertamum > s.insertamum' ); $this->addJoin('public.tbl_prestudent p', $this->dbTable . '.prestudent_id=p.prestudent_id'); $this->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT'); @@ -180,8 +201,6 @@ class Studierendenantrag_model extends DB_Model $this->addLimit(1); - $this->db->where_in('s.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist')); - return $this->loadWhere([ $this->pk => $antrag_id ]); @@ -233,20 +252,45 @@ class Studierendenantrag_model extends DB_Model $this->addSelect($this->dbTable . '.datum_wiedereinstieg'); $this->addSelect($this->dbTable . '.grund'); $this->addSelect($this->dbTable . '.dms_id'); - $this->addSelect("(SELECT count(1) FROM campus.tbl_studierendenantrag_status WHERE studierendenantrag_id = " . $this->dbTable . ".studierendenantrag_id AND studierendenantrag_statustyp_kurzbz = 'Genehmigt') AS isapproved", false); + $this->addSelect('s.insertvon AS status_insertvon'); + $this->addSelect( + "(SELECT count(1) FROM campus.tbl_studierendenantrag_status WHERE studierendenantrag_id = " . + $this->dbTable . + ".studierendenantrag_id AND studierendenantrag_statustyp_kurzbz = 'Genehmigt') AS isapproved", + false + ); $this->addJoin('public.tbl_prestudent p', 'prestudent_id', 'RIGHT'); $this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz'); - $this->addJoin('public.tbl_prestudentstatus ps', 'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=' . $this->dbTable . '.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ' . $this->dbTable . '.studiensemester_kurzbz)', 'LEFT'); + $this->addJoin( + 'public.tbl_prestudentstatus ps', + 'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=' . + $this->dbTable . + '.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ' . + $this->dbTable . + '.studiensemester_kurzbz)', + 'LEFT' + ); $this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT'); $this->addJoin('bis.tbl_orgform of', 'of.orgform_kurzbz=COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, stg.orgform_kurzbz)'); + $this->addJoin( + 'campus.tbl_studierendenantrag_status s', + 'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id', + 'LEFT' + ); $this->addJoin( 'campus.tbl_studierendenantrag_statustyp st', - 'campus.get_status_studierendenantrag(studierendenantrag_id)=st.studierendenantrag_statustyp_kurzbz', + 's.studierendenantrag_statustyp_kurzbz=st.studierendenantrag_statustyp_kurzbz', 'LEFT' ); - $this->db->where("(SELECT status_kurzbz FROM public.tbl_prestudentstatus WHERE prestudent_id=p.prestudent_id AND status_kurzbz='Student' LIMIT 1) IS NOT NULL", null, false); + $this->db->where("( + SELECT status_kurzbz + FROM public.tbl_prestudentstatus + WHERE prestudent_id=p.prestudent_id + AND status_kurzbz='Student' + LIMIT 1 + ) IS NOT NULL", null, false); return $this->loadWhere([ @@ -287,4 +331,144 @@ 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.studienjahr_kurzbz AS studienjahr_kurzbz, + 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, studienjahr_kurzbz + 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 + ]); + } + + /** + * Returns if an Antrag is manually paused + * + * @param integer $antrag_id + * + * @return boolean + */ + public function isManuallyPaused($antrag_id) + { + $this->addJoin( + 'campus.tbl_studierendenantrag_status s', + 'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id' + ); + + $this->db->where([ + 's.studierendenantrag_id' => $antrag_id, + 's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE + ]); + + $this->db->group_start(); + $this->db->where_not_in('s.insertvon', [ + Studierendenantragstatus_model::INSERTVON_DEREGISTERED, + Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL + ]); + $this->db->or_group_start(); + $this->db->where('s.insertvon', Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL); + $this->db->where('1 !=', '( + SELECT COUNT(*)%2 + FROM campus.tbl_studierendenantrag_status i + WHERE i.studierendenantrag_id = s.studierendenantrag_id + AND i.insertamum > ( + SELECT ii.insertamum + FROM campus.tbl_studierendenantrag_status ii + WHERE ii.studierendenantrag_id = s.studierendenantrag_id + AND ii.insertvon <> ' . $this->escape(Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL) . ' + ORDER BY ii.insertamum DESC + LIMIT 1 + ) + )', false); + $this->db->group_end(); + $this->db->group_end(); + + return hasData($this->load()); + } } diff --git a/application/models/education/Studierendenantragstatus_model.php b/application/models/education/Studierendenantragstatus_model.php index c134cc4ee..cf9cce1be 100644 --- a/application/models/education/Studierendenantragstatus_model.php +++ b/application/models/education/Studierendenantragstatus_model.php @@ -15,6 +15,10 @@ class Studierendenantragstatus_model extends DB_Model const STATUS_OBJECTED = 'Beeinsprucht'; const STATUS_OBJECTION_DENIED = 'EinspruchAbgelehnt'; const STATUS_DEREGISTERED = 'Abgemeldet'; + const STATUS_PAUSE = 'Pause'; + + const INSERTVON_ABMELDUNGSTGL = "AbmeldungStgl"; + const INSERTVON_DEREGISTERED = "Studienabbruch"; /** * Constructor @@ -49,4 +53,157 @@ class Studierendenantragstatus_model extends DB_Model return $this->loadWhere($where); } + + public function stopAntraegeForAbmeldungStgl($antrag_id) + { + $sql = 'INSERT INTO campus.tbl_studierendenantrag_status + (studierendenantrag_id, studierendenantrag_statustyp_kurzbz, insertvon, insertamum) + SELECT studierendenantrag_id, ?, ?, ( + SELECT insertamum + FROM campus.tbl_studierendenantrag_status + WHERE studierendenantrag_status_id = campus.get_status_id_studierendenantrag(?) + ) + FROM campus.tbl_studierendenantrag + WHERE prestudent_id = ( + SELECT prestudent_id + FROM campus.tbl_studierendenantrag + WHERE studierendenantrag_id = ? + ) + AND studierendenantrag_id <> ? + AND ( + ( + typ = ? + AND campus.get_status_studierendenantrag(studierendenantrag_id) IN ? + ) OR ( + typ = ? + AND campus.get_status_studierendenantrag(studierendenantrag_id) IN ? + ) OR ( + typ = ? + AND campus.get_status_studierendenantrag(studierendenantrag_id) IN ? + ) + )'; + + return $this->execQuery($sql, [ + self::STATUS_PAUSE, + self::INSERTVON_ABMELDUNGSTGL, + $antrag_id, + $antrag_id, + $antrag_id, + Studierendenantrag_model::TYP_ABMELDUNG, + [ + Studierendenantragstatus_model::STATUS_CREATED + ], + Studierendenantrag_model::TYP_UNTERBRECHUNG, + [ + Studierendenantragstatus_model::STATUS_CREATED + ], + Studierendenantrag_model::TYP_WIEDERHOLUNG, + [ + Studierendenantragstatus_model::STATUS_REQUESTSENT_1, + Studierendenantragstatus_model::STATUS_REQUESTSENT_2, + Studierendenantragstatus_model::STATUS_CREATED, + Studierendenantragstatus_model::STATUS_LVSASSIGNED, + Studierendenantragstatus_model::STATUS_PAUSE + ], + ]); + } + + public function resumeAntraegeForAbmeldungStgl($antrag_id) + { + $sql = 'INSERT INTO campus.tbl_studierendenantrag_status + (studierendenantrag_id, studierendenantrag_statustyp_kurzbz, insertvon, insertamum) + SELECT studierendenantrag_id, ( + SELECT studierendenantrag_statustyp_kurzbz + FROM campus.tbl_studierendenantrag_status s + WHERE s.studierendenantrag_id=a.studierendenantrag_id + AND campus.get_status_id_studierendenantrag(a.studierendenantrag_id) <> studierendenantrag_status_id + ORDER BY insertamum DESC + LIMIT 1 + ), ?, ( + SELECT insertamum + FROM campus.tbl_studierendenantrag_status + WHERE studierendenantrag_status_id = campus.get_status_id_studierendenantrag(?) + ) + FROM campus.tbl_studierendenantrag a + WHERE prestudent_id = ( + SELECT prestudent_id + FROM campus.tbl_studierendenantrag + WHERE studierendenantrag_id = ? + ) + AND typ <> ? + AND campus.get_status_studierendenantrag(studierendenantrag_id) = ? + '; + + return $this->execQuery($sql, [ + self::INSERTVON_ABMELDUNGSTGL, + $antrag_id, + $antrag_id, + Studierendenantrag_model::TYP_ABMELDUNG_STGL, + Studierendenantragstatus_model::STATUS_PAUSE + ]); + } + + public function stopAntraegeForAbbruchBy($antrag_id) + { + $sql = 'INSERT INTO campus.tbl_studierendenantrag_status + (studierendenantrag_id, studierendenantrag_statustyp_kurzbz, insertvon, insertamum) + SELECT studierendenantrag_id, ?, ?, ( + SELECT insertamum + FROM campus.tbl_studierendenantrag_status + WHERE studierendenantrag_status_id = campus.get_status_id_studierendenantrag(?) + ) + FROM campus.tbl_studierendenantrag + WHERE prestudent_id = ( + SELECT prestudent_id + FROM campus.tbl_studierendenantrag + WHERE studierendenantrag_id = ? + ) + AND studierendenantrag_id <> ? + AND ( + ( + typ = ? + AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ? + ) OR ( + typ = ? + AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ? + ) OR ( + typ = ? + AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ? + ) OR ( + typ = ? + AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ? + ) + )'; + + return $this->execQuery($sql, [ + self::STATUS_PAUSE, + self::INSERTVON_DEREGISTERED, + $antrag_id, + $antrag_id, + $antrag_id, + Studierendenantrag_model::TYP_ABMELDUNG, + [ + Studierendenantragstatus_model::STATUS_APPROVED, + Studierendenantragstatus_model::STATUS_CANCELLED + ], + Studierendenantrag_model::TYP_UNTERBRECHUNG, + [ + Studierendenantragstatus_model::STATUS_APPROVED, + Studierendenantragstatus_model::STATUS_CANCELLED, + Studierendenantragstatus_model::STATUS_REMINDERSENT, + Studierendenantragstatus_model::STATUS_REJECTED + ], + Studierendenantrag_model::TYP_ABMELDUNG_STGL, + [ + Studierendenantragstatus_model::STATUS_CANCELLED, + Studierendenantragstatus_model::STATUS_DEREGISTERED, + Studierendenantragstatus_model::STATUS_OBJECTION_DENIED + ], + Studierendenantrag_model::TYP_WIEDERHOLUNG, + [ + Studierendenantragstatus_model::STATUS_DEREGISTERED, + Studierendenantragstatus_model::STATUS_APPROVED + ], + ]); + } } diff --git a/application/models/person/Kennzeichen_model.php b/application/models/person/Kennzeichen_model.php new file mode 100644 index 000000000..fe8a9ac62 --- /dev/null +++ b/application/models/person/Kennzeichen_model.php @@ -0,0 +1,15 @@ +dbTable = 'public.tbl_kennzeichen'; + $this->pk = 'kennzeichen_id'; + } + +} diff --git a/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php index 5b276c55e..12842e2a3 100644 --- a/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php +++ b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php @@ -18,7 +18,7 @@ class Dienstverhaeltnis_model extends DB_Model $result = null; $qry = " - SELECT + SELECT dv.dienstverhaeltnis_id, tbl_benutzer.uid, tbl_mitarbeiter.personalnummer, @@ -30,8 +30,8 @@ class Dienstverhaeltnis_model extends DB_Model org.oe_kurzbz, org.bezeichnung oe_bezeichnung, dv.von, - dv.bis, - dv.vertragsart_kurzbz, + dv.bis, + dv.vertragsart_kurzbz, dv.updateamum, dv.updatevon FROM tbl_mitarbeiter @@ -59,13 +59,13 @@ class Dienstverhaeltnis_model extends DB_Model "; return $this->execQuery($qry, $data); - + } public function getDVByID($dvid) { $this->addSelect('hr.tbl_dienstverhaeltnis.*, public.tbl_organisationseinheit.bezeichnung as unternehmen'); $this->addJoin('public.tbl_organisationseinheit', 'hr.tbl_dienstverhaeltnis.oe_kurzbz = public.tbl_organisationseinheit.oe_kurzbz'); - $result = $this->load($dvid); + $result = $this->load($dvid); if (hasData($result)) { return $result; @@ -81,7 +81,7 @@ class Dienstverhaeltnis_model extends DB_Model $datestring = $date->format("Y-m-d"); $qry = " - SELECT + SELECT dv.dienstverhaeltnis_id, tbl_benutzer.uid, tbl_mitarbeiter.personalnummer, @@ -115,26 +115,26 @@ class Dienstverhaeltnis_model extends DB_Model $params = array_merge($params, array($dvid, $dvid)); $dvidclause = <<= COALESCE(vb.von, '1970-01-01'::date) - AND - COALESCE(dv.bis::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31') + AND + vb.vertragsbestandteiltyp_kurzbz = 'karenz' + AND + dv.von::date >= COALESCE(vb.von, '1970-01-01'::date) + AND + COALESCE(dv.bis::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31') ) = 0 AND dv.dienstverhaeltnis_id != ? EODVIDC; - + } - + $query = <<= dv.von + AND + COALESCE(?::date, '2170-12-31'::date) >= dv.von AND ( - SELECT - COUNT(*) AS karenzen - FROM - hr.tbl_vertragsbestandteil vb - WHERE + SELECT + COUNT(*) AS karenzen + FROM + hr.tbl_vertragsbestandteil vb + WHERE vb.dienstverhaeltnis_id = dv.dienstverhaeltnis_id - AND - vb.vertragsbestandteiltyp_kurzbz = 'karenz' - AND - ?::date >= COALESCE(vb.von, '1970-01-01'::date) - AND - COALESCE(?::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31') - ) = 0 + AND + vb.vertragsbestandteiltyp_kurzbz = 'karenz' + AND + ?::date >= COALESCE(vb.von, '1970-01-01'::date) + AND + COALESCE(?::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31') + ) = 0 {$dvidclause} EOSQL; - + $ret = $this->execReadOnlyQuery($query, $params); - + if( ($dvcount = getData($ret)) && ($dvcount[0]->dvcount > 0) ) { return true; } - - return false; + + return false; } -} \ No newline at end of file + + public function getDVByPersonUIDOverlapping($uid, $oe_kurzbz=null, $beginn=null, $ende=null) + { + $result = null; + + $qry = " + SELECT + dv.dienstverhaeltnis_id, + tbl_benutzer.uid, + tbl_mitarbeiter.personalnummer, + tbl_mitarbeiter.kurzbz, + tbl_mitarbeiter.lektor, + tbl_mitarbeiter.fixangestellt, + tbl_person.person_id, + tbl_benutzer.alias, + org.oe_kurzbz, + org.bezeichnung oe_bezeichnung, + dv.von, + dv.bis, + dv.vertragsart_kurzbz, + dv.updateamum, + dv.updatevon + FROM tbl_mitarbeiter + JOIN tbl_benutzer ON tbl_mitarbeiter.mitarbeiter_uid::text = tbl_benutzer.uid::text + JOIN tbl_person USING (person_id) + JOIN hr.tbl_dienstverhaeltnis dv ON(tbl_benutzer.uid::text = dv.mitarbeiter_uid::text) + JOIN public.tbl_organisationseinheit org USING(oe_kurzbz) + WHERE tbl_benutzer.uid=?"; + $data = array($uid); + + if(!is_null($oe_kurzbz)) + { + $qry.=" AND oe_kurzbz=?"; + $data[] = $oe_kurzbz; + } + + if (!is_null($beginn) && !is_null($ende)) + { + $qry.=" AND (?,?) OVERLAPS (dv.von, COALESCE(dv.bis, '2999-12-31'))"; + $data[] = $beginn; + $data[] = $ende; + } + + $qry .=" + ORDER BY dv.von desc + "; + + return $this->execQuery($qry, $data); + + } + +} diff --git a/application/views/errors/json/html/error_404.php b/application/views/errors/json/html/error_404.php new file mode 100644 index 000000000..0caade2b1 --- /dev/null +++ b/application/views/errors/json/html/error_404.php @@ -0,0 +1,65 @@ + + + + +404 Page Not Found + + + +
+

+ +
+ + diff --git a/application/views/errors/json/html/error_db.php b/application/views/errors/json/html/error_db.php new file mode 100644 index 000000000..dce6a7572 --- /dev/null +++ b/application/views/errors/json/html/error_db.php @@ -0,0 +1,49 @@ +

', $msg); + +$msgs = []; + +$error = [ + 'heading' => $heading +]; + +/** NOTE(chris): extract Error Number and SQL + * @see: DB_driver.php:692 + */ +if (substr(current($msg), 0, 14) == 'Error Number: ') { + $code = substr(array_shift($msg), 14); + if ($code) + $error['code'] = (int)$code; + $msgs[] = array_shift($msg); + $error['sql'] = array_shift($msg); +} + +/** NOTE(chris): extract Line Number and Filename + * @see: DB_driver.php:1782 + * @see: DB_driver.php:1783 + */ +if (count($msg) >= 2) { + if (substr(end($msg), 0, 13) == 'Line Number: ' && substr(prev($msg), 0, 10) == 'Filename: ') { + $error['line'] = (int)substr(array_pop($msg), 13); + $error['filename'] = substr(array_pop($msg), 10); + } +} + +foreach ($msg as $m) + $msgs[] = $m; + + +if (count($msgs) == 1) + $error['message'] = current($msgs); +else + $error['messages'] = $msgs; + +$g_result->addError($error, FHCAPI_Controller::ERROR_TYPE_DB); +$g_result->setStatus(FHCAPI_Controller::STATUS_ERROR); diff --git a/application/views/errors/json/html/error_exception.php b/application/views/errors/json/html/error_exception.php new file mode 100644 index 000000000..7984bd13e --- /dev/null +++ b/application/views/errors/json/html/error_exception.php @@ -0,0 +1,27 @@ + $message, + 'class' => get_class($exception), + 'filename' => $exception->getFile(), + 'line' => $exception->getLine() +]; + +if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true) { + $error['backtrace'] = []; + foreach (debug_backtrace() as $err) { + if (isset($err['file']) && strpos($err['file'], realpath(BASEPATH)) !== 0) { + $error['backtrace'][] = [ + 'file' => $err['file'], + 'line' => $err['line'], + 'function' => $err['function'] + ]; + } + } +} + +$g_result->addError($error, FHCAPI_Controller::ERROR_TYPE_EXCEPTION); +$g_result->setStatus(FHCAPI_Controller::STATUS_ERROR); diff --git a/application/views/errors/json/html/error_general.php b/application/views/errors/json/html/error_general.php new file mode 100644 index 000000000..e69494463 --- /dev/null +++ b/application/views/errors/json/html/error_general.php @@ -0,0 +1,20 @@ +

', $msg); + +$error = [ + 'heading' => $heading +]; +if (count($msg) == 1) + $error['message'] = current($msg); +else + $error['messages'] = $msg; + +$g_result->addError($error, FHCAPI_Controller::ERROR_TYPE_GENERAL); +$g_result->setStatus(FHCAPI_Controller::STATUS_ERROR); diff --git a/application/views/errors/json/html/error_php.php b/application/views/errors/json/html/error_php.php new file mode 100644 index 000000000..91f2abf3c --- /dev/null +++ b/application/views/errors/json/html/error_php.php @@ -0,0 +1,31 @@ + $message, + 'severity' => $severity, + 'filename' => $filepath, + 'line' => $line +]; + +if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true) { + $error['backtrace'] = []; + foreach (debug_backtrace() as $err) { + if (isset($err['file']) && strpos($err['file'], realpath(BASEPATH)) !== 0) { + $error['backtrace'][] = [ + 'file' => $err['file'], + 'line' => $err['line'], + 'function' => $err['function'] + ]; + } + } +} + +// TODO(chris): change type with severity +$g_result->addError($error, 'php'); + +if (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity) { + $g_result->setStatus('error'); +} diff --git a/application/views/lehre/Antrag/Create.php b/application/views/lehre/Antrag/Create.php index 2c9d0d382..f0b681c2a 100644 --- a/application/views/lehre/Antrag/Create.php +++ b/application/views/lehre/Antrag/Create.php @@ -31,9 +31,9 @@ $this->load->view(

load->view(

p->t('studierendenantrag', 'calltoaction_' . $type); ?>


- + p->t('studierendenantrag', 'antrag_typ_' . $type); ?>
@@ -63,7 +66,16 @@ $this->load->view( studierendenantrag_id; ?> p->t('studierendenantrag', 'antrag_typ_' . $antrag->typ); ?> - status_bezeichnung; ?> + + status == Studierendenantragstatus_model::STATUS_PAUSE + && $antrag->status_insertvon == Studierendenantragstatus_model::INSERTVON_DEREGISTERED + ) + ? $this->p->t('studierendenantrag', 'status_stop') + : $antrag->status_bezeichnung; + ?> + studiensemester_kurzbz; ?> datum))->format('d.m.Y'); ?> datum_wiedereinstieg ? (new DateTime($antrag->datum_wiedereinstieg))->format('d.m.Y') : ''; ?> @@ -74,15 +86,32 @@ $this->load->view( -