From b2d2c3e2c36f2edb0f9db45c8b9dbc3371a5dc8b Mon Sep 17 00:00:00 2001 From: Alexei Karpenko Date: Sun, 2 Jun 2024 17:46:51 +0200 Subject: [PATCH] Plausichecks: added BeginndatumVorBismeldung and FalscheStatusabfolgeVorStudentstatus, improved AbschlusstatusFehlt --- .../issues/PlausicheckDefinitionLib.php | 6 +- .../plausichecks/AbschlussstatusFehlt.php | 21 ++- .../plausichecks/BeginndatumVorBismeldung.php | 121 +++++++++++++ .../FalscheStatusabfolgeVorStudentstatus.php | 171 ++++++++++++++++++ system/fehlerupdate.php | 16 ++ 5 files changed, 324 insertions(+), 11 deletions(-) create mode 100644 application/libraries/issues/plausichecks/BeginndatumVorBismeldung.php create mode 100644 application/libraries/issues/plausichecks/FalscheStatusabfolgeVorStudentstatus.php diff --git a/application/libraries/issues/PlausicheckDefinitionLib.php b/application/libraries/issues/PlausicheckDefinitionLib.php index b44a5ce19..462917297 100644 --- a/application/libraries/issues/PlausicheckDefinitionLib.php +++ b/application/libraries/issues/PlausicheckDefinitionLib.php @@ -15,13 +15,16 @@ class PlausicheckDefinitionLib 'AktSemesterNull' => 'AktSemesterNull', 'AktiverStudentOhneStatus' => 'AktiverStudentOhneStatus', 'AusbildungssemPrestudentUngleichAusbildungssemStatus' => 'AusbildungssemPrestudentUngleichAusbildungssemStatus', + 'BeginndatumVorBismeldung' => 'BeginndatumVorBismeldung', 'BewerberNichtZumRtAngetreten' => 'BewerberNichtZumRtAngetreten', 'DatumAbschlusspruefungFehlt' => 'DatumAbschlusspruefungFehlt', 'DatumSponsionFehlt' => 'DatumSponsionFehlt', 'DatumStudiensemesterFalscheReihenfolge' => 'DatumStudiensemesterFalscheReihenfolge', + 'DualesStudiumOhneMarkierung' => 'DualesStudiumOhneMarkierung', 'FalscheAnzahlAbschlusspruefungen' => 'FalscheAnzahlAbschlusspruefungen', 'FalscheAnzahlHeimatadressen' => 'FalscheAnzahlHeimatadressen', 'FalscheAnzahlZustelladressen' => 'FalscheAnzahlZustelladressen', + 'FalscheStatusabfolgeVorStudentstatus' => 'FalscheStatusabfolgeVorStudentstatus', 'GbDatumWeitZurueck' => 'GbDatumWeitZurueck', 'InaktiverStudentAktiverStatus' => 'InaktiverStudentAktiverStatus', 'IncomingHeimatNationOesterreich' => 'IncomingHeimatNationOesterreich', @@ -33,8 +36,7 @@ class PlausicheckDefinitionLib 'PrestudentMischformOhneOrgform' => 'PrestudentMischformOhneOrgform', 'StgPrestudentUngleichStgStudienplan' => 'StgPrestudentUngleichStgStudienplan', 'StgPrestudentUngleichStgStudent' => 'StgPrestudentUngleichStgStudent', - 'StudentstatusNachAbbrecher' => 'StudentstatusNachAbbrecher', - 'DualesStudiumOhneMarkierung' => 'DualesStudiumOhneMarkierung' + 'StudentstatusNachAbbrecher' => 'StudentstatusNachAbbrecher' //'StudienplanUngueltig' => 'StudienplanUngueltig' ); diff --git a/application/libraries/issues/plausichecks/AbschlussstatusFehlt.php b/application/libraries/issues/plausichecks/AbschlussstatusFehlt.php index 3690e1331..3890e91c7 100644 --- a/application/libraries/issues/plausichecks/AbschlussstatusFehlt.php +++ b/application/libraries/issues/plausichecks/AbschlussstatusFehlt.php @@ -101,23 +101,26 @@ class AbschlussstatusFehlt extends PlausiChecker if (isset($studiensemester_kurzbz)) { + $this->_ci->load->model('organisation/studiensemester_model', 'StudiensemesterModel'); $prevStudiensemesterRes = $this->_ci->StudiensemesterModel->getPreviousFrom($studiensemester_kurzbz); if (isError($prevStudiensemesterRes)) return $prevStudiensemesterRes; + $semesterArr = array($studiensemester_kurzbz); + if (hasData($prevStudiensemesterRes)) { // if Studiensemester given, check only if has status in current or previous semester - $prevStudiensemester = getData($prevStudiensemesterRes)[0]->studiensemester_kurzbz; - $qry .= " AND EXISTS ( - SELECT 1 - FROM public.tbl_prestudentstatus ps - WHERE studiensemester_kurzbz IN (?, ?) - AND ps.prestudent_id = pre.prestudent_id - )"; - $params[] = $prevStudiensemester; - $params[] = $studiensemester_kurzbz; + $semesterArr[] = getData($prevStudiensemesterRes)[0]->studiensemester_kurzbz; } + + $qry .= " AND EXISTS ( + SELECT 1 + FROM public.tbl_prestudentstatus ps + WHERE studiensemester_kurzbz IN ? + AND ps.prestudent_id = pre.prestudent_id + )"; + $params[] = $semesterArr; } if (isset($studiengang_kz)) diff --git a/application/libraries/issues/plausichecks/BeginndatumVorBismeldung.php b/application/libraries/issues/plausichecks/BeginndatumVorBismeldung.php new file mode 100644 index 000000000..70fcec720 --- /dev/null +++ b/application/libraries/issues/plausichecks/BeginndatumVorBismeldung.php @@ -0,0 +1,121 @@ +_config['exkludierteStudiengaenge']) ? $this->_config['exkludierteStudiengaenge'] : null; + + // pass parameters needed for plausicheck + $studiensemester_kurzbz = isset($params['studiensemester_kurzbz']) ? $params['studiensemester_kurzbz'] : null; + $studiengang_kz = isset($params['studiengang_kz']) ? $params['studiengang_kz'] : null; + + // get all students failing the plausicheck + $prestudentRes = $this->getBeginndatumVorBismeldung( + $studiensemester_kurzbz, + $studiengang_kz, + null, + $exkludierte_studiengang_kz + ); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz, + ), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } + + /** + * Bewerber should have participated in Reihungstest. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @param exkludierte_studiengang_kz array if certain Studiengänge have to be excluded from check + * @return success with prestudents or error + */ + public function getBeginndatumVorBismeldung( + $studiensemester_kurzbz, + $studiengang_kz = null, + $prestudent_id = null, + $exkludierte_studiengang_kz = null + ) { + $this->_ci->load->model('codex/Bismeldestichtag_model', 'BismeldestichtagModel'); + + $bismeldestichtagRes = $this->_ci->BismeldestichtagModel->getByStudiensemester($studiensemester_kurzbz); + + if (isError($bismeldestichtagRes)) return $bismeldestichtagRes; + + if (!hasData($bismeldestichtagRes)) return success(array()); + + $bismeldestichtag = getData($bismeldestichtagRes)[0]->meldestichtag; + + $params = array($bismeldestichtag, $studiensemester_kurzbz, $bismeldestichtag); + + $qry = " + SELECT + prestudent.person_id, prestudent.prestudent_id, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, status.studiensemester_kurzbz + FROM + public.tbl_prestudent prestudent + JOIN public.tbl_prestudentstatus status ON(prestudent.prestudent_id=status.prestudent_id) + JOIN public.tbl_person USING(person_id) + LEFT JOIN bis.tbl_orgform USING(orgform_kurzbz) + JOIN public.tbl_studiengang stg USING(studiengang_kz) + WHERE + status.datum < ?::date + AND status.studiensemester_kurzbz = ? + AND status.insertamum > ?::date + AND stg.melderelevant + AND prestudent.bismelden"; + + if (isset($studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent.prestudent_id = ?"; + $params[] = $prestudent_id; + } + + if (isset($exkludierte_studiengang_kz) && !isEmptyArray($exkludierte_studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz NOT IN ?"; + $params[] = $exkludierte_studiengang_kz; + } + + return $this->_db->execReadOnlyQuery($qry, $params); + } +} diff --git a/application/libraries/issues/plausichecks/FalscheStatusabfolgeVorStudentstatus.php b/application/libraries/issues/plausichecks/FalscheStatusabfolgeVorStudentstatus.php new file mode 100644 index 000000000..99d43978a --- /dev/null +++ b/application/libraries/issues/plausichecks/FalscheStatusabfolgeVorStudentstatus.php @@ -0,0 +1,171 @@ +_config['exkludierteStudiengaenge']) ? $this->_config['exkludierteStudiengaenge'] : null; + + // pass parameters needed for plausicheck + $studiensemester_kurzbz = isset($params['studiensemester_kurzbz']) ? $params['studiensemester_kurzbz'] : null; + $studiengang_kz = isset($params['studiengang_kz']) ? $params['studiengang_kz'] : null; + + // get all students failing the plausicheck + $prestudentRes = $this->getFalscheStatusabfolgeVorStudentstatus( + $studiensemester_kurzbz, + $studiengang_kz, + null, + $exkludierte_studiengang_kz + ); + + if (isError($prestudentRes)) return $prestudentRes; + + if (hasData($prestudentRes)) + { + $prestudents = getData($prestudentRes); + + // populate results with data necessary for writing issues + foreach ($prestudents as $prestudent) + { + $results[] = array( + 'person_id' => $prestudent->person_id, + 'oe_kurzbz' => $prestudent->prestudent_stg_oe_kurzbz, + 'fehlertext_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ), + 'resolution_params' => array( + 'prestudent_id' => $prestudent->prestudent_id, + 'studiensemester_kurzbz' => $prestudent->studiensemester_kurzbz + ) + ); + } + } + + // return the results + return success($results); + } + + /** + * Bewerber should have participated in Reihungstest. + * @param studiensemester_kurzbz string check is to be executed for certain Studiensemester + * @param studiengang_kz int if check is to be executed for certain Studiengang + * @param prestudent_id int if check is to be executed only for one prestudent + * @param exkludierte_studiengang_kz array if certain Studiengänge have to be excluded from check + * @return success with prestudents or error + */ + public function getFalscheStatusabfolgeVorStudentstatus( + $studiensemester_kurzbz = null, + $studiengang_kz = null, + $prestudent_id = null, + $exkludierte_studiengang_kz = null + ) { + $params = array(); + + $qry = " + SELECT + DISTINCT person_id, prestudent_id, prestudent_stg_oe_kurzbz, studiensemester_kurzbz + FROM + ( + SELECT + prestudent.person_id, prestudent.prestudent_id, + stg.studiengang_kz, stg.oe_kurzbz AS prestudent_stg_oe_kurzbz, status.studiensemester_kurzbz, + status.status_kurzbz, status.datum, status.insertamum, status.ext_id, + LAG(status.status_kurzbz, 1) + OVER ( + PARTITION BY prestudent.prestudent_id + ORDER BY status.datum, status.insertamum, status.ext_id + ) AS prev_status_kurzbz + FROM + public.tbl_prestudent prestudent + JOIN public.tbl_prestudentstatus status ON (prestudent.prestudent_id=status.prestudent_id) + JOIN public.tbl_person USING(person_id) + LEFT JOIN bis.tbl_orgform USING(orgform_kurzbz) + JOIN public.tbl_studiengang stg USING(studiengang_kz) + WHERE + status.status_kurzbz IN ('Interessent', 'Bewerber', 'Aufgenommener', 'Student') + AND stg.melderelevant + AND prestudent.bismelden + -- there should be a student already + AND EXISTS ( + SELECT 1 + FROM + public.tbl_prestudentstatus + WHERE + prestudent_id = prestudent.prestudent_id + AND status_kurzbz = 'Student' + AND datum >= status.datum + ) + ) prestudents + WHERE + ( + -- incorrect order + (status_kurzbz = 'Interessent' AND prev_status_kurzbz NOT IN ('Interessent') AND prev_status_kurzbz IS NOT NULL) + OR ( + (status_kurzbz <> 'Interessent' AND prev_status_kurzbz IS NULL) + OR (status_kurzbz = 'Bewerber' AND prev_status_kurzbz NOT IN ('Bewerber', 'Interessent')) + OR (status_kurzbz = 'Aufgenommener' AND prev_status_kurzbz NOT IN ('Aufgenommener', 'Bewerber')) + OR (status_kurzbz = 'Student' AND prev_status_kurzbz NOT IN ('Student', 'Aufgenommener')) + ) + )"; + + if (isset($studiensemester_kurzbz)) + { + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $prevStudiensemesterRes = $this->_ci->StudiensemesterModel->getPreviousFrom($studiensemester_kurzbz); + + if (isError($prevStudiensemesterRes)) return $prevStudiensemesterRes; + + $semesterArr = array($studiensemester_kurzbz); + + if (hasData($prevStudiensemesterRes)) + { + // if Studiensemester given, check only if has status in current or previous semester + $semesterArr[] = getData($prevStudiensemesterRes)[0]->studiensemester_kurzbz; + } + + $qry .= " AND EXISTS ( + SELECT 1 + FROM public.tbl_prestudentstatus ps + WHERE studiensemester_kurzbz IN ? + AND ps.prestudent_id = prestudents.prestudent_id + )"; + + $params[] = $semesterArr; + } + + if (isset($studiengang_kz)) + { + $qry .= " AND studiengang_kz = ?"; + $params[] = $studiengang_kz; + } + + if (isset($prestudent_id)) + { + $qry .= " AND prestudent_id = ?"; + $params[] = $prestudent_id; + } + + if (isset($exkludierte_studiengang_kz) && !isEmptyArray($exkludierte_studiengang_kz)) + { + $qry .= " AND stg.studiengang_kz NOT IN ?"; + $params[] = $exkludierte_studiengang_kz; + } + + $qry .= " ORDER BY person_id DESC, prestudent_id DESC, prestudent_stg_oe_kurzbz, studiensemester_kurzbz"; + + return $this->_db->execReadOnlyQuery($qry, $params); + } +} diff --git a/system/fehlerupdate.php b/system/fehlerupdate.php index 89446982d..48b6481d6 100644 --- a/system/fehlerupdate.php +++ b/system/fehlerupdate.php @@ -293,6 +293,22 @@ $fehlerArr = array( 'fehlertyp_kurzbz' => 'error', 'app' => 'core' ), + array( + 'fehlercode' => 'CORE_STUDENTSTATUS_0017', + 'fehler_kurzbz' => 'BeginndatumVorBismeldung', + 'fehlercode_extern' => null, + 'fehlertext' => 'Statusdatum vor Bismeldedatum eingetragen, nachdem das Bismeldedatum erreicht wurde (prestudent_id %s, Studiensemester %s)', + 'fehlertyp_kurzbz' => 'error', + 'app' => 'core' + ), + array( + 'fehlercode' => 'CORE_STUDENTSTATUS_0018', + 'fehler_kurzbz' => 'FalscheStatusabfolgeVorStudentstatus', + 'fehlercode_extern' => null, + 'fehlertext' => 'Falsche Statusabfolge vor Studentstatus (prestudent_id %s, Studiensemester %s)', + 'fehlertyp_kurzbz' => 'error', + 'app' => 'core' + ), array( 'fehlercode' => 'CORE_PERSON_0001', 'fehler_kurzbz' => 'GbDatumWeitZurueck',