From 2a8b61c07fe60d031d0af852c045b52dbbfbeac7 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 11 May 2022 18:29:10 +0200 Subject: [PATCH 001/439] - Added new library application/libraries/SignatureLib.php - Changed configs for the signature server in config/vilesci.config-default.inc.php - Changed include/dokument_export.class.php to make use of the new configs --- application/libraries/SignatureLib.php | 76 ++++++++++++++++++++++++++ config/vilesci.config-default.inc.php | 11 +++- include/dokument_export.class.php | 2 +- 3 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 application/libraries/SignatureLib.php diff --git a/application/libraries/SignatureLib.php b/application/libraries/SignatureLib.php new file mode 100644 index 000000000..b8c4374a3 --- /dev/null +++ b/application/libraries/SignatureLib.php @@ -0,0 +1,76 @@ +sendsJson() + ->authenticateWith(SIGNATUR_USER, SIGNATUR_PASSWORD) + ->body('{"filename": "'.basename($inputFileName).'", "content": "'.base64_encode($inputFileContent).'"}') + ->expectsJson() + ->send(); + } + } + catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception + { + $resultList = $cee->getMessage(); + } + catch (Exception $e) // any other exception + { + $resultList = $e->getMessage(); + } + + // If the response is fine + if (isset($resultPost->body) && is_object($resultPost->body) && isset($resultPost->body->retval)) + { + return $resultPost->body->retval; + } + + return $resultList; + } +} + diff --git a/config/vilesci.config-default.inc.php b/config/vilesci.config-default.inc.php index 5285eef3b..a3e4cbece 100644 --- a/config/vilesci.config-default.inc.php +++ b/config/vilesci.config-default.inc.php @@ -186,11 +186,16 @@ define('FHC_REST_PASSWORD', 'password'); * Signatur * DEFAULT: https://signatur.example.com/api/sign */ -define('SIGNATUR_URL', 'https://signatur.example.com/api/sign'); +// Generic URL +define('SIGNATUR_URL', 'https://signatur.dev.technikum-wien.at/api'); +// Sign API +define('SIGNATUR_SIGN_API', 'sign'); +// List API +define('SIGNATUR_LIST_API', 'list'); // User für Zugriff auf Signaturserver -define('SIGNATUR_USER', 'username'); +define('SIGNATUR_USER', 'fhcomplete'); // Passwort für Zugriff auf Signaturserver -define('SIGNATUR_PASSWORD', 'password'); +define('SIGNATUR_PASSWORD', 'Fhcomplet3Signature!'); // Signaturprofil das verwendet werden soll define('SIGNATUR_DEFAULT_PROFILE', 'FHC_AMT_GROSS_DE'); diff --git a/include/dokument_export.class.php b/include/dokument_export.class.php index 4f23a7dcd..3a6e57657 100644 --- a/include/dokument_export.class.php +++ b/include/dokument_export.class.php @@ -527,7 +527,7 @@ class dokument_export $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, SIGNATUR_URL); + curl_setopt($ch, CURLOPT_URL, SIGNATUR_URL.'/'.SIGNATUR_SIGN_API); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 7); curl_setopt($ch, CURLOPT_USERAGENT, "FH-Complete"); From d4042228d9114502fd0151510df15effa43b21e2 Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 13 May 2022 20:11:31 +0200 Subject: [PATCH 002/439] - Better code and comments in application/libraries/SignatureLib->list - cis/private/lehre/abgabe_lektor_details.php and cis/private/lehre/abgabe_student_details.php check if the uploaded document contains digital signares and display a phrase - Added new phrase to locale/de-AT/abgabetool.php and locale/en-US/abgabetool.php --- application/libraries/SignatureLib.php | 15 +++--- cis/private/lehre/abgabe_lektor_details.php | 25 +++++++++- cis/private/lehre/abgabe_student_details.php | 49 ++++++++++++++++---- locale/de-AT/abgabetool.php | 1 + locale/en-US/abgabetool.php | 1 + 5 files changed, 73 insertions(+), 18 deletions(-) diff --git a/application/libraries/SignatureLib.php b/application/libraries/SignatureLib.php index b8c4374a3..132545219 100644 --- a/application/libraries/SignatureLib.php +++ b/application/libraries/SignatureLib.php @@ -33,16 +33,13 @@ class SignatureLib */ public static function list($inputFileName) { - // Generic error occurred - $resultList = 'Generic error occurred'; - try { // Get the content of the given file $inputFileContent = file_get_contents($inputFileName); if ($inputFileContent === false) // if failed { - $resultList = 'An error occurred while getting the content from: '.$inputFileName; + error_log('An error occurred while getting the content from: '.$inputFileName); } else { @@ -57,20 +54,22 @@ class SignatureLib } catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception { - $resultList = $cee->getMessage(); + error_log($cee->getMessage()); } catch (Exception $e) // any other exception { - $resultList = $e->getMessage(); + error_log($e->getMessage()); } // If the response is fine - if (isset($resultPost->body) && is_object($resultPost->body) && isset($resultPost->body->retval)) + if (isset($resultPost->body) && is_object($resultPost->body) + && isset($resultPost->body->retval) && is_array($resultPost->body->retval)) { return $resultPost->body->retval; } - return $resultList; + // Otherwise return a null as error + return null; } } diff --git a/cis/private/lehre/abgabe_lektor_details.php b/cis/private/lehre/abgabe_lektor_details.php index a508de098..e1b47369d 100644 --- a/cis/private/lehre/abgabe_lektor_details.php +++ b/cis/private/lehre/abgabe_lektor_details.php @@ -37,6 +37,7 @@ require_once('../../../include/phrasen.class.php'); require_once('../../../include/projektarbeit.class.php'); require_once('../../../include/projektbetreuer.class.php'); require_once('../../../include/sancho.inc.php'); +require_once('../../../application/libraries/SignatureLib.php'); if (!$db = new basis_db()) $db=false; @@ -642,7 +643,29 @@ $result=@$db->db_query($qry); } if(file_exists(PAABGABE_PATH.$row->paabgabe_id.'_'.$uid.'.pdf')) { - $htmlstr .= " PDF"; + $uploadedDocumentSigned = null; + + // Check if the document is signed + $signList = SignatureLib::list(PAABGABE_PATH.$row->paabgabe_id.'_'.$uid.'.pdf'); + if (is_array($signList) && count($signList) > 0) + { + // The document is signed + } + elseif ($signList === null) + { + $uploadedDocumentSigned = 'WARNING: signature server error'; + } + else + { + $uploadedDocumentSigned = $p->t('abgabetool/uploadedDocumentNotSigned'); + } + + $htmlstr .= " + + PDF + + ".$uploadedDocumentSigned." + "; } else { diff --git a/cis/private/lehre/abgabe_student_details.php b/cis/private/lehre/abgabe_student_details.php index 29d74ab66..b8a8f158e 100644 --- a/cis/private/lehre/abgabe_student_details.php +++ b/cis/private/lehre/abgabe_student_details.php @@ -36,6 +36,7 @@ require_once('../../../include/phrasen.class.php'); require_once('../../../include/projektarbeit.class.php'); require_once('../../../include/projektbetreuer.class.php'); require_once('../../../include/sancho.inc.php'); +require_once('../../../application/libraries/SignatureLib.php'); $anzeigesprache = getSprache(); $p = new phrasen($anzeigesprache); @@ -111,6 +112,7 @@ $titel = $projektarbeit_obj->titel; $person = new person(); $person->load($bid); $betreuer = $person->titelpre.' '.$person->vorname.' '.$person->nachname.' '.$person->titelpost; +$uploadedDocumentSigned = null; if($uid!=$user) { @@ -286,15 +288,20 @@ if($command=="update" && $error!=true) move_uploaded_file($_FILES['datei']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'); if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf')) { - exec('chmod 640 "'.PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'.'"'); - - $qry="UPDATE campus.tbl_paabgabe SET - abgabedatum = now(), - updatevon = ".$db->db_add_param($user).", - updateamum = now() - WHERE paabgabe_id=".$db->db_add_param($paabgabe_id, FHC_INTEGER); - $result=$db->db_query($qry); - echo $p->t('global/dateiErfolgreichHochgeladen'); + // Check if the document is signed + $signList = SignatureLib::list(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'); + if (is_array($signList) && count($signList) > 0) + { + // The document is signed + } + elseif ($signList === null) + { + $uploadedDocumentSigned = 'WARNING: signature server error'; + } + else + { + $uploadedDocumentSigned = $p->t('abgabetool/uploadedDocumentNotSigned'); + } } else { @@ -311,6 +318,21 @@ if($command=="update" && $error!=true) } if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf')) { + // Check if the document is signed + $signList = SignatureLib::list(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'); + if (is_array($signList) && count($signList) > 0) + { + // The document is signed + } + elseif ($signList === null) + { + $uploadedDocumentSigned = 'WARNING: signature server error'; + } + else + { + $uploadedDocumentSigned = $p->t('abgabetool/uploadedDocumentNotSigned'); + } + /*$qry="UPDATE campus.tbl_paabgabe SET abgabedatum = now(), updatevon = '".$user."', @@ -339,6 +361,15 @@ if($command=="update" && $error!=true) $htmlstr .= ''."\n"; $htmlstr .= ''."\n"; $htmlstr .= ''."\n"; + + // If there are info about the signed document + if ($uploadedDocumentSigned != null) + { + $htmlstr .= "\n"; + $htmlstr .= "".$uploadedDocumentSigned.""; + $htmlstr .= "\n"; + } + $htmlstr .= "\n"; $htmlstr .= "".$p->t('abgabetool/spracheDerArbeit').":"; $sprache = @$db->db_query("SELECT sprache FROM public.tbl_sprache"); diff --git a/locale/de-AT/abgabetool.php b/locale/de-AT/abgabetool.php index c4b17318b..6d1eb923f 100644 --- a/locale/de-AT/abgabetool.php +++ b/locale/de-AT/abgabetool.php @@ -91,4 +91,5 @@ $this->phrasen['abgabetool/projektbeurteilungDownload']='Projektbeurteilung heru $this->phrasen['abgabetool/projektbeurteilungErstDownload']='Erst-/Begutachter'; $this->phrasen['abgabetool/projektbeurteilungZweitDownload']='Zweitbegutachter'; $this->phrasen['abgabetool/fehlerErmittelnEndabgabeProjektarbeit']='Fehler beim Ermitteln des Enduplaods der Projektarbeit'; +$this->phrasen['abgabetool/uploadedDocumentNotSigned']='The uploaded document is not signed DE'; ?> diff --git a/locale/en-US/abgabetool.php b/locale/en-US/abgabetool.php index b05456faa..c782dedcc 100644 --- a/locale/en-US/abgabetool.php +++ b/locale/en-US/abgabetool.php @@ -91,4 +91,5 @@ $this->phrasen['abgabetool/projektbeurteilungDownload']='Thesis-Assessment downl $this->phrasen['abgabetool/projektbeurteilungErstDownload']='First-/Assessor'; $this->phrasen['abgabetool/projektbeurteilungZweitDownload']='Second Assessor'; $this->phrasen['abgabetool/fehlerErmittelnEndabgabeProjektarbeit']='Error when getting endupload of project work'; +$this->phrasen['abgabetool/uploadedDocumentNotSigned']='The uploaded document is not signed EN'; ?> From 22bba685ffcacdbb0ee1b2847cea3eab8b3c8a65 Mon Sep 17 00:00:00 2001 From: Paolo Date: Mon, 16 May 2022 16:15:48 +0200 Subject: [PATCH 003/439] Added new style to the warning --- cis/private/lehre/abgabe_lektor_details.php | 27 ++++++++++++-------- cis/private/lehre/abgabe_student_details.php | 24 ++++++++++------- locale/de-AT/abgabetool.php | 2 +- locale/en-US/abgabetool.php | 2 +- 4 files changed, 33 insertions(+), 22 deletions(-) diff --git a/cis/private/lehre/abgabe_lektor_details.php b/cis/private/lehre/abgabe_lektor_details.php index e1b47369d..29a1221af 100644 --- a/cis/private/lehre/abgabe_lektor_details.php +++ b/cis/private/lehre/abgabe_lektor_details.php @@ -641,6 +641,14 @@ $result=@$db->db_query($qry); { $htmlstr .= "               "; } + if($row->abgabedatum && $row->paabgabetyp_kurzbz=="end") + { + $htmlstr .= " zusätzliche Daten"; + } + else + { + $htmlstr .= "     "; + } if(file_exists(PAABGABE_PATH.$row->paabgabe_id.'_'.$uid.'.pdf')) { $uploadedDocumentSigned = null; @@ -663,17 +671,14 @@ $result=@$db->db_query($qry); $htmlstr .= " PDF - - ".$uploadedDocumentSigned." - "; - } - else - { - $htmlstr .= "     "; - } - if($row->abgabedatum && $row->paabgabetyp_kurzbz=="end") - { - $htmlstr .= " zusätzliche Daten"; + "; + if ($uploadedDocumentSigned != null) + { + $htmlstr .= '
+ '.$uploadedDocumentSigned.' +
'; + } + $htmlstr .= ""; } else { diff --git a/cis/private/lehre/abgabe_student_details.php b/cis/private/lehre/abgabe_student_details.php index b8a8f158e..949749a3b 100644 --- a/cis/private/lehre/abgabe_student_details.php +++ b/cis/private/lehre/abgabe_student_details.php @@ -361,15 +361,6 @@ if($command=="update" && $error!=true) $htmlstr .= ''."\n"; $htmlstr .= ''."\n"; $htmlstr .= ''."\n"; - - // If there are info about the signed document - if ($uploadedDocumentSigned != null) - { - $htmlstr .= "\n"; - $htmlstr .= "".$uploadedDocumentSigned.""; - $htmlstr .= "\n"; - } - $htmlstr .= "\n"; $htmlstr .= "".$p->t('abgabetool/spracheDerArbeit').":"; $sprache = @$db->db_query("SELECT sprache FROM public.tbl_sprache"); @@ -403,6 +394,21 @@ if($command=="update" && $error!=true) $htmlstr .= ''.$p->t('abgabetool/seitenanzahl').':* '."\n"; $htmlstr .=" \n"; + + // If there are info about the signed document + if ($uploadedDocumentSigned != null) + { + $htmlstr .= "\n"; + $htmlstr .= ""; + $htmlstr .= '
+ + '.$uploadedDocumentSigned.' +
'; + $htmlstr .= ""; + $htmlstr .= "\n"; + } + + $htmlstr .=" \n"; $htmlstr .="

".$p->t('abgabetool/eidesstattlicheErklaerung')."

\n"; $htmlstr .= "".$p->t('abgabetool/gelesenUndAkzeptiert').":* "; $htmlstr .=" * ".$p->t('abgabetool/pflichtfeld')." diff --git a/locale/de-AT/abgabetool.php b/locale/de-AT/abgabetool.php index 6d1eb923f..093b56255 100644 --- a/locale/de-AT/abgabetool.php +++ b/locale/de-AT/abgabetool.php @@ -91,5 +91,5 @@ $this->phrasen['abgabetool/projektbeurteilungDownload']='Projektbeurteilung heru $this->phrasen['abgabetool/projektbeurteilungErstDownload']='Erst-/Begutachter'; $this->phrasen['abgabetool/projektbeurteilungZweitDownload']='Zweitbegutachter'; $this->phrasen['abgabetool/fehlerErmittelnEndabgabeProjektarbeit']='Fehler beim Ermitteln des Enduplaods der Projektarbeit'; -$this->phrasen['abgabetool/uploadedDocumentNotSigned']='The uploaded document is not signed DE'; +$this->phrasen['abgabetool/uploadedDocumentNotSigned']='Warning! The uploaded document is not signed DE'; ?> diff --git a/locale/en-US/abgabetool.php b/locale/en-US/abgabetool.php index c782dedcc..333e21272 100644 --- a/locale/en-US/abgabetool.php +++ b/locale/en-US/abgabetool.php @@ -91,5 +91,5 @@ $this->phrasen['abgabetool/projektbeurteilungDownload']='Thesis-Assessment downl $this->phrasen['abgabetool/projektbeurteilungErstDownload']='First-/Assessor'; $this->phrasen['abgabetool/projektbeurteilungZweitDownload']='Second Assessor'; $this->phrasen['abgabetool/fehlerErmittelnEndabgabeProjektarbeit']='Error when getting endupload of project work'; -$this->phrasen['abgabetool/uploadedDocumentNotSigned']='The uploaded document is not signed EN'; +$this->phrasen['abgabetool/uploadedDocumentNotSigned']='Warning! The uploaded document is not signed'; ?> From 2d2383639617fe349f8263927d607556afb7d6e7 Mon Sep 17 00:00:00 2001 From: Paolo Date: Mon, 16 May 2022 16:23:15 +0200 Subject: [PATCH 004/439] Translated german phrase --- locale/de-AT/abgabetool.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locale/de-AT/abgabetool.php b/locale/de-AT/abgabetool.php index 093b56255..378544811 100644 --- a/locale/de-AT/abgabetool.php +++ b/locale/de-AT/abgabetool.php @@ -91,5 +91,5 @@ $this->phrasen['abgabetool/projektbeurteilungDownload']='Projektbeurteilung heru $this->phrasen['abgabetool/projektbeurteilungErstDownload']='Erst-/Begutachter'; $this->phrasen['abgabetool/projektbeurteilungZweitDownload']='Zweitbegutachter'; $this->phrasen['abgabetool/fehlerErmittelnEndabgabeProjektarbeit']='Fehler beim Ermitteln des Enduplaods der Projektarbeit'; -$this->phrasen['abgabetool/uploadedDocumentNotSigned']='Warning! The uploaded document is not signed DE'; +$this->phrasen['abgabetool/uploadedDocumentNotSigned']='Warnung! Das hochgeladene Dokument ist nicht signiert'; ?> From 94a1534c14e3ec3781adef1be5db921b0e29c68e Mon Sep 17 00:00:00 2001 From: Paolo Date: Mon, 23 May 2022 14:42:59 +0200 Subject: [PATCH 005/439] - Warning Wrap on small Screens in Leturer side - Perform Signatur Check only on Files from Type Endupload --- cis/private/lehre/abgabe_lektor_details.php | 57 ++++++++++++-------- cis/private/lehre/abgabe_student_details.php | 28 +++------- 2 files changed, 40 insertions(+), 45 deletions(-) diff --git a/cis/private/lehre/abgabe_lektor_details.php b/cis/private/lehre/abgabe_lektor_details.php index 29a1221af..f0a19c89a 100644 --- a/cis/private/lehre/abgabe_lektor_details.php +++ b/cis/private/lehre/abgabe_lektor_details.php @@ -548,6 +548,8 @@ $htmlstr .= " $result=@$db->db_query($qry); while ($row=@$db->db_fetch_object($result)) { + $uploadedDocumentSigned = null; + $htmlstr .= "
\n"; $htmlstr .= "\n"; $htmlstr .= "\n"; @@ -649,43 +651,52 @@ $result=@$db->db_query($qry); { $htmlstr .= "     "; } - if(file_exists(PAABGABE_PATH.$row->paabgabe_id.'_'.$uid.'.pdf')) - { - $uploadedDocumentSigned = null; - // Check if the document is signed - $signList = SignatureLib::list(PAABGABE_PATH.$row->paabgabe_id.'_'.$uid.'.pdf'); - if (is_array($signList) && count($signList) > 0) + if (file_exists(PAABGABE_PATH.$row->paabgabe_id.'_'.$uid.'.pdf')) + { + if ($row->paabgabetyp_kurzbz == 'end') { - // The document is signed - } - elseif ($signList === null) - { - $uploadedDocumentSigned = 'WARNING: signature server error'; - } - else - { - $uploadedDocumentSigned = $p->t('abgabetool/uploadedDocumentNotSigned'); + // Check if the document is signed + $signList = SignatureLib::list(PAABGABE_PATH.$row->paabgabe_id.'_'.$uid.'.pdf'); + if (is_array($signList) && count($signList) > 0) + { + // The document is signed + } + elseif ($signList === null) + { + $uploadedDocumentSigned = 'WARNING: signature server error'; + } + else + { + $uploadedDocumentSigned = $p->t('abgabetool/uploadedDocumentNotSigned'); + } } $htmlstr .= " PDF - "; - if ($uploadedDocumentSigned != null) - { - $htmlstr .= '
- '.$uploadedDocumentSigned.' -
'; - } - $htmlstr .= ""; + + "; } else { $htmlstr .= "     "; } + $htmlstr .= " \n"; + if ($uploadedDocumentSigned != null) + { + $htmlstr .= ' + + + +
+ '.$uploadedDocumentSigned.' +
+ + '; + } $htmlstr .= "
\n"; } diff --git a/cis/private/lehre/abgabe_student_details.php b/cis/private/lehre/abgabe_student_details.php index 949749a3b..ed29519ff 100644 --- a/cis/private/lehre/abgabe_student_details.php +++ b/cis/private/lehre/abgabe_student_details.php @@ -282,41 +282,25 @@ if($command=="update" && $error!=true) $extensions = explode(".", $_FILES['datei']['name']); if(strtoupper(end($extensions))=='PDF') { - if($paabgabetyp_kurzbz!='end') + if ($paabgabetyp_kurzbz != 'end') { //"normaler" Upload move_uploaded_file($_FILES['datei']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'); - if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf')) - { - // Check if the document is signed - $signList = SignatureLib::list(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'); - if (is_array($signList) && count($signList) > 0) - { - // The document is signed - } - elseif ($signList === null) - { - $uploadedDocumentSigned = 'WARNING: signature server error'; - } - else - { - $uploadedDocumentSigned = $p->t('abgabetool/uploadedDocumentNotSigned'); - } - } - else + if (!file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf')) { echo $p->t('global/dateiNichtErfolgreichHochgeladen'); } } - else + else // endupload type { //Upload der Endabgabe - Eingabe der Zusatzdaten $command='add'; - if(!$error) + if (!$error) { move_uploaded_file($_FILES['datei']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'); } - if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf')) + + if (file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf')) { // Check if the document is signed $signList = SignatureLib::list(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'); From c354c69e212be33093bf27000ca9efa54a891e44 Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 24 May 2022 11:23:48 +0200 Subject: [PATCH 006/439] Fixed Zwischenabgabe file upload --- cis/private/lehre/abgabe_student_details.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/cis/private/lehre/abgabe_student_details.php b/cis/private/lehre/abgabe_student_details.php index ed29519ff..f91f410ab 100644 --- a/cis/private/lehre/abgabe_student_details.php +++ b/cis/private/lehre/abgabe_student_details.php @@ -286,7 +286,19 @@ if($command=="update" && $error!=true) { //"normaler" Upload move_uploaded_file($_FILES['datei']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'); - if (!file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf')) + if (file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf')) + { + exec('chmod 640 "'.PAABGABE_PATH.$paabgabe_id.'_'.$uid.'.pdf'.'"'); + + $qry="UPDATE campus.tbl_paabgabe SET + abgabedatum = now(), + updatevon = ".$db->db_add_param($user).", + updateamum = now() + WHERE paabgabe_id=".$db->db_add_param($paabgabe_id, FHC_INTEGER); + $result=$db->db_query($qry); + echo $p->t('global/dateiErfolgreichHochgeladen'); + } + else { echo $p->t('global/dateiNichtErfolgreichHochgeladen'); } From 7f2025c41405f261fa103ea4a242730c056f1c0f Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 24 May 2022 11:27:24 +0200 Subject: [PATCH 007/439] Added signature config entries to config/cis.config-default.inc.php --- config/cis.config-default.inc.php | 17 +++++++++++++++++ config/vilesci.config-default.inc.php | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/config/cis.config-default.inc.php b/config/cis.config-default.inc.php index 9d31548f6..d6f920259 100644 --- a/config/cis.config-default.inc.php +++ b/config/cis.config-default.inc.php @@ -204,6 +204,23 @@ define('TABLE_ID','_id'); define('TABLE_BEGIN','tbl_'); define('VIEW_BEGIN','vw_'); +/** + * Signatur + * DEFAULT: https://signatur.example.com/api/sign + */ +// Generic URL +define('SIGNATUR_URL', 'https://signatur.dev.technikum-wien.at/api'); +// Sign API +define('SIGNATUR_SIGN_API', 'sign'); +// List API +define('SIGNATUR_LIST_API', 'list'); +// User für Zugriff auf Signaturserver +define('SIGNATUR_USER', 'fhcomplete'); +// Passwort für Zugriff auf Signaturserver +define('SIGNATUR_PASSWORD', 'supersecretpassword'); +// Signaturprofil das verwendet werden soll +define('SIGNATUR_DEFAULT_PROFILE', 'FHC_AMT_GROSS_DE'); + //Gibt an, ob das Studienbuchblatt im CIS gedruckt werden kann define('CIS_DOKUMENTE_STUDIENBUCHLBATT_DRUCKEN',true); diff --git a/config/vilesci.config-default.inc.php b/config/vilesci.config-default.inc.php index a3e4cbece..c4232b020 100644 --- a/config/vilesci.config-default.inc.php +++ b/config/vilesci.config-default.inc.php @@ -195,7 +195,7 @@ define('SIGNATUR_LIST_API', 'list'); // User für Zugriff auf Signaturserver define('SIGNATUR_USER', 'fhcomplete'); // Passwort für Zugriff auf Signaturserver -define('SIGNATUR_PASSWORD', 'Fhcomplet3Signature!'); +define('SIGNATUR_PASSWORD', 'supersecretpassword'); // Signaturprofil das verwendet werden soll define('SIGNATUR_DEFAULT_PROFILE', 'FHC_AMT_GROSS_DE'); From 8880e07bf20d1332455a4a598e5cd44a4d42be8d Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 24 May 2022 12:22:30 +0200 Subject: [PATCH 008/439] include/dokument_export.class.php now checks the new signature server response structure --- include/dokument_export.class.php | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/dokument_export.class.php b/include/dokument_export.class.php index 3a6e57657..7d797cb21 100644 --- a/include/dokument_export.class.php +++ b/include/dokument_export.class.php @@ -559,18 +559,19 @@ class dokument_export curl_close($ch); $resultdata = json_decode($result); - if (isset($resultdata->success) && $resultdata->success == 'true') + // If it is success + if (isset($resultdata->error) && $resultdata->error == 0) { $this->signed_filename = $this->temp_folder .'/signed.pdf'; - file_put_contents($this->signed_filename, base64_decode($resultdata->document)); + file_put_contents($this->signed_filename, base64_decode($resultdata->retval)); return true; } - else + else // otherwise if it is an error { - if(isset($resultdata->errormsg)) - $this->errormsg = $resultdata->errormsg; + if(isset($resultdata->retval)) + $this->errormsg = $resultdata->retval; else - $this->errormsg = 'Unknown Error:'.print_r($resultdata,true); + $this->errormsg = 'Unknown Error:'.print_r($resultdata, true); return false; } } From 450b0b64339db9316e196676c474eccf981a1ea8 Mon Sep 17 00:00:00 2001 From: Manfred Date: Wed, 14 Sep 2022 15:55:07 +0200 Subject: [PATCH 009/439] Initial commit --- include/berechtigung.class.php | 37 + .../benutzerberechtigung_autocomplete.php | 116 ++ .../benutzerberechtigung_details.php | 1149 +++++++++++------ 3 files changed, 914 insertions(+), 388 deletions(-) create mode 100644 vilesci/stammdaten/benutzerberechtigung_autocomplete.php diff --git a/include/berechtigung.class.php b/include/berechtigung.class.php index 684ad4e81..ab224be4d 100644 --- a/include/berechtigung.class.php +++ b/include/berechtigung.class.php @@ -312,5 +312,42 @@ class berechtigung extends basis_db return false; } } + + /** + * Sucht nach Berechtigungen + * @param string $searchItem Suchbegriff + * @return boolean + */ + public function searchBerechtigungen($searchItem) + { + $this->result=array(); + $qry = 'SELECT * FROM system.tbl_berechtigung WHERE + ( + LOWER(berechtigung_kurzbz) LIKE LOWER(\'%'.$this->db_escape(($searchItem)).'%\') + OR + LOWER(beschreibung) LIKE LOWER(\'%'.$this->db_escape(($searchItem)).'%\') + )'; + + $qry .= ' ORDER BY berechtigung_kurzbz'; + + if($this->db_query($qry)) + { + while($row = $this->db_fetch_object()) + { + $obj = new berechtigung(); + + $obj->berechtigung_kurzbz = $row->berechtigung_kurzbz; + $obj->beschreibung = $row->beschreibung; + + $this->result[] = $obj; + } + return true; + } + else + { + $this->errormsg = 'Fehler beim Laden der Berechtigungen'; + return false; + } + } } ?> \ No newline at end of file diff --git a/vilesci/stammdaten/benutzerberechtigung_autocomplete.php b/vilesci/stammdaten/benutzerberechtigung_autocomplete.php new file mode 100644 index 000000000..07e57809e --- /dev/null +++ b/vilesci/stammdaten/benutzerberechtigung_autocomplete.php @@ -0,0 +1,116 @@ + + */ +require_once ('../../config/vilesci.config.inc.php'); +require_once ('../../include/functions.inc.php'); +require_once ('../../include/basis_db.class.php'); +require_once ('../../include/ort.class.php'); +require_once ('../../include/benutzer.class.php'); +require_once ('../../include/studiengang.class.php'); +require_once ('../../include/berechtigung.class.php'); +require_once ('../../include/organisationseinheit.class.php'); +require_once ('../../include/sprache.class.php'); + +if (! $db = new basis_db()) + die('Es konnte keine Verbindung zum Server aufgebaut werden.'); + +$uid = get_uid(); +$sprache = getSprache(); + +if (isset($_REQUEST['autocomplete']) && $_REQUEST['autocomplete'] == 'benutzer') +{ + $search = trim((isset($_REQUEST['term']) ? $_REQUEST['term'] : '')); + if (is_null($search) || $search == '') + exit(); + + $benutzer = new benutzer(); + + if ($benutzer->search(array( + $search + ))) + { + $result_obj = array(); + foreach ($benutzer->result as $row) + { + $item['vorname'] = html_entity_decode($row->vorname); + $item['nachname'] = html_entity_decode($row->nachname); + $item['uid'] = html_entity_decode($row->uid); + $result_obj[] = $item; + } + echo json_encode($result_obj); + } + exit(); +} + +if (isset($_REQUEST['autocomplete']) && $_REQUEST['autocomplete'] == 'berechtigung') +{ + $search = trim((isset($_REQUEST['term']) ? $_REQUEST['term'] : '')); + if (is_null($search) || $search == '') + exit(); + + $berechtigung = new berechtigung(); + + if ($berechtigung->searchBerechtigungen($search)) + { + $result_obj = array(); + foreach ($berechtigung->result as $row) + { + $item['berechtigung_kurzbz'] = html_entity_decode($row->berechtigung_kurzbz); + $item['beschreibung'] = html_entity_decode($row->beschreibung); + $result_obj[] = $item; + } + echo json_encode($result_obj); + } + exit(); +} + +if (isset($_REQUEST['autocomplete']) && $_REQUEST['autocomplete'] == 'oe_kurzbz') +{ + $search = trim((isset($_REQUEST['term']) ? $_REQUEST['term'] : '')); + if (is_null($search) || $search == '') + exit(); + + $search = array($search); + $oe = new organisationseinheit(); + $oe->search($search); + + $stg = new studiengang(); + $stg->search($search); + foreach($stg->result as $row) + { + if($row->aktiv===true) + $oe->result[] = new organisationseinheit($row->oe_kurzbz); + } + + if(is_array($oe->result) && count($oe->result) > 0) + { + $result_obj = array(); + foreach($oe->result as $row) + { + if($row->aktiv==true) + { + $item['oe_kurzbz'] = html_entity_decode($row->oe_kurzbz); + $item['organisationseinheittyp_kurzbz'] = html_entity_decode($row->organisationseinheittyp_kurzbz); + $item['bezeichnung'] = html_entity_decode($row->bezeichnung); + $result_obj[] = $item; + } + } + echo json_encode($result_obj); + } + exit(); +} + +?> diff --git a/vilesci/stammdaten/benutzerberechtigung_details.php b/vilesci/stammdaten/benutzerberechtigung_details.php index 83a9c34bb..03e7b15b9 100644 --- a/vilesci/stammdaten/benutzerberechtigung_details.php +++ b/vilesci/stammdaten/benutzerberechtigung_details.php @@ -37,7 +37,28 @@ require_once('../../include/person.class.php'); require_once('../../include/benutzer.class.php'); require_once('../../include/funktion.class.php'); require_once('../../include/wawi_kostenstelle.class.php'); +require_once('../../include/log.class.php'); +/* + * TODOs + * + +Checkbox-Range +Mehrfach-Löschen + + +Wawi und kostenstelle ausblenden +Checkbox markieren bei (doppel)klick auf Zeile + +---------------------- + +Nach übertragen gleich zu Person springen +Bug in Kopieren - Verdoppelt alle Einträge +Sortierreihenfolge. OE wird anscheinend nicht sortiert +ART prüfen auf schreibweise +BEschreibungstexte bestehender Rechte + + */ $user = get_uid(); $rechte = new benutzerberechtigung(); @@ -51,7 +72,8 @@ if(!$rechte->isBerechtigt('basis/berechtigung')) //$reloadstr = ''; // neuladen der liste im oberen frame $htmlstr = ''; -$errorstr = ''; //fehler beim insert +$errorstr = ''; +$successstr = ''; $sel = ''; $chk = ''; $oe_arr = array(); @@ -73,64 +95,161 @@ $neu = false; $negativ = false; $filter=(isset($_GET['filter'])?$_GET['filter']:'alle'); -if(isset($_POST['del'])) +if(isset($_POST['delete']) && $_POST['delete'] != '') { if(!$rechte->isBerechtigt('basis/berechtigung', null, 'suid')) - die('Sie haben keine Berechtigung fuer diese Aktion'); + die($rechte->errormsg); - $benutzerberechtigung_id = $_POST['benutzerberechtigung_id']; + $benutzerberechtigung_id = $_POST['delete']; $ber = new benutzerberechtigung(); if(!$ber->delete($benutzerberechtigung_id)) $errorstr .= 'Datensatz konnte nicht gelöscht werden!'; - //$reloadstr .= "\n"; + //$reloadstr .= ""; } -if(isset($_POST['kopieren'])) +if(isset($_POST['delete_multi']) && $_POST['delete_multi'] != '') { + if(!$rechte->isBerechtigt('basis/berechtigung', null, 'suid')) + die($rechte->errormsg); + + if (isset($_POST['dataset'])) + { + $i = 0; + foreach ($_POST['dataset'] AS $benutzerberechtigung_id => $value) + { + // Nur markierte Rechte kopieren + if (!isset($value['check'])) + { + continue; + } + + $ber = new benutzerberechtigung(); + if(!$ber->delete($benutzerberechtigung_id)) + { + $errorstr .= 'Datensatz konnte nicht gelöscht werden!'; + } + else + { + $i ++; + //Log schreiben + $log = new log(); + + $logdata = var_export((array) $ber, true); + $log->new = true; + $log->sql = $logdata; + $log->sqlundo = 'Kein Undo vorhanden'; + $log->executetime = date('Y-m-d H:i:s'); + $log->mitarbeiter_uid = $user; + $log->beschreibung = 'Berechtigung gelöscht'; + + if(!$log->save()) + { + $errorstr .= "Fehler beim schreiben des Log-Eintrags
"; + } + } + } + if ($errorstr == '') + { + $successstr .= "".$i." Rechte erfolgreich gelöscht
"; + } + } + + + + //$reloadstr .= ""; + +} + +if(isset($_POST['uebertragen']) && $_POST['uebertragen_nach'] != '') +{ + //echo '
', var_dump($_POST), '
';exit(); if($rechte->isBerechtigt('basis/berechtigung', null, 'suid')) { - $uid = $_POST['uid']; - $uid_von = $_POST['uid_von']; + $uidVon = $_POST['uid']; + $copyTo = $_POST['uebertragen_nach']; - $rechtevon = new benutzerberechtigung(); - if(!$rechtevon->loadBenutzerRollen($uid_von)) - die('Fehler beim Laden der Berechtigung von '.$uid_von); - - foreach($rechtevon->berechtigungen AS $row) + if (isset($_POST['dataset'])) { - //Nur aktive Berechtigungen kopieren - if(($row->start=='' || $row->start<=date('Y-m-d')) && ($row->ende=='' || $row->ende>=date('Y-m-d'))) + $i = 0; + foreach ($_POST['dataset'] AS $key => $value) { + // Nur markierte Rechte kopieren + if (!isset($value['check'])) + { + continue; + } + + $rolle_kurzbz = (isset($value['rolle_kurzbz']) ? $value['rolle_kurzbz'] : ''); + $berechtigung_kurzbz = (isset($value['berechtigung_kurzbz']) ? $value['berechtigung_kurzbz'] : ''); + $art = (isset($value['art']) ? $value['art'] : ''); + $oe_kurzbz = (isset($value['oe_kurzbz']) ? $value['oe_kurzbz'] : ''); + $kostenstelle_id = (isset($value['kostenstelle_id']) ? $value['kostenstelle_id'] : ''); + $start = (isset($value['start']) ? $value['start'] : ''); + $ende = (isset($value['ende']) ? $value['ende'] : ''); + $anmerkung = (isset($value['anmerkung']) ? $value['anmerkung'] : ''); + + $funktion_kurzbz = (isset($value['funktion_kurzbz']) ? $value['funktion_kurzbz'] : ''); + $studiensemester_kurzbz = null; + $ber = new benutzerberechtigung(); - $ber->new = true; - //$ber->benutzerberechtigung_id = $benutzerberechtigung_id; - $ber->art = $row->art; - $ber->oe_kurzbz = $row->oe_kurzbz; - $ber->berechtigung_kurzbz = $row->berechtigung_kurzbz; - $ber->rolle_kurzbz = $row->rolle_kurzbz; - $ber->uid = $uid; - $ber->funktion_kurzbz = $row->funktion_kurzbz; - $ber->studiensemester_kurzbz = $row->studiensemester_kurzbz; - $ber->start = $row->start; - $ber->ende = $row->ende; - $ber->negativ = $row->negativ; - $ber->insertamum=date('Y-m-d H:i:s'); + $ber->insertamum = date('Y-m-d H:i:s'); $ber->insertvon = $user; + $ber->new = true; + + if (isset($value['negativ'])) + $ber->negativ = true; + else + $ber->negativ = false; + + $ber->art = $art; + $ber->oe_kurzbz = $oe_kurzbz; + $ber->berechtigung_kurzbz = $berechtigung_kurzbz; + $ber->rolle_kurzbz = $rolle_kurzbz; + $ber->uid = $copyTo; + $ber->funktion_kurzbz = $funktion_kurzbz; + $ber->studiensemester_kurzbz = $studiensemester_kurzbz; + $ber->start = $start; + $ber->ende = $ende; $ber->updateamum = date('Y-m-d H:i:s'); $ber->updatevon = $user; - $ber->kostenstelle_id = $row->kostenstelle_id; - $ber->anmerkung = 'Kopiert von UID '.$uid_von.($row->anmerkung!=''?'. Anmerkung von UID '.$uid_von.': '.$row->anmerkung:''); + $ber->kostenstelle_id = $kostenstelle_id; + $ber->anmerkung = 'Kopiert von UID '.$uidVon.($anmerkung!=''?'. Anmerkung von UID '.$uidVon.': '.$anmerkung:''); if(!$ber->save()) { - if (!$ber->new) - $errorstr .= "Datensatz konnte nicht gespeichert werden!".$ber->errormsg; + $errorstr .= "Datensatz konnte nicht gespeichert werden!".$ber->errormsg; } + else + { + $i ++; + //Log schreiben + $log = new log(); + + $logdata = var_export((array) $ber, true); + $log->new = true; + $log->sql = $logdata; + $log->sqlundo = 'Kein Undo vorhanden'; + $log->executetime = date('Y-m-d H:i:s'); + $log->mitarbeiter_uid = $user; + $log->beschreibung = 'Berechtigung übertragen von '.$uidVon.' nach '.$copyTo; + + if(!$log->save()) + { + $errorstr .= "Fehler beim schreiben des Log-Eintrags
"; + } + } + } + if ($errorstr == '') + { + $successstr .= "".$i." Rechte erfolgreich kopiert
"; + echo ""; } } } @@ -140,71 +259,137 @@ if(isset($_POST['kopieren'])) } } -if(isset($_POST['schick']) || isset($_POST['copy'])) +if(isset($_POST['schick'])) { if($rechte->isBerechtigt('basis/berechtigung', null, 'suid')) { - $benutzerberechtigung_id = $_POST['benutzerberechtigung_id']; - $art = $_POST['art']; - $oe_kurzbz = (isset($_POST['oe_kurzbz'])?$_POST['oe_kurzbz']:''); - $berechtigung_kurzbz = (isset($_POST['berechtigung_kurzbz'])?$_POST['berechtigung_kurzbz']:''); - $rolle_kurzbz = (isset($_POST['rolle_kurzbz'])?$_POST['rolle_kurzbz']:''); - $uid = $_POST['uid']; - $funktion_kurzbz = $_POST['funktion_kurzbz']; - $studiensemester_kurzbz = null;//$_POST['studiensemester_kurzbz']; - $start = $_POST['start']; - $ende = $_POST['ende']; - $kostenstelle_id = (isset($_POST['kostenstelle_id'])?$_POST['kostenstelle_id']:''); - $anmerkung = (isset($_POST['anmerkung'])?$_POST['anmerkung']:''); + if (isset($_POST['dataset'])) + { + foreach ($_POST['dataset'] AS $benutzerberechtigung_id => $value) + { + $rolle_kurzbz = (isset($value['rolle_kurzbz']) ? $value['rolle_kurzbz'] : ''); + $berechtigung_kurzbz = (isset($value['berechtigung_kurzbz']) ? $value['berechtigung_kurzbz'] : ''); + $art = (isset($value['art']) ? $value['art'] : ''); + $oe_kurzbz = (isset($value['oe_kurzbz']) ? $value['oe_kurzbz'] : ''); + $kostenstelle_id = (isset($value['kostenstelle_id']) ? $value['kostenstelle_id'] : ''); + $start = (isset($value['start']) ? $value['start'] : ''); + $ende = (isset($value['ende']) ? $value['ende'] : ''); + $uid = $_POST['uid']; + $anmerkung = (isset($value['anmerkung']) ? $value['anmerkung'] : ''); + $funktion_kurzbz = (isset($_POST['funktion_kurzbz']) ? $_POST['funktion_kurzbz'] : ''); + $studiensemester_kurzbz = null; + + $ber = new benutzerberechtigung(); + if (isset($_POST['neu'])) + { + $ber->insertamum = date('Y-m-d H:i:s'); + $ber->insertvon = $user; + $ber->new = true; + } + else + { + if(!$ber->load($benutzerberechtigung_id)) + die('Fehler beim Laden der Berechtigung'); + } + if (isset($value['negativ'])) + $ber->negativ = true; + else + $ber->negativ = false; + + $ber->benutzerberechtigung_id = $benutzerberechtigung_id; + $ber->art = $art; + $ber->oe_kurzbz = $oe_kurzbz; + $ber->berechtigung_kurzbz = $berechtigung_kurzbz; + $ber->rolle_kurzbz = $rolle_kurzbz; + $ber->uid = $uid; + $ber->funktion_kurzbz = $funktion_kurzbz; + $ber->studiensemester_kurzbz = $studiensemester_kurzbz; + $ber->start = $start; + $ber->ende = $ende; + $ber->updateamum = date('Y-m-d H:i:s'); + $ber->updatevon = $user; + $ber->kostenstelle_id = $kostenstelle_id; + $ber->anmerkung = $anmerkung; + + if(!$ber->save()) + { + if (!$ber->new) + $errorstr .= "Datensatz konnte nicht upgedatet werden!".$ber->errormsg; + else + $errorstr .= "Datensatz konnte nicht gespeichert werden!".$ber->errormsg; + } + else + { + //Log schreiben + $log = new log(); + + $logdata = var_export((array) $ber, true); + $log->new = true; + $log->sql = $logdata; + $log->sqlundo = 'Kein Undo vorhanden'; + $log->executetime = date('Y-m-d H:i:s'); + $log->mitarbeiter_uid = $user; + if (isset($_POST['neu'])) + $log->beschreibung = 'Neue Berechtigung für '.$uid.' angelegt'; + else + $log->beschreibung = 'Berechtigung für '.$uid.' aktualisiert'; + + if(!$log->save()) + { + $errorstr .= "Fehler beim schreiben des Log-Eintrags
"; + } + } + } + } + } + else + { + $errorstr.='Fehler beim Speichern: '.$rechte->errormsg; + } +} + +if(isset($_POST['copy']) && $_POST['copy'] != '') +{ + if($rechte->isBerechtigt('basis/berechtigung', null, 'suid')) + { $ber = new benutzerberechtigung(); - if (isset($_POST['neu']) || isset($_POST['copy'])) - { - $ber->insertamum=date('Y-m-d H:i:s'); - $ber->insertvon = $user; - $ber->new = true; - } - else - { - if(!$ber->load($benutzerberechtigung_id)) - die('Fehler beim Laden der Berechtigung'); - } - if (isset($_POST['negativ'])) - $ber->negativ = true; - else - $ber->negativ = false; + if(!$ber->load($_POST['copy'])) + die('Fehler beim Laden der Berechtigung'); - $ber->benutzerberechtigung_id = $benutzerberechtigung_id; - $ber->art = $art; - $ber->oe_kurzbz = $oe_kurzbz; - $ber->berechtigung_kurzbz = $berechtigung_kurzbz; - $ber->rolle_kurzbz = $rolle_kurzbz; - $ber->uid = $uid; - $ber->funktion_kurzbz = $funktion_kurzbz; - $ber->studiensemester_kurzbz = $studiensemester_kurzbz; - $ber->start = $start; - $ber->ende = $ende; - $ber->updateamum = date('Y-m-d H:i:s'); - $ber->updatevon = $user; - $ber->kostenstelle_id = $kostenstelle_id; - $ber->anmerkung = $anmerkung; + $ber->new = true; + $ber->insertamum = date('Y-m-d H:i:s'); + $ber->insertvon = $user; - if(!$ber->save()){ + if(!$ber->save()) + { if (!$ber->new) $errorstr .= "Datensatz konnte nicht upgedatet werden!".$ber->errormsg; else $errorstr .= "Datensatz konnte nicht gespeichert werden!".$ber->errormsg; } - /*if ($ber->new) + else { - $reloadstr .= "\n"; - }*/ + //Log schreiben + $log = new log(); + + $logdata = var_export((array) $ber, true); + $log->new = true; + $log->sql = $logdata; + $log->sqlundo = 'Kein Undo vorhanden'; + $log->executetime = date('Y-m-d H:i:s'); + $log->mitarbeiter_uid = $user; + $log->beschreibung = 'Berechtigung für '.$uid.' kopiert'; + + if(!$log->save()) + { + $errorstr .= "Fehler beim schreiben des Log-Eintrags
"; + } + } } else { - $errorstr.='Fehler beim Speichern: Sie haben keine Berechtigung zum Speichern'; + $errorstr.='Fehler beim Speichern: '.$rechte->errormsg; } } @@ -220,10 +405,10 @@ sort($rolle_arr); $b->getBerechtigungen(); foreach($b->result as $berechtigung) { - $berechtigung_arr[] = $berechtigung->berechtigung_kurzbz; + $berechtigung_arr[$berechtigung->berechtigung_kurzbz] = $berechtigung->beschreibung; $berechtigung_beschreibung_arr[] = $berechtigung->beschreibung; } -//var_dump($berechtigung_arr); + $st = new studiensemester(); $st->getAll(); foreach($st->studiensemester as $studiensemester) @@ -233,6 +418,10 @@ foreach($st->studiensemester as $studiensemester) $oe = new organisationseinheit(); $oe->getAll(); +foreach ($oe->result AS $row) +{ + $oe_arr[$row->oe_kurzbz] = $row->organisationseinheittyp_kurzbz.' '.$row->bezeichnung; +} $kostenstelle = new wawi_kostenstelle(); $kostenstelle->getAll(); @@ -259,13 +448,16 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $rights->loadBenutzerRollen($uid); $name = new benutzer(); $name->load($uid); - $htmlstr .= "Berechtigungen von ".$name->nachname." ".$name->vorname." (".$uid.")\n"; + + $htmlstr .= "Berechtigungen von ".$name->nachname." ".$name->vorname." (".$uid.")"; + $htmlstr .= "

".$errorstr."

".$successstr."

"; + //Formular zum Kopieren von Berechtigungen - $htmlstr .= "
\n"; - $htmlstr .= "Berechtigungen (aktive) kopieren von UID \n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - $htmlstr .= "
\n"; + //$htmlstr .= "
"; + //$htmlstr .= "Berechtigungen (aktive) kopieren von UID "; + //$htmlstr .= ""; + //$htmlstr .= ""; + //$htmlstr .= "
"; $i = 0; // Zusätzlich jede Funktion mit einer gültigen Berechtigung anzeigen @@ -291,11 +483,13 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $i++; if ($i==1) { - $htmlstr .= "Geerbte Berechtigungen aus Funktion\n"; + $htmlstr .= "

Geerbte Berechtigungen aus Funktion(en) "; } - $htmlstr .= ($i>1?", ":"").$funktion_bezeichnung->beschreibung.""; + $htmlstr .= ($i > 1 ? ", " : "").$funktion_bezeichnung->beschreibung; } } + if(!empty($funktionsrecht)) + $htmlstr .= '

'; } } elseif(isset($_REQUEST['funktion_kurzbz']) && $_REQUEST['funktion_kurzbz']!='') @@ -307,10 +501,10 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) die('Funktion existiert nicht'); $rights->loadBenutzerRollen(null, $funktion_kurzbz); - $htmlstr .= "Berechtigungen der Funktion ".$funktion->beschreibung."\n"; + $htmlstr .= "Berechtigungen der Funktion ".$funktion->beschreibung.""; } - //$htmlstr .= "Berechtigungen von ".$name->nachname." ".$name->vorname." (".$uid.")".$funktion_kurzbz."\n"; + //$htmlstr .= "Berechtigungen von ".$name->nachname." ".$name->vorname." (".$uid.")".$funktion_kurzbz.""; /*$htmlstr .= '      Filter: Alle | nur WaWi @@ -318,16 +512,19 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) ';*/ - $htmlstr .= "\n"; //Alternatives styling fuer Tablesorter um Platz zu sparen. - $htmlstr .= "\n"; + //////////////// + // Neue Berechtigung einfügen + //////////////// + + $htmlstr .= "
"; + $htmlstr .= ""; $htmlstr .= " - - - + + @@ -335,63 +532,52 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) - - \n"; + "; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; + $htmlstr .= ""; + $htmlstr .= ""; + $htmlstr .= ""; + $htmlstr .= ""; + $htmlstr .= ""; + $htmlstr .= ""; - //Status - $htmlstr .= " \n"; + $htmlstr .= ""; //Rolle - $htmlstr .= " \n"; + $htmlstr .= " "; //Berechtigung_kurzbz - $htmlstr .= " \n"; + $htmlstr .= " "; //Art - $htmlstr .= " \n"; + $htmlstr .= " "; //Organisationseinheit - if($funktion_kurzbz!='') - $htmlstr .= " \n"; + if($funktion_kurzbz != '') + { + $htmlstr .= " "; + } else { - $htmlstr .= " \n"; + $htmlstr .= " "; } //Kostenstelle - $htmlstr .= " \n"; + $htmlstr .= " "; - $htmlstr .= " \n"; - $htmlstr .= " \n"; - $htmlstr .= " \n"; + //Negativ + $htmlstr .= " "; + + //Start + $htmlstr .= " "; + + //Ende + $htmlstr .= " "; //Anmerkung - $htmlstr .= " \n"; + $htmlstr .= " "; - $htmlstr .= " "; - $htmlstr .= "\n"; - $htmlstr .= " \n"; + $htmlstr .= " "; + $htmlstr .= ""; + $htmlstr .= "
Rolle Berechtigung ArtOrganisationseinheitKostenstelleOrganisationseinheitKostenstelle Neg Gültig ab Gültig bisInfo
 Neu: "; + $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= " OE aus MA-FunktionOE aus MA-Funktion"; + $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= "
"; + + $htmlstr .= "
"; + + //////////////// + // Tabelle für bestehende Berechtigungen + //////////////// + + $htmlstr .= "
"; + + $htmlstr .= ""; + $htmlstr .= ""; + $htmlstr .= " + + + +
+ + +
+ "; + $htmlstr .= ""; + $htmlstr .= ""; + $htmlstr .= " + + + + + + + + + + + + + + + "; foreach($rights->berechtigungen as $b) { @@ -430,199 +659,139 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) break; default: break; } - if(isset($_POST['edit']) && $_POST['benutzerberechtigung_id']==$b->benutzerberechtigung_id) + + $htmlstr .= " "; + $heute = strtotime(date('Y-m-d')); + if ($b->ende!='' && strtotime($b->ende) < $heute) { - $htmlstr .= " \n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - - $heute = strtotime(date('Y-m-d')); - if ($b->ende!='' && strtotime($b->ende)<$heute) - { - $status="ampel_rot.png"; - $titel="ccc"; - } - elseif ($b->start!='' && strtotime($b->start)>$heute) - { - $status="ampel_gelb.png"; - $titel="bbb"; - } - else - { - $status="ampel_gruen.png"; - $titel="aaa"; - } - //Status - $htmlstr .= " \n"; - //Rolle - $htmlstr .= " \n"; - - //Berechtigung - $htmlstr .= " \n"; - - //Art - $htmlstr .= " \n"; - - //Organisationseinheit - if($funktion_kurzbz!='') - $htmlstr .= " \n"; - else - { - $htmlstr .= " \n"; - } - - //Kostenstelle - $htmlstr .= " \n"; - - $htmlstr .= " \n"; - $htmlstr .= " \n"; - $htmlstr .= " \n"; - $htmlstr .= " \n"; - $htmlstr .= " \n"; - - $htmlstr .= " "; - $htmlstr .= " "; - $htmlstr .= "\n"; - $htmlstr .= " \n"; + $titel="ccc"; + $style = 'style="border-left: 10px solid tomato; border-right: 10px solid transparent; text-align: center; vertical-align: middle"'; + } + elseif ($b->start!='' && strtotime($b->start) > $heute) + { + $titel="bbb"; + $style = 'style="border-left: 10px solid gold; border-right: 10px solid transparent; text-align: center; vertical-align: middle"'; } else { - $htmlstr .= " \n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; - $htmlstr .= "\n"; + $titel="aaa"; + $style = 'style="border-left: 10px solid LightGreen; border-right: 10px solid transparent; text-align: center; vertical-align: middle"'; + } + // Auswahlcheckbox + $htmlstr .= " "; - $heute = strtotime(date('Y-m-d')); - if ($b->ende!='' && strtotime($b->ende)<$heute) + //Rolle + $htmlstr .= " \n"; - //Rolle - $htmlstr .= " \n"; + $sel = ""; + $htmlstr .= ""; + } + $htmlstr .= " "; + $htmlstr.=""; - //Berechtigung - $htmlstr .= " \n"; + //Berechtigung + $htmlstr .= " "; - //Art - $htmlstr .= " \n"; + //Art + $htmlstr .= " "; - //Organisationseinheit - $oekey = $oe->result; - $org = new organisationseinheit(); - $org->load($b->oe_kurzbz); - $htmlstr .= " \n"; - - //Kostenstelle - $kst = new wawi_kostenstelle(); - $kst->load($b->kostenstelle_id); - if(!$kst->aktiv) - $style='style="text-decoration:line-through;"'; - else - $style=''; - $htmlstr .= " \n"; - - - $htmlstr .= " \n"; - $htmlstr .= " \n"; - $htmlstr .= " \n"; - $htmlstr .= " \n"; - $htmlstr .= " \n"; - - $htmlstr .= " "; - $htmlstr .= " "; - $htmlstr .= "\n"; - $htmlstr .= " \n"; + //Organisationseinheit + if($funktion_kurzbz != '') + { + $htmlstr .= " "; + } + else + { + $htmlstr .= " "; } + //Kostenstelle + $htmlstr .= " "; + + //Negativ-Checkbox + $htmlstr .= " "; + + //Gültig ab + $htmlstr .= " "; + + // Gültig bis + $htmlstr .= " "; + + //Anmerkung + $htmlstr .= " "; + + //Info + $htmlstr .= " "; + + $htmlstr .= " "; + $htmlstr .= " "; } - - $htmlstr .= "
RolleBerechtigungArtOrganisationseinheitKostenstelleNegGültig abGültig bisAnmerkungInfo
aktiv"; - - // Wenn editiert wird, zu der Zeile Springen - $htmlstr.=" - - "; - $htmlstr.="OE aus MA-Funktionnegativ?'checked="checked"':'')." onchange='markier(\"td_".$b->benutzerberechtigung_id."\")'>anmerkung))."' size='30' maxlength='256' markier(\"td_".$b->benutzerberechtigung_id."\")'>information  
"; + $htmlstr .= " ".$titel.""; + $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= " aktiv$b->rolle_kurzbz$b->berechtigung_kurzbz"; + $htmlstr .= " ".$b->berechtigung_kurzbz.""; + $htmlstr .= " berechtigung_kurzbz] : '')."'>"; + $htmlstr .= " ".$b->art.""; + $htmlstr .= " ".$b->art.""; + $htmlstr .= " "; + $htmlstr .= " ".$org->organisationseinheittyp_kurzbz." ".$org->bezeichnung."$kst->bezeichnungnegativ?'checked="checked"':'')." onchange='markier(\"td_".$b->benutzerberechtigung_id."\")' disabled>".$b->start."".$b->ende."".$b->anmerkung."information
OE aus MA-Funktion"; + $htmlstr .= " ".($b->oe_kurzbz != '' ? $oe_arr[$b->oe_kurzbz] : '').""; + $htmlstr .= " "; + $htmlstr .= " oe_kurzbz] : '')."'>"; + $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= " negativ?'checked="checked"':'').">"; + $htmlstr .= " "; + $htmlstr .= " ".$b->start.""; + $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= " ".$b->ende.""; + $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= " anmerkung))."' size='30' maxlength='256'>"; + $htmlstr .= " information"; + $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= "
\n"; + $htmlstr .= ""; + $htmlstr .= '
+
'; + $htmlstr .= ''; + $htmlstr .= ' + +
'; + $htmlstr .= ""; } -$htmlstr .= "
".$errorstr."
\n"; + ?> @@ -635,58 +804,19 @@ $htmlstr .= "
".$errorstr."
\n"; - - - + + + + + + @@ -1052,11 +1188,15 @@ $htmlstring .= "" . $p->t('benotungstool/punkte') . ' / ' . $p->t('benotungs if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) { - $htmlstring .= "" . $p->t('benotungstool/nachpruefung') . ""; + $htmlstring .= "
" . $p->t('benotungstool/nachpruefung') . "
+ + "; } if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) { - $htmlstring .= "" . $p->t('benotungstool/nachpruefung2') . ""; + $htmlstring .= "
" . $p->t('benotungstool/nachpruefung') . "
+ + "; } if (defined('CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF') && CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF) { diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index 0ad985e76..81545a7f6 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -41,10 +41,15 @@ require_once('../../../../include/benutzerfunktion.class.php'); require_once('../../../../include/benutzer.class.php'); require_once('../../../../include/student.class.php'); require_once('../../../../include/notenschluessel.class.php'); +require_once('../../../../include/phrasen.class.php'); + if (!$db = new basis_db()) die('Fehler beim Herstellen der Datenbankverbindung'); +$sprache = getSprache(); +$p = new phrasen($sprache); + $user = get_uid(); if(!check_lektor($user)) @@ -52,6 +57,7 @@ if(!check_lektor($user)) $lehreinheit_id=''; +$lehreinheit_id_pr=''; if(isset($_GET['lvid']) && is_numeric($_GET['lvid'])) //Lehrveranstaltung_id $lvid = $_GET['lvid']; @@ -62,60 +68,17 @@ if(isset($_GET['lehreinheit_id']) && is_numeric($_GET['lehreinheit_id'])) //Lehr $lehreinheit_id = $_GET['lehreinheit_id']; if(isset($_GET['lehreinheit_id_pr']) && is_numeric($_GET['lehreinheit_id_pr'])) //Lehreinheit_id der pruefung - $lehreinheit_id = $_GET['lehreinheit_id_pr']; - -if(isset($_GET['datum'])) -{ - $datum = $_GET['datum']; - $datum_obj = new datum(); - $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); -} -else - die('Fehlerhafte Parameteruebergabe'); - -//Laden der Lehrveranstaltung -$lv_obj = new lehrveranstaltung(); -if(!$lv_obj->load($lvid)) - die($lv_obj->errormsg); - -//Studiengang laden -$stg_obj = new studiengang($lv_obj->studiengang_kz); + $lehreinheit_id_pr = $_GET['lehreinheit_id_pr']; if(isset($_GET['stsem'])) $stsem = $_GET['stsem']; else $stsem = ''; - -$uebung_id = (isset($_GET['uebung_id'])?$_GET['uebung_id']:''); -$uid = (isset($_GET['uid'])?$_GET['uid']:''); - //Studiensemester laden $stsem_obj = new studiensemester(); if($stsem=='') $stsem = $stsem_obj->getaktorNext(); -$student_uid = $_REQUEST["student_uid"]; - -$note = $_REQUEST["note"]; -if(isset($_REQUEST['punkte'])) - $punkte = $_REQUEST['punkte']; -else - $punkte = ''; - -$punkte = str_replace(',','.',$punkte); - -if($punkte!='') -{ - // Bei Punkteeingabe wird die Note nochmals geprueft und ggf korrigiert - $notenschluessel = new notenschluessel(); - $note_pruef = $notenschluessel->getNote($punkte, $lvid, $stsem); - if($note_pruef!=$note) - { - $note = $note_pruef; - $note_dirty=true; - } -} - if(!isset($_GET['typ'])) { $typ='Termin2'; @@ -128,16 +91,151 @@ else die('Typ ist ungueltig'); } -if($note=='') - $note = 9; - -$old_note = $note; - -// lvgesamtnote für studenten speichern -if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) +if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) +{ + foreach ($_POST as $row=>$val) + { + if(mb_strstr(mb_strtolower($row), 'student_uid_')) + { + $id=mb_substr($row, mb_strlen('student_uid_')); + + $student_uid = $_POST['student_uid_'.$id]; + $note = null; + $punkte = null; + $datum = null; + if(isset($_POST['note_'.$id])) + $note = $_POST['note_'.$id]; + elseif(isset($_POST['punkte_'.$id])) + $punkte = $_POST['punkte_'.$id]; + else + { + $response.="\nNote oder Punkte fehlen"; + continue; + } + $punkte=str_replace(',','.', $punkte); + + $datum = $_POST['datumNachp_'.$id]; + + // //check ob Matrikelnummer anstelle der student_uid übergeben wurde + // + // + // $student = new student(); + // + // + // $response2 = true; + // if (!$student->checkIfValidStudentUID($student_uid)) + // { + // //UID ermitteln + // if(!$student_uid = $student->getUidFromMatrikelnummer($student_uid)) + // { + // $response2 = false; + // $response2.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($student_uid)); + // continue; + // } + // } + + + $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); + + if(isset($_POST['student_uid_'.$id]) && (isset($_POST['note_'.$id]) || isset($_POST['punkte_'.$id])) && isset($_POST['datumNachp_'.$id])) + { + // echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . + // $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . "\n"; + + $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte); + + echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . + $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . " response" . $response . "\n"; + // echo $response; + + } + else + { + echo "\n fehlende oder fehlerhafte Inputparameter"; + } + } + } + +} +else +{ + // Einzelupdate + + if(isset($_GET['datum']) ) + { + $datum = $_GET['datum']; + $datum_obj = new datum(); + $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); + } + + // echo "Variante Einzel"; + else + die('Fehlerhafte Parameteruebergabe'); + + $student_uid = $_REQUEST["student_uid"]; + + $note = $_REQUEST["note"]; + if(isset($_REQUEST['punkte'])) + $punkte = $_REQUEST['punkte']; + else + $punkte = ''; + + $punkte = str_replace(',','.',$punkte); + + if($punkte!='') + { + // Bei Punkteeingabe wird die Note nochmals geprueft und ggf korrigiert + $notenschluessel = new notenschluessel(); + $note_pruef = $notenschluessel->getNote($punkte, $lvid, $stsem); + if($note_pruef!=$note) + { + $note = $note_pruef; + $note_dirty=true; + } + } + + if($note=='') + $note = 9; + + $old_note = $note; + + //Laden der Lehrveranstaltung + $lv_obj = new lehrveranstaltung(); + if(!$lv_obj->load($lvid)) + die($lv_obj->errormsg); + + //Studiengang laden + $stg_obj = new studiengang($lv_obj->studiengang_kz); + + $uebung_id = (isset($_GET['uebung_id'])?$_GET['uebung_id']:''); + $uid = (isset($_GET['uid'])?$_GET['uid']:''); + + // lvgesamtnote für studenten speichern + if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) + { + // Die Pruefung muss einer Lehreinheit zugeordnet werden + // deshalb wird hier versucht eine passende Lehreinheit zu ermitteln. + + $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); + + $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note); + echo $response; + } + else + echo "Fehler beim Eintragen der Prüfungen"; + +} + +/** + * Berechnet Lehreinheit auf Basis LV-Daten + * @param string $db Datenbankvariable + * @param string $student_uid student_uid + * @param int $lvid Lehrveranstaltungsid + * @param string $stsem Studiensemester im Format 'WSYYYY' + * @return String LehreinheitId + */ +function getLehreinheit($db, $lvid, $student_uid, $stsem) { - // Die Pruefung muss einer Lehreinheit zugeordnet werden - // deshalb wird hier versucht eine passende Lehreinheit zu ermitteln. $le_arr = array(); $qry_stud = "SELECT lehreinheit_id, lehrform_kurzbz FROM @@ -158,104 +256,117 @@ if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) } } - if (!in_array($lehreinheit_id,$le_arr)) + //if (!in_array($lehreinheit_id,$le_arr)) $lehreinheit_id = $le_arr[0]; + return $lehreinheit_id; +} + +/** + * Prüfung speichern + */ +function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte=null) +{ $jetzt = date("Y-m-d H:i:s"); + global $user; //, $note, $punkte, $datum; - $pr = new Pruefung(); - - // Wenn eine Pruefung angelegt wird, wird zuerst eine Pruefung mit 1. Termin angelegt - // und dort die Zeugnisnote gespeichert - if($pr->getPruefungen($student_uid, "Termin1", $lvid, $stsem)) + if ($typ == "Termin2") { - if ($pr->result) + $pr = new Pruefung(); + // Wenn eine Pruefung angelegt wird, wird zuerst eine Pruefung mit 1. Termin angelegt + // und dort die Zeugnisnote gespeichert + if($pr->getPruefungen($student_uid, "Termin1", $lvid, $stsem)) { - $termin1 = 1; - } - else - { - $lvnote = new lvgesamtnote(); - if ($lvnote->load($lvid, $student_uid, $stsem)) + if ($pr->result) { - $pr_note = $lvnote->note; - $pr_punkte = $lvnote->punkte; - $benotungsdatum = $lvnote->benotungsdatum; + $termin1 = 1; } else { - $pr_note = 9; - $pr_punkte = ''; - $benotungsdatum = $jetzt; + $lvnote = new lvgesamtnote(); + if ($lvnote->load($lvid, $student_uid, $stsem)) + { + $pr_note = $lvnote->note; + $pr_punkte = $lvnote->punkte; + $benotungsdatum = $lvnote->benotungsdatum; + } + else + { + $pr_note = 9; + $pr_punkte = ''; + $benotungsdatum = $jetzt; + } + + $pr_1 = new Pruefung(); + $pr_1->lehreinheit_id = $lehreinheit_id; + $pr_1->student_uid = $student_uid; + $pr_1->mitarbeiter_uid = $user; + $pr_1->note = $pr_note; + $pr_1->punkte = $pr_punkte; + $pr_1->pruefungstyp_kurzbz = "Termin1"; + $pr_1->datum = $benotungsdatum; + $pr_1->anmerkung = ""; + $pr_1->insertamum = $jetzt; + $pr_1->insertvon = $user; + $pr_1->updateamum = null; + $pr_1->updatevon = null; + $pr_1->ext_id = null; + $pr_1->new = true; + $pr_1->save(); + $response = "neu T1"; } - $pr_1 = new Pruefung(); - $pr_1->lehreinheit_id = $lehreinheit_id; - $pr_1->student_uid = $student_uid; - $pr_1->mitarbeiter_uid = $user; - $pr_1->note = $pr_note; - $pr_1->punkte = $pr_punkte; - $pr_1->pruefungstyp_kurzbz = "Termin1"; - $pr_1->datum = $benotungsdatum; - $pr_1->anmerkung = ""; - $pr_1->insertamum = $jetzt; - $pr_1->insertvon = $user; - $pr_1->updateamum = null; - $pr_1->updatevon = null; - $pr_1->ext_id = null; - $pr_1->new = true; - $pr_1->save(); + $prTermin2 = new Pruefung(); + $pr_2 = new Pruefung(); + + // Die Pruefung wird als Termin2 eingetragen + if ($prTermin2->getPruefungen($student_uid, 'Termin2', $lvid, $stsem)) + { + if ($prTermin2->result) + { + $pr_2->load($prTermin2->result[0]->pruefung_id); + $pr_2->new = null; + $pr_2->updateamum = $jetzt; + $pr_2->updatevon = $user; + $old_note = $pr_2->note; + $pr_2->note = $note; + $pr_2->punkte = $punkte; + $pr_2->datum = $datum; + $pr_2->anmerkung = ""; + $response = "update T2"; + } + else + { + $pr_2->lehreinheit_id = $lehreinheit_id; + $pr_2->student_uid = $student_uid; + $pr_2->mitarbeiter_uid = $user; + $pr_2->note = $note; + $pr_2->punkte = $punkte; + $pr_2->pruefungstyp_kurzbz = $typ; + $pr_2->datum = $datum; + $pr_2->anmerkung = ""; + $pr_2->insertamum = $jetzt; + $pr_2->insertvon = $user; + $pr_2->updateamum = null; + $pr_2->updatevon = null; + $pr_2->ext_id = null; + $pr_2->new = true; + $old_note = -1; + $response = "new T2"; + } + $pr_2->save(); + } } } - - - $prTermin2 = new Pruefung(); - $pr_2 = new Pruefung(); - - // Die Pruefung wird als Termin2 eingetragen - if ($prTermin2->getPruefungen($student_uid, $typ, $lvid, $stsem)) + else { - if ($prTermin2->result) - { - $pr_2->load($prTermin2->result[0]->pruefung_id); - $pr_2->new = null; - $pr_2->updateamum = $jetzt; - $pr_2->updatevon = $user; - $old_note = $pr_2->note; - $pr_2->note = $note; - $pr_2->punkte = $punkte; - $pr_2->datum = $datum; - $pr_2->anmerkung = ""; - } - else - { - $pr_2->lehreinheit_id = $lehreinheit_id; - $pr_2->student_uid = $student_uid; - $pr_2->mitarbeiter_uid = $user; - $pr_2->note = $note; - $pr_2->punkte = $punkte; - $pr_2->pruefungstyp_kurzbz = $typ; - $pr_2->datum = $datum; - $pr_2->anmerkung = ""; - $pr_2->insertamum = $jetzt; - $pr_2->insertvon = $user; - $pr_2->updateamum = null; - $pr_2->updatevon = null; - $pr_2->ext_id = null; - $pr_2->new = true; - $old_note = -1; - } - $pr_2->save(); + $response = "no existing T3"; } - - // Wenn eine Pruefung eingetragen wird, wird danach die LV-Note korrigiert - $jetzt = date("Y-m-d H:i:s"); - - $lvid = $_REQUEST["lvid"]; + //Gesamtnote updaten $lvgesamtnote = new lvgesamtnote(); - if (!$lvgesamtnote->load($lvid, $student_uid, $stsem)) - { + if (!$lvgesamtnote->load($lvid, $student_uid, $stsem)) + { $lvgesamtnote->student_uid = $student_uid; $lvgesamtnote->lehrveranstaltung_id = $lvid; $lvgesamtnote->studiensemester_kurzbz = $stsem; @@ -272,9 +383,9 @@ if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) $lvgesamtnote->insertvon = $user; $new = true; $response = "neu"; - } - else - { + } + else + { $lvgesamtnote->note = $note; $lvgesamtnote->punkte = $punkte; $lvgesamtnote->benotungsdatum = $jetzt; @@ -286,12 +397,11 @@ if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) else $response = "update"; } + if (!$lvgesamtnote->save($new)) - echo "".$lvgesamtnote->errormsg.""; + return $lvgesamtnote->errormsg; else - echo $response; + return $response; } -else - echo "Fehler beim Eintragen der Prüfungen"; ?> From 035d196ae5cb45b44a4f2f863e7bf5fd0ddbe872 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 13 Oct 2022 08:04:10 +0200 Subject: [PATCH 015/439] Logik Matrikelnummer StudentenId --- .../benotungstool/nachpruefungeintragen.php | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index 81545a7f6..d1a7e2326 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -99,6 +99,8 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) { $id=mb_substr($row, mb_strlen('student_uid_')); + $response2 = ''; + $student_uid = $_POST['student_uid_'.$id]; $note = null; $punkte = null; @@ -115,24 +117,21 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $punkte=str_replace(',','.', $punkte); $datum = $_POST['datumNachp_'.$id]; + $datum_obj = new datum(); + $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); // //check ob Matrikelnummer anstelle der student_uid übergeben wurde - // - // - // $student = new student(); - // - // - // $response2 = true; - // if (!$student->checkIfValidStudentUID($student_uid)) - // { - // //UID ermitteln - // if(!$student_uid = $student->getUidFromMatrikelnummer($student_uid)) - // { - // $response2 = false; - // $response2.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($student_uid)); - // continue; - // } - // } + + $student = new student(); + if (!$student->checkIfValidStudentUID($student_uid)) + { + //UID ermitteln + if(!$student_uid = $student->getUidFromMatrikelnummer($student_uid)) + { + $response2.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($student_uid)); + continue; + } + } $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); @@ -146,7 +145,7 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . " response" . $response . "\n"; - // echo $response; + echo $response2; } else @@ -168,7 +167,6 @@ else $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); } - // echo "Variante Einzel"; else die('Fehlerhafte Parameteruebergabe'); From 29fc5181bf237ba65337de647f1180c4d9420b9d Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 13 Oct 2022 10:16:26 +0200 Subject: [PATCH 016/439] Importfunktion Termin3 --- .../benotungstool/lvgesamtnoteverwalten.php | 2 +- .../benotungstool/nachpruefungeintragen.php | 48 +++++++++++++++++-- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index 6a160c646..80bb7c5a5 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -1194,7 +1194,7 @@ if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN } if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) { - $htmlstring .= "
" . $p->t('benotungstool/nachpruefung') . "
+ $htmlstring .= "
" . $p->t('benotungstool/nachpruefung2') . "
"; } diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index d1a7e2326..e8553ce7b 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -120,8 +120,7 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $datum_obj = new datum(); $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); - // //check ob Matrikelnummer anstelle der student_uid übergeben wurde - + //check ob Matrikelnummer anstelle der student_uid übergeben wurde $student = new student(); if (!$student->checkIfValidStudentUID($student_uid)) { @@ -138,9 +137,6 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) if(isset($_POST['student_uid_'.$id]) && (isset($_POST['note_'.$id]) || isset($_POST['punkte_'.$id])) && isset($_POST['datumNachp_'.$id])) { - // echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . - // $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . "\n"; - $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte); echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . @@ -356,6 +352,48 @@ function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ } } } + elseif ($typ == "Termin3") + { + $prTermin3 = new Pruefung(); + $pr_3 = new Pruefung(); + + if ($prTermin3->getPruefungen($student_uid, 'Termin3', $lvid, $stsem)) + { + if ($prTermin3->result) + { + $pr_3->load($prTermin3->result[0]->pruefung_id); + $pr_3->new = null; + $pr_3->updateamum = $jetzt; + $pr_3->updatevon = $user; + $old_note = $pr_3->note; + $pr_3->note = $note; + $pr_3->punkte = $punkte; + $pr_3->datum = $datum; + $pr_3->anmerkung = ""; + $response = "Prüfung Termin3 aktualisiert"; + } + else + { + $pr_3->lehreinheit_id = $lehreinheit_id; + $pr_3->student_uid = $student_uid; + $pr_3->mitarbeiter_uid = $user; + $pr_3->note = $note; + $pr_3->punkte = $punkte; + $pr_3->pruefungstyp_kurzbz = $typ; + $pr_3->datum = $datum; + $pr_3->anmerkung = ""; + $pr_3->insertamum = $jetzt; + $pr_3->insertvon = $user; + $pr_3->updateamum = null; + $pr_3->updatevon = null; + $pr_3->ext_id = null; + $pr_3->new = true; + $old_note = -1; + $response = "neue Prüfung Termin3"; + } + $pr_3->save(); + } + } else { $response = "no existing T3"; From ce3cea5515721e933b621cf9f2902ddca5aecf21 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 13 Oct 2022 15:36:08 +0200 Subject: [PATCH 017/439] Validierungen Format Datum, Matrikelnr, StudentId, Note --- .../benotungstool/lvgesamtnoteverwalten.php | 61 +++++++++---------- .../benotungstool/nachpruefungeintragen.php | 51 +++++++--------- locale/de-AT/benotungstool.php | 4 +- locale/en-US/benotungstool.php | 1 + 4 files changed, 56 insertions(+), 61 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index 80bb7c5a5..8a428ff2a 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -20,33 +20,33 @@ * Gerald Simane-Sequens < gerald.simane-sequens@technikum-wien.at > * Manuela Thamer */ -require_once ('../../../../config/cis.config.inc.php'); -require_once ('../../../../config/global.config.inc.php'); -require_once ('../../../../include/functions.inc.php'); -require_once ('../../../../include/lehrveranstaltung.class.php'); -require_once ('../../../../include/studiengang.class.php'); -require_once ('../../../../include/studiensemester.class.php'); -require_once ('../../../../include/lehreinheit.class.php'); -require_once ('../../../../include/benutzerberechtigung.class.php'); -require_once ('../../../../include/uebung.class.php'); -require_once ('../../../../include/beispiel.class.php'); -require_once ('../../../../include/studentnote.class.php'); -require_once ('../../../../include/datum.class.php'); -require_once ('../../../../include/legesamtnote.class.php'); -require_once ('../../../../include/lvgesamtnote.class.php'); -require_once ('../../../../include/zeugnisnote.class.php'); -require_once ('../../../../include/pruefung.class.php'); -require_once ('../../../../include/person.class.php'); -require_once ('../../../../include/benutzer.class.php'); -require_once ('../../../../include/mitarbeiter.class.php'); -require_once ('../../../../include/mail.class.php'); -require_once ('../../../../include/phrasen.class.php'); -require_once ('../../../../include/note.class.php'); -require_once ('../../../../include/notenschluessel.class.php'); -require_once ('../../../../include/studienplan.class.php'); -require_once ('../../../../include/addon.class.php'); -require_once ('../../../../include/mobilitaet.class.php'); -require_once ('../../../../include/student.class.php'); +require_once('../../../../config/cis.config.inc.php'); +require_once('../../../../config/global.config.inc.php'); +require_once('../../../../include/functions.inc.php'); +require_once('../../../../include/lehrveranstaltung.class.php'); +require_once('../../../../include/studiengang.class.php'); +require_once('../../../../include/studiensemester.class.php'); +require_once('../../../../include/lehreinheit.class.php'); +require_once('../../../../include/benutzerberechtigung.class.php'); +require_once('../../../../include/uebung.class.php'); +require_once('../../../../include/beispiel.class.php'); +require_once('../../../../include/studentnote.class.php'); +require_once('../../../../include/datum.class.php'); +require_once('../../../../include/legesamtnote.class.php'); +require_once('../../../../include/lvgesamtnote.class.php'); +require_once('../../../../include/zeugnisnote.class.php'); +require_once('../../../../include/pruefung.class.php'); +require_once('../../../../include/person.class.php'); +require_once('../../../../include/benutzer.class.php'); +require_once('../../../../include/mitarbeiter.class.php'); +require_once('../../../../include/mail.class.php'); +require_once('../../../../include/phrasen.class.php'); +require_once('../../../../include/note.class.php'); +require_once('../../../../include/notenschluessel.class.php'); +require_once('../../../../include/studienplan.class.php'); +require_once('../../../../include/addon.class.php'); +require_once('../../../../include/mobilitaet.class.php'); +require_once('../../../../include/student.class.php'); $summe_stud = 0; $summe_t2 = 0; @@ -190,7 +190,7 @@ foreach ($noten_obj->result as $row) $noten_array[$row->note]['lehre'] = $row->lehre; $noten_array[$row->note]['lkt_ueberschreibbar'] = $row->lkt_ueberschreibbar; $noten_array[$row->note]['anmerkung'] = $row->anmerkung; - foreach ($sprachen->result AS $s) + foreach ($sprachen->result as $s) $noten_array[$row->note]['bezeichnung_mehrsprachig'][$s->sprache] = $row->bezeichnung_mehrsprachig[$s->sprache]; } @@ -376,7 +376,7 @@ foreach ($noten_obj->result as $row) var datum_test = datum.split("."); if (datum_test[0].length != 2 || datum_test[1].length != 2 || datum_test[2].length!=4 || isNaN(datum_test[2]) || datum_test[1]>12 || datum_test[1]<1 || datum_test[0]>31 || datum_test[0]<1) - alert("Invalid Date Format: DD.MM.YYYY"); + alert("Das Datum entspricht nicht dem Format TT.MM.JJJJ!"); else { var anlegendiv = document.getElementById("nachpruefung_div"); @@ -939,7 +939,6 @@ if (defined('CIS_ANWESENHEITSLISTE_NOTENLISTE_ANZEIGEN') && CIS_ANWESENHEITSLIST { $hrefpath = "../notenliste.xls.php?stg=$stg_obj->studiengang_kz&lvid=$lvid&stsem=$stsem"; echo "
" . $p->t('benotungstool/notenlisteImport') . ""; - } // eingetragene lv-gesamtnoten freigeben @@ -1333,7 +1332,6 @@ if (defined("CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE") && CIS_GESAMTNOTE_PRUEFUNG foreach ($grades as $uid => $data) //Ausgabe Array { - $htmlstring .= ' ' . $db->convert_html_chars($uid) . ' @@ -1465,7 +1463,6 @@ if (defined("CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE") && CIS_GESAMTNOTE_PRUEFUNG // Punkte if (CIS_GESAMTNOTE_PUNKTE) { - $htmlstring .= ' $val) + $errorMatrnr = ''; + $errorDatum = ''; + foreach ($_POST as $row => $val) { if(mb_strstr(mb_strtolower($row), 'student_uid_')) { $id=mb_substr($row, mb_strlen('student_uid_')); - $response2 = ''; - $student_uid = $_POST['student_uid_'.$id]; $note = null; $punkte = null; @@ -114,35 +114,36 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $response.="\nNote oder Punkte fehlen"; continue; } - $punkte=str_replace(',','.', $punkte); + $punkte=str_replace(',', '.', $punkte); $datum = $_POST['datumNachp_'.$id]; + //check Datumsformat + $checkedDatum = $datum; $datum_obj = new datum(); - $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); + if(!$datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true)) + { + $errorDatum .="\n".$p->t('benotungstool/datumsformatUnzulaessig', array($checkedDatum)); + continue; + } //check ob Matrikelnummer anstelle der student_uid übergeben wurde $student = new student(); if (!$student->checkIfValidStudentUID($student_uid)) { + $checkedMatrnr = $student_uid; //UID ermitteln if(!$student_uid = $student->getUidFromMatrikelnummer($student_uid)) { - $response2.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($student_uid)); + $errorMatrnr.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht', array($checkedMatrnr)); continue; } } - $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); if(isset($_POST['student_uid_'.$id]) && (isset($_POST['note_'.$id]) || isset($_POST['punkte_'.$id])) && isset($_POST['datumNachp_'.$id])) { $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte); - - echo "\ndb " . " lvid ". $lvid . " note " . $note . " student_uid " . $student_uid . " datum " . $datum . " studiensem " . - $stsem . " lehreinheit_id_pr " . $lehreinheit_id . " typ " . $typ . " response" . $response . "\n"; - echo $response2; - } else { @@ -150,22 +151,18 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) } } } - + echo $errorMatrnr . $errorDatum; } else { // Einzelupdate - if(isset($_GET['datum']) ) + if(isset($_GET['datum'])) { $datum = $_GET['datum']; $datum_obj = new datum(); - $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) OR die('Invalid date format'); + $datum = $datum_obj->checkformatDatum($datum, 'Y-m-d', true) or die($p->t('benotungstool/datumsformatUnzulaessig', array($checkedDatum))); } - - else - die('Fehlerhafte Parameteruebergabe'); - $student_uid = $_REQUEST["student_uid"]; $note = $_REQUEST["note"]; @@ -174,7 +171,7 @@ else else $punkte = ''; - $punkte = str_replace(',','.',$punkte); + $punkte = str_replace(',', '.', $punkte); if($punkte!='') { @@ -205,11 +202,10 @@ else $uid = (isset($_GET['uid'])?$_GET['uid']:''); // lvgesamtnote für studenten speichern - if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '') ) + if (isset($_REQUEST["submit"]) && ($_REQUEST["student_uid"] != '')) { // Die Pruefung muss einer Lehreinheit zugeordnet werden // deshalb wird hier versucht eine passende Lehreinheit zu ermitteln. - $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); $response = savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note); @@ -217,7 +213,6 @@ else } else echo "Fehler beim Eintragen der Prüfungen"; - } /** @@ -259,7 +254,7 @@ function getLehreinheit($db, $lvid, $student_uid, $stsem) /** * Prüfung speichern */ -function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte=null) +function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ, $note, $punkte = null) { $jetzt = date("Y-m-d H:i:s"); global $user; //, $note, $punkte, $datum; @@ -370,7 +365,7 @@ function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ $pr_3->punkte = $punkte; $pr_3->datum = $datum; $pr_3->anmerkung = ""; - $response = "Prüfung Termin3 aktualisiert"; + $response = "update T3"; } else { @@ -389,14 +384,14 @@ function savePruefung($lvid, $student_uid, $stsem, $lehreinheit_id, $datum, $typ $pr_3->ext_id = null; $pr_3->new = true; $old_note = -1; - $response = "neue Prüfung Termin3"; + $response = "new T3"; } $pr_3->save(); } } else { - $response = "no existing T3"; + $response = "fehlende oder fehlerhafte Inputparameter"; } //Gesamtnote updaten diff --git a/locale/de-AT/benotungstool.php b/locale/de-AT/benotungstool.php index a38aa31f3..b7c2af638 100644 --- a/locale/de-AT/benotungstool.php +++ b/locale/de-AT/benotungstool.php @@ -148,7 +148,9 @@ $this->phrasen['benotungstool/anzahlKommisionellePruefungen']='Anzahl kommission $this->phrasen['benotungstool/pruefungAnlegenFuer']='Prüfung anlegen für'; $this->phrasen['benotungstool/kreuzerltool']='Kreuzerltool'; $this->phrasen['benotungstool/studentIstLvNichtZugeordnet']='Der Student %s %s (%s) ist dieser Lehrveranstaltung nicht zugeordnet. Die Note wird nicht uebernommen!'; -$this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student mit Matrikelnummer %s existiert nicht.'; +$this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student*in mit Matrikelnummer %s existiert nicht.'; +$this->phrasen['benotungstool/datumsformatUnzulaessig']='Das Datum %s entspricht nicht dem Format TT.MM.JJJJ!'; +$this->phrasen['benotungstool/noteUnzulaessig']='Die Note %s ist nicht zulaessig. Die Zeile wurde uebersprungen.'; $this->phrasen['benotungstool/noteNichtUeberschreibbar']='Für Student mit Matrikelnummer %s eingetragene Zeugnisote %s ist nicht überschreibbar'; $this->phrasen['benotungstool/fehlerhafteNoteBeiStudent']='Fehlerhafte Note bei Student %s %s'; $this->phrasen['benotungstool/keineKreuzerllistenFuerDieseLehrveranstaltung']='Derzeit gibt es keine Kreuzerllisten für diese Lehrveranstaltung'; diff --git a/locale/en-US/benotungstool.php b/locale/en-US/benotungstool.php index 72f29256e..1f1dc89c6 100644 --- a/locale/en-US/benotungstool.php +++ b/locale/en-US/benotungstool.php @@ -148,6 +148,7 @@ $this->phrasen['benotungstool/pruefungAnlegenFuer']='Create an examination for ' $this->phrasen['benotungstool/kreuzerltool']='"Kreuzerl" tool'; $this->phrasen['benotungstool/studentIstLvNichtZugeordnet']='Student is not assigned to this course. The grade was not accepted!'; $this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student with student ID number %s does not exist.'; +$this->phrasen['benotungstool/datumsformatUnzulaessig']='The date %s is not in valid format TT.MM.JJJJ.'; $this->phrasen['benotungstool/noteNichtUeberschreibbar']='Transcript grade %2$s for student with Personal identifier %1$s is not rewritable'; $this->phrasen['benotungstool/fehlerhafteNoteBeiStudent']='Incorrect grade for student %s %s'; $this->phrasen['benotungstool/keineKreuzerllistenFuerDieseLehrveranstaltung']='There are currently no checklists for this course'; From 8754c46575f53bccffdcb1ec2dd6d51923fd0b48 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 17 Oct 2022 14:34:11 +0200 Subject: [PATCH 018/439] Refactor Import Termin2 und Termin3 --- .../benotungstool/lvgesamtnoteverwalten.php | 27 ++++--------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index 8a428ff2a..b7bb74d54 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -606,7 +606,7 @@ foreach ($noten_obj->result as $row) // **** // * Oeffnet ein Fenster fuer den Import von Noten für die Nachprüfung aus dem Excel // **** - function GradeImportNachp() + function GradeImportNachp(termin) { var str = "
"; str += ""; @@ -614,31 +614,14 @@ foreach ($noten_obj->result as $row) var y = getOffset('y'); y = y+50; anlegendiv.style.top = y+"px"; str += ''; str += ''; - str += "
X
t('benotungstool/importAnweisungNachp');?>:
' onclick='saveGradeBulkNachp(\"Termin2\");'>"; + + str += "
' onclick='saveGradeBulkNachp(\""+ termin +"\");'>"; str += "
"; anlegendiv.innerHTML = str; anlegendiv.style.visibility = "visible"; $('#noteimporttextareaNachp').focus(); } - // **** - // * Oeffnet ein Fenster fuer den Import von Noten für Termin3 aus dem Excel - // **** - function GradeImportTermin3() - { - var str = "
"; - str += ""; - var anlegendiv = document.getElementById("nachpruefung_div"); - var y = getOffset('y'); y = y+50; anlegendiv.style.top = y+"px"; - str += ''; - str += ''; - str += "
X
t('benotungstool/importAnweisungNachp');?>:
' onclick='saveGradeBulkNachp(\"Termin3\");'>"; - str += "
"; - anlegendiv.innerHTML = str; - anlegendiv.style.visibility = "visible"; - $('#noteimporttextareaTermin3').focus(); - } - // Speichert die Noten ueber den Import function saveGradeBulk() { @@ -1188,13 +1171,13 @@ $htmlstring .= "" . $p->t('benotungstool/punkte') . ' / ' . $p->t('benotungs if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) { $htmlstring .= "
" . $p->t('benotungstool/nachpruefung') . "
- + "; } if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) { $htmlstring .= "
" . $p->t('benotungstool/nachpruefung2') . "
- + "; } if (defined('CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF') && CIS_GESAMTNOTE_PRUEFUNG_KOMMPRUEF) From 47d3ab33e78d0fbb68f5e484494a518c7e35033c Mon Sep 17 00:00:00 2001 From: ma0068 Date: Tue, 18 Oct 2022 09:17:07 +0200 Subject: [PATCH 019/439] =?UTF-8?q?Adaptierung=20Vorlage=20Notenliste.xls?= =?UTF-8?q?=20um=20Nachpr=C3=BCfung=20und=20Termin3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../benotungstool/lvgesamtnoteeintragen.php | 21 +++--- .../benotungstool/lvgesamtnoteverwalten.php | 4 +- .../benotungstool/nachpruefungeintragen.php | 1 + cis/private/lehre/notenliste.xls.php | 67 +++++++++++++++++++ locale/de-AT/benotungstool.php | 4 +- locale/en-US/benotungstool.php | 2 +- 6 files changed, 84 insertions(+), 15 deletions(-) diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteeintragen.php b/cis/private/lehre/benotungstool/lvgesamtnoteeintragen.php index 73d0e6fca..8337b7c36 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteeintragen.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteeintragen.php @@ -98,9 +98,9 @@ if($stsem=='') //$note = $_REQUEST["note"]; -if(!$rechte->isBerechtigt('admin',0) && - !$rechte->isBerechtigt('admin',$lv_obj->studiengang_kz) && - !$rechte->isBerechtigt('lehre',$lv_obj->studiengang_kz)) +if(!$rechte->isBerechtigt('admin', 0) && + !$rechte->isBerechtigt('admin', $lv_obj->studiengang_kz) && + !$rechte->isBerechtigt('lehre', $lv_obj->studiengang_kz)) { $qry = "SELECT lehreinheit_id FROM lehre.tbl_lehrveranstaltung JOIN lehre.tbl_lehreinheit USING(lehrveranstaltung_id) JOIN lehre.tbl_lehreinheitmitarbeiter USING(lehreinheit_id) @@ -117,11 +117,11 @@ if(!$rechte->isBerechtigt('admin',0) && } } -function savenote($db,$lvid, $student_uid, $note, $punkte=null) +function savenote($db, $lvid, $student_uid, $note, $punkte = null) { global $stsem, $user, $p, $noten_anmerkung; $jetzt = date("Y-m-d H:i:s"); - $punkte = str_replace(',','.',$punkte); + $punkte = str_replace(',', '.', $punkte); //Ermitteln ob der Student diesem Kurs zugeteilt ist $qry = "SELECT 1 FROM campus.vw_student_lehrveranstaltung WHERE uid=".$db->db_add_param($student_uid)." AND lehrveranstaltung_id=".$db->db_add_param($lvid, FHC_INTEGER); if($result = $db->db_query($qry)) @@ -207,13 +207,12 @@ if (isset($_REQUEST["submit"])) $note = $_REQUEST["note"]; $punkte = (isset($_REQUEST["punkte"])?$_REQUEST["punkte"]:''); - $response = savenote($db,$lvid, $student_uid, $note, $punkte); + $response = savenote($db, $lvid, $student_uid, $note, $punkte); echo $response; } else { - - foreach ($_POST as $row=>$val) + foreach ($_POST as $row => $val) { if(mb_strstr(mb_strtolower($row), 'matrikelnr_')) { @@ -232,7 +231,7 @@ if (isset($_REQUEST["submit"])) $response.="\nNote oder Punkte fehlen"; continue; } - $punkte=str_replace(',','.', $punkte); + $punkte=str_replace(',', '.', $punkte); //check ob statt Matrikelnummer nicht bereits student_uid (Moodle Grade Import) vorliegt.. $student = new student(); @@ -241,7 +240,7 @@ if (isset($_REQUEST["submit"])) //UID ermitteln if(!$student_uid = $student->getUidFromMatrikelnummer($matrikelnummer)) { - $response.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht',array($matrikelnummer)); + $response.="\n".$p->t('benotungstool/studentMitMatrikelnummerExistiertNicht', array($matrikelnummer)); continue; } } @@ -268,7 +267,7 @@ if (isset($_REQUEST["submit"])) } } - $val=savenote($db,$lvid, $student_uid, $note, $punkte); + $val=savenote($db, $lvid, $student_uid, $note, $punkte); if($val!='neu' && $val!='update' && $val!='update_f') $response.=$val; } diff --git a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php index b7bb74d54..64179a3e9 100644 --- a/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php +++ b/cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php @@ -749,6 +749,7 @@ foreach ($noten_obj->result as $row) } ?> + for(row in rows) { zeile = rows[row].split(" "); @@ -779,6 +780,7 @@ foreach ($noten_obj->result as $row) } } + if (alertMsg != "") alert(alertMsg); @@ -1306,7 +1308,7 @@ if (defined("CIS_GESAMTNOTE_PRUEFUNG_MOODLE_LE_NOTE") && CIS_GESAMTNOTE_PRUEFUNG foreach ($addon_obj->result as $row) { if (file_exists('../../../../addons/' . $row->kurzbz . '/cis/grades.inc.php')) - include ('../../../../addons/' . $row->kurzbz . '/cis/grades.inc.php'); + include('../../../../addons/' . $row->kurzbz . '/cis/grades.inc.php'); } } } diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index 307c0ca30..290113179 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -105,6 +105,7 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) $note = null; $punkte = null; $datum = null; + $response = ''; if(isset($_POST['note_'.$id])) $note = $_POST['note_'.$id]; elseif(isset($_POST['punkte_'.$id])) diff --git a/cis/private/lehre/notenliste.xls.php b/cis/private/lehre/notenliste.xls.php index 74cb7e7c1..4a6817a36 100644 --- a/cis/private/lehre/notenliste.xls.php +++ b/cis/private/lehre/notenliste.xls.php @@ -35,6 +35,7 @@ require_once('../../../include/note.class.php'); require_once('../../../include/notenschluessel.class.php'); require_once('../../../include/Excel/excel.php'); require_once('../../../include/phrasen.class.php'); +require_once('../../../include/pruefung.class.php'); $uid = get_uid(); @@ -191,6 +192,19 @@ else } //Studenten holen + + //Spaltengruppe für Nachprüfung + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) + { + $worksheet->write($lines,8,$p->t('benotungstool/nachpruefung'),$format_bold); + } + + //Spaltengruppe für 2.Nebensprüfungstermin + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) + { + $worksheet->write($lines,12,$p->t('benotungstool/nachpruefung2'),$format_bold); + } + $lines++; $worksheet->write($lines,1,$p->t('global/uid'),$format_border_bottom); $worksheet->write($lines,2,$p->t('global/nachname'),$format_border_bottom); @@ -203,6 +217,26 @@ else else $worksheet->write($lines,6,$p->t('benotungstool/note'),$format_border_bottom); + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) + { + $worksheet->write($lines,8,$p->t('global/uid'),$format_border_bottom); + $worksheet->write($lines,9,$p->t('global/datum'),$format_border_bottom); + if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) + $worksheet->write($lines,10,$p->t('benotungstool/punkte'),$format_border_bottom); + else + $worksheet->write($lines,10,$p->t('benotungstool/note'),$format_border_bottom); + } + + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) +{ + $worksheet->write($lines,12,$p->t('global/uid'),$format_border_bottom); + $worksheet->write($lines,13,$p->t('global/uid'),$format_border_bottom); + if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE) + $worksheet->write($lines,14,$p->t('benotungstool/punkte'),$format_border_bottom); + else + $worksheet->write($lines,14,$p->t('benotungstool/note'),$format_border_bottom); +} + $stsem_obj = new studiensemester(); $stsem_obj->load($stsem); $stsemdatumvon = $stsem_obj->start; @@ -282,6 +316,39 @@ else $worksheet->write($lines,4,'="'.$elem->semester.$elem->verband.$elem->gruppe.'"'); $worksheet->write($lines,5,'="'.trim($elem->matrikelnr).'"',$format_highlight); $worksheet->write($lines,6, $note, $format_highlightright); + + // Nachprüfung + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN2') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN2) + { + $worksheet->write($lines,8, $elem->uid, $format_highlightright); + $pr = new Pruefung(); + $pr->getPruefungen($elem->uid, "Termin2", $lvid, $sem); + $output2 = $pr->result; + + if ($output2) + { + $resultPr = $output2[0]; + $worksheet->write($lines,9, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright); + $worksheet->write($lines,10, $resultPr->note, $format_highlightright); + } + } + + // Nachprüfung + if (defined('CIS_GESAMTNOTE_PRUEFUNG_TERMIN3') && CIS_GESAMTNOTE_PRUEFUNG_TERMIN3) + { + $worksheet->write($lines,12, $elem->uid, $format_highlightright); + $pr = new Pruefung(); + $pr->getPruefungen($elem->uid, "Termin3", $lvid, $sem); + $output3 = $pr->result; + + if ($output3) + { + $resultPr = $output3[0]; + $worksheet->write($lines,13, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright); + $worksheet->write($lines,14, $resultPr->note, $format_highlightright); + } + } + $i++; $lines++; } diff --git a/locale/de-AT/benotungstool.php b/locale/de-AT/benotungstool.php index b7c2af638..feac092f6 100644 --- a/locale/de-AT/benotungstool.php +++ b/locale/de-AT/benotungstool.php @@ -172,8 +172,8 @@ $this->phrasen['benotungstool/eingetrageneNoten']='Eingetragene Noten'; $this->phrasen['benotungstool/zeunis']='Zeugnis'; $this->phrasen['benotungstool/handbuch']='Handbuch'; $this->phrasen['benotungstool/punkte']='Punkte'; -$this->phrasen['benotungstool/importAnweisung']='Kopieren Sie die Spalten Personenkennzeichen und Note aus der Notenliste (bzw. StudentenUid und Note aus dem MoodleExport) und fügen Sie diese in folgendes Feld ein'; -$this->phrasen['benotungstool/importAnweisungNachp']='Kopieren Sie die Spalten Personenkennzeichen, Datum und Note aus der Notenliste (bzw. StudentenUid, Datum und Note aus dem MoodleExport) und fügen Sie diese in folgendes Feld ein'; +$this->phrasen['benotungstool/importAnweisung']='Kopieren Sie die Spalten StudentenUid und Note aus der Notenliste (bzw. StudentenUid und Note aus dem MoodleExport) und fügen Sie diese in folgendes Feld ein'; +$this->phrasen['benotungstool/importAnweisungNachp']='Kopieren Sie die Spalten StudentenUid (bzw. Personenkennzeichen), Datum und Note aus der Notenliste bzw. dem Moodle Export File und fügen Sie diese in folgendes Feld ein'; $this->phrasen['benotungstool/pruefung']='Prüfung'; $this->phrasen['benotungstool/notenlisteImport']='Notenliste für den LV-Noten-Import (Excel)'; $this->phrasen['benotungstool/bearbeitetvon']='Bearbeitet von'; diff --git a/locale/en-US/benotungstool.php b/locale/en-US/benotungstool.php index 1f1dc89c6..f482409d8 100644 --- a/locale/en-US/benotungstool.php +++ b/locale/en-US/benotungstool.php @@ -171,7 +171,7 @@ $this->phrasen['benotungstool/zeunis']='Transcript'; $this->phrasen['benotungstool/handbuch']='Handbook'; $this->phrasen['benotungstool/punkte']='Points'; $this->phrasen['benotungstool/importAnweisung']='Copy the columns "personal identifier" and "grade" from the grade list (or "student ID number" and "grade" from the moodle export file) and insert them in the following field'; -$this->phrasen['benotungstool/importAnweisungNachp']='Copy the columns "personal identifier", "date" and "grade" from the grade list (or "student ID number", "date" and "grade" from the moodle export file) and insert them in the following field'; +$this->phrasen['benotungstool/importAnweisungNachp']='Copy the columns "student ID number" (or "personal identifier"), "date" and "grade" from the grade list or from the moodle export file and insert them in the following field'; $this->phrasen['benotungstool/pruefung']='Examination'; $this->phrasen['benotungstool/notenlisteImport']='Grade list for the subject grade import (Excel)'; $this->phrasen['benotungstool/geaenderteNotenVorhanden']='There are changed grades. Please send the changes to the assistant by clicking "Approval"'; From aadd6b0d926f12621e04c48ac458a5878ce63912 Mon Sep 17 00:00:00 2001 From: Manfred Date: Tue, 18 Oct 2022 16:48:27 +0200 Subject: [PATCH 020/439] =?UTF-8?q?Anzahl=20Rechte=20z=C3=A4hlen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vilesci/stammdaten/benutzerberechtigung_details.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/vilesci/stammdaten/benutzerberechtigung_details.php b/vilesci/stammdaten/benutzerberechtigung_details.php index e3149cf66..4f43a915c 100644 --- a/vilesci/stammdaten/benutzerberechtigung_details.php +++ b/vilesci/stammdaten/benutzerberechtigung_details.php @@ -499,6 +499,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $rechte_funktion = new benutzerberechtigung(); $rechte_funktion->loadBenutzerRollen(null, $recht); $funktionsrecht = $rechte_funktion->berechtigungen; // Hat die Funktion ein Recht? + $anzahlFunktionsrechte = count($funktionsrecht); $funktion_bezeichnung = new funktion(); $funktion_bezeichnung->load($recht); if(!empty($funktionsrecht)) @@ -515,6 +516,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $htmlstr .= ""; $htmlstr .= $funktion_bezeichnung->beschreibung; + $htmlstr .= " (".$anzahlFunktionsrechte.")"; } } if(isset($funktionsrecht)) From 5e9b5b2ce51cac12bf26d7a8669fa6fa6abc7399 Mon Sep 17 00:00:00 2001 From: Manfred Date: Mon, 24 Oct 2022 14:27:34 +0200 Subject: [PATCH 021/439] Direktlink auf Rolle --- .../stammdaten/benutzerberechtigung_details.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/vilesci/stammdaten/benutzerberechtigung_details.php b/vilesci/stammdaten/benutzerberechtigung_details.php index 4f43a915c..c8dff5491 100644 --- a/vilesci/stammdaten/benutzerberechtigung_details.php +++ b/vilesci/stammdaten/benutzerberechtigung_details.php @@ -592,7 +592,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) //Art $htmlstr .= " "; - $htmlstr .= " "; + $htmlstr .= " "; $htmlstr .= " "; //Organisationseinheit @@ -727,7 +727,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $htmlstr .= " "; //Rolle - $htmlstr .= " "; + $htmlstr .= " "; $htmlstr .= " "; + if ($b->rolle_kurzbz != '') + { + $htmlstr .= " "; + } $htmlstr.=""; //Berechtigung @@ -756,7 +760,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) //Art $htmlstr .= " "; $htmlstr .= " ".$b->art.""; - $htmlstr .= " "; + $htmlstr .= " "; $htmlstr .= " "; //Organisationseinheit @@ -930,10 +934,10 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) changeMonth: true, changeYear: true, dateFormat: 'yy-mm-dd', - showOn: "button", - buttonImage: "../../skin/images/date_edit.png", + showOn: "focus" + /*buttonImage: "../../skin/images/date_edit.png", buttonImageOnly: true, - buttonText: "Select date" + buttonText: "Select date"*/ }); $("#t1").tablesorter( From 73dd6e6dc1a202c70e61448c55ef0efa19a54405 Mon Sep 17 00:00:00 2001 From: Manfred Date: Mon, 24 Oct 2022 14:27:54 +0200 Subject: [PATCH 022/439] Autocomplete in Berechtigungrolle --- vilesci/stammdaten/berechtigungrolle.php | 122 +++++++++++++++++------ 1 file changed, 93 insertions(+), 29 deletions(-) diff --git a/vilesci/stammdaten/berechtigungrolle.php b/vilesci/stammdaten/berechtigungrolle.php index ecd7920e7..71df53d14 100644 --- a/vilesci/stammdaten/berechtigungrolle.php +++ b/vilesci/stammdaten/berechtigungrolle.php @@ -41,27 +41,59 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); Berechtigungen Uebersicht - - - + + -

Berechtigung - Rolle - Übersicht

+

Berechtigung - Rolle -

deleteRolleBerechtigung($rolle_kurzbz, $berechtigung_kurzbz)): ?> Fehler beim Löschen: errormsg ?> - Berechtigung gelöscht! + Berechtigung gelöscht! -
- Zurück + Zurück zur Rollenübersicht -

RolleBerechtigung "":

- +

getBerechtigungen(); ?>
+ - - - + + + +
@@ -154,6 +216,8 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); getRolleBerechtigung($rolle_kurzbz); foreach($berechtigungen->result as $rolle): ?> @@ -161,7 +225,7 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); From c7f477555c4e1aada684fde19b6068fbadd1daf7 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Thu, 27 Oct 2022 15:17:29 +0200 Subject: [PATCH 023/439] Adaptierungen DB und Dropdowns Fas Lehrveranstaltungen --- .../lehrveranstaltungdetailoverlay.xul.php | 50 +++++++++++++------ include/raumtyp.class.php | 8 ++- rdf/raumtyp.rdf.php | 3 +- system/dbupdate_3.3.php | 16 +++++- 4 files changed, 58 insertions(+), 19 deletions(-) diff --git a/content/lvplanung/lehrveranstaltungdetailoverlay.xul.php b/content/lvplanung/lehrveranstaltungdetailoverlay.xul.php index e18407e72..ed13e1e63 100644 --- a/content/lvplanung/lehrveranstaltungdetailoverlay.xul.php +++ b/content/lvplanung/lehrveranstaltungdetailoverlay.xul.php @@ -199,26 +199,46 @@ $p = new phrasen($sprache); - '; + '; if ($stsem_zahlung != FALSE && $stsem == $stsem_zahlung) { $path = "../pdfExport.php?xsl=Inskription&xml=student.rdf.php&ss=".$stsem."&uid=".$uid."&xsl_stg_kz=".$xsl_stg_kz; - echo ''; - echo ''; + echo ''; + echo ''; + + $patheng = "../pdfExport.php?xsl=InskriptionEng&xml=student.rdf.php&ss=".$stsem."&uid=".$uid."&xsl_stg_kz=".$xsl_stg_kz; + echo ''; + echo ''; } else { - echo ''; + echo ''; } - echo '
art ?> beschreibung ?> - + entfernen '.$p->t('global/name').'
'.$p->t('tools/inskriptionsbestaetigung').' '.$stsem.'
'.$p->t('tools/inskriptionsbestaetigung').' '.$stsem.' ' . $p->t('global/deutsch'). '
'.$p->t('tools/inskriptionsbestaetigung').' '.$stsem.' ' . $p->t('global/englisch'). '
'.$p->t('tools/studienbeitragFuerSSNochNichtBezahlt',array($stsem)).'
'.$p->t('tools/studienbeitragFuerSSNochNichtBezahlt',array($stsem)).'
'; + echo ''; if (defined('CIS_DOKUMENTE_STUDIENBUCHLBATT_DRUCKEN') && CIS_DOKUMENTE_STUDIENBUCHLBATT_DRUCKEN) { diff --git a/content/fas.xul.php b/content/fas.xul.php index 449f917b7..80efdb2f9 100644 --- a/content/fas.xul.php +++ b/content/fas.xul.php @@ -125,7 +125,8 @@ foreach($addon_obj->result as $addon) - + + @@ -513,6 +514,12 @@ foreach($addon_obj->result as $addon) label = "&menu-dokumente-inskriptionsbestaetigung.label;" command = "menu-dokumente-inskriptionsbestaetigung:command" accesskey = "&menu-dokumente-inskriptionsbestaetigung.accesskey;"/> + 0) - window.open('content/pdfExport.php?xml=student.rdf.php&xsl=Inskription&stg_kz='+stg_kz+'&uid='+paramList+'&ss='+stsem+'&output='+output,'Inskriptionsbestaetigung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes'); + window.open('content/pdfExport.php?xml=student.rdf.php&xsl='+ xsl +'&stg_kz='+stg_kz+'&uid='+paramList+'&ss='+stsem+'&output='+output,'Inskriptionsbestaetigung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes'); else alert('Bitte einen Studenten auswaehlen'); } diff --git a/locale/de-AT/fas.dtd b/locale/de-AT/fas.dtd index df6180904..c3d420ede 100644 --- a/locale/de-AT/fas.dtd +++ b/locale/de-AT/fas.dtd @@ -187,6 +187,10 @@ + + + + diff --git a/rdf/student.rdf.php b/rdf/student.rdf.php index af0bbe82d..6eb9a967e 100644 --- a/rdf/student.rdf.php +++ b/rdf/student.rdf.php @@ -1218,6 +1218,7 @@ else bezeichnung.']]> bezeichnung.']]> + english.']]> typ.']]> orgform_kurzbz.']]> diff --git a/system/vorlage_zip/Inskription.odt b/system/vorlage_zip/Inskription.odt index d1933cdcb62b745b19287a5a29eacfe5a786f433..6471c5cc2bd6b81776a4e9172079222313ede67e 100644 GIT binary patch literal 12858 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

QPA)-><$EXMi5Q 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 diff --git a/system/vorlage_zip/InskriptionEng.odt b/system/vorlage_zip/InskriptionEng.odt new file mode 100644 index 0000000000000000000000000000000000000000..e26be218e03bf872113f94ac7236f90f0dd11dcb GIT binary patch literal 13220 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 literal 0 HcmV?d00001 diff --git a/system/xsl/inskriptioneng_0.xml b/system/xsl/inskriptioneng_0.xml new file mode 100644 index 000000000..c2080a5ec --- /dev/null +++ b/system/xsl/inskriptioneng_0.xml @@ -0,0 +1,347 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + + + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + + + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + + + --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + + + + + + Certificate of Enrolment University of Applied Sciences Demo + + + + + + To be submitted to (place where the certificate is to be submitted and its reference number, e.g. social security number). + + + Student number + + + + + + + + + + + + + + + + + + born on , is enrolled as a regular student in + (beginning ) + in the + + + Bachelor Degree program + + + Master Degree program + + + Degree Program + + + + + + + + + + + + (), + + st + nd + rd + th + + semester (beginning , ). + + + + + + + + Date: + + + Rector: + + + + + \ No newline at end of file From 9c0d70fe890d234aa2b44086fcfec4be0074a714 Mon Sep 17 00:00:00 2001 From: Paolo Date: Tue, 8 Nov 2022 12:01:05 +0100 Subject: [PATCH 025/439] Removed version 4 of tinymce --- composer.json | 12 -- composer.lock | 424 +++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 386 insertions(+), 50 deletions(-) diff --git a/composer.json b/composer.json index 825ed5625..46f4edc39 100644 --- a/composer.json +++ b/composer.json @@ -270,17 +270,6 @@ } } }, - { - "type": "package", - "package": { - "name": "tinymce/tinymce4", - "version": "4.9.11", - "dist": { - "url": "https://github.com/tinymce/tinymce-dist/archive/refs/tags/4.9.11.zip", - "type": "zip" - } - } - }, { "type": "package", "package": { @@ -413,7 +402,6 @@ "scottjehl/respond": "1.4.2", "tapmodo/jcrop": "2.0.4", - "tinymce/tinymce4": "4.9.*", "tinymce/tinymce5": "5.10.*", "tomazdragar/simplecropper": "1.0", "twbs/bootstrap3": "3.4.*", diff --git a/composer.lock b/composer.lock index 72f13c76f..ce909eccc 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d530cc4d7bd81812535eb64e87ba04f4", + "content-hash": "269157583af475d4c8cd307400c7b248", "packages": [ { "name": "afarkas/html5shiv", @@ -35,6 +35,10 @@ ], "description": "Defacto way to enable use of HTML5 sectioning elements in legacy Internet Explorer.", "homepage": "http://paulirish.com/2011/the-history-of-the-html5-shiv/", + "support": { + "issues": "https://github.com/aFarkas/html5shiv/issues", + "source": "https://github.com/aFarkas/html5shiv/tree/3.7.3" + }, "time": "2015-07-20T20:04:00+00:00" }, { @@ -130,6 +134,16 @@ "keywords": [ "qr code" ], + "support": { + "issues": "https://github.com/chillerlan/php-qrcode/issues", + "source": "https://github.com/chillerlan/php-qrcode/tree/v2.0.x" + }, + "funding": [ + { + "url": "https://ko-fi.com/codemasher", + "type": "ko_fi" + } + ], "time": "2020-04-12T07:38:35+00:00" }, { @@ -178,6 +192,10 @@ "helper", "trait" ], + "support": { + "issues": "https://github.com/chillerlan/php-traits/issues", + "source": "https://github.com/chillerlan/php-traits" + }, "abandoned": true, "time": "2018-06-22T00:30:47+00:00" }, @@ -218,6 +236,10 @@ ], "description": "REST Server for the CodeIgniter framework", "homepage": "https://github.com/chriskacerguis/codeigniter-restserver", + "support": { + "issues": "https://github.com/chriskacerguis/codeigniter-restserver/issues", + "source": "https://github.com/chriskacerguis/codeigniter-restserver" + }, "time": "2017-09-23T16:44:55+00:00" }, { @@ -236,6 +258,10 @@ }, "type": "library", "notification-url": "https://packagist.org/downloads/", + "support": { + "issues": "https://github.com/akiyatkin/tablesorter/issues", + "source": "https://github.com/akiyatkin/tablesorter/tree/master" + }, "time": "2016-09-02T11:31:54+00:00" }, { @@ -269,6 +295,13 @@ ], "description": "The CodeIgniter framework", "homepage": "https://codeigniter.com", + "support": { + "forum": "http://forum.codeigniter.com/", + "issues": "https://github.com/bcit-ci/CodeIgniter/issues", + "slack": "https://codeigniterchat.slack.com", + "source": "https://github.com/bcit-ci/CodeIgniter", + "wiki": "https://github.com/bcit-ci/CodeIgniter/wiki" + }, "time": "2022-03-03T13:21:49+00:00" }, { @@ -573,6 +606,10 @@ ], "description": "Shim repository for Angular.js", "homepage": "http://angularjs.org", + "support": { + "issues": "https://github.com/components/angular.js/issues", + "source": "https://github.com/components/angular.js/tree/master" + }, "time": "2015-06-07T20:10:38+00:00" }, { @@ -615,6 +652,13 @@ ], "description": "jQuery JavaScript Library", "homepage": "http://jquery.com", + "support": { + "forum": "http://forum.jquery.com", + "irc": "irc://irc.freenode.org/jquery", + "issues": "https://github.com/jquery/jquery/issues", + "source": "https://github.com/jquery/jquery", + "wiki": "http://docs.jquery.com/" + }, "time": "2021-03-20T19:13:42+00:00" }, { @@ -700,6 +744,10 @@ } ], "description": "jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library. Whether you're building highly interactive web applications or you just need to add a date picker to a form control, jQuery UI is the perfect choice.", + "support": { + "issues": "https://github.com/components/jqueryui/issues", + "source": "https://github.com/components/jqueryui/tree/master" + }, "time": "2016-09-16T05:47:55+00:00" }, { @@ -749,6 +797,10 @@ "captcha", "security" ], + "support": { + "issues": "https://github.com/dapphp/securimage/issues", + "source": "https://github.com/dapphp/securimage/tree/master" + }, "abandoned": true, "time": "2018-03-09T06:07:41+00:00" }, @@ -812,6 +864,12 @@ "rdfa", "sparql" ], + "support": { + "forum": "http://groups.google.com/group/easyrdf/", + "irc": "irc://chat.freenode.net/easyrdf", + "issues": "http://github.com/njh/easyrdf/issues", + "source": "https://github.com/easyrdf/easyrdf/tree/0.9.1" + }, "time": "2015-02-27T09:45:49+00:00" }, { @@ -890,6 +948,10 @@ "faker", "fixtures" ], + "support": { + "issues": "https://github.com/fzaninotto/Faker/issues", + "source": "https://github.com/fzaninotto/Faker/tree/v1.9.2" + }, "abandoned": true, "time": "2020-12-11T09:56:16+00:00" }, @@ -1012,6 +1074,10 @@ "json", "schema" ], + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/master" + }, "time": "2014-08-25T02:48:14+00:00" }, { @@ -1046,6 +1112,10 @@ } ], "description": "A framework-agnostic PHP Implementation for generating simple forms based on json-schema", + "support": { + "issues": "https://github.com/kingsquare/json-schema-form/issues", + "source": "https://github.com/kingsquare/json-schema-form/tree/master" + }, "time": "2014-07-10T12:27:19+00:00" }, { @@ -1106,6 +1176,10 @@ "keywords": [ "markdown" ], + "support": { + "issues": "https://github.com/michelf/php-markdown/issues", + "source": "https://github.com/michelf/php-markdown/tree/lib" + }, "time": "2015-03-01T12:03:08+00:00" }, { @@ -1153,20 +1227,24 @@ "uri", "url" ], + "support": { + "issues": "https://github.com/lanthaler/IRI/issues", + "source": "https://github.com/lanthaler/IRI/tree/master" + }, "time": "2014-01-21T13:43:39+00:00" }, { "name": "ml/json-ld", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/lanthaler/JsonLD.git", - "reference": "c74a1aed5979ed1cfb1be35a55a305fd30e30b93" + "reference": "537e68e87a6bce23e57c575cd5dcac1f67ce25d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/c74a1aed5979ed1cfb1be35a55a305fd30e30b93", - "reference": "c74a1aed5979ed1cfb1be35a55a305fd30e30b93", + "url": "https://api.github.com/repos/lanthaler/JsonLD/zipball/537e68e87a6bce23e57c575cd5dcac1f67ce25d8", + "reference": "537e68e87a6bce23e57c575cd5dcac1f67ce25d8", "shasum": "" }, "require": { @@ -1202,7 +1280,11 @@ "JSON-LD", "jsonld" ], - "time": "2020-06-16T17:45:06+00:00" + "support": { + "issues": "https://github.com/lanthaler/JsonLD/issues", + "source": "https://github.com/lanthaler/JsonLD/tree/1.2.1" + }, + "time": "2022-09-29T08:45:17+00:00" }, { "name": "moment/momentjs", @@ -1262,6 +1344,14 @@ "sorting", "table" ], + "support": { + "docs": "https://mottie.github.io/tablesorter/docs/index.html", + "email": "wowmotty@gmail.com", + "irc": "irc://irc.freenode.org/tablesorter", + "issues": "https://github.com/Mottie/tablesorter/issues", + "source": "https://github.com/Mottie/tablesorter", + "wiki": "https://github.com/Mottie/tablesorter/wiki" + }, "time": "2020-03-03T13:46:03+00:00" }, { @@ -1312,6 +1402,10 @@ "rest", "restful" ], + "support": { + "issues": "https://github.com/nategood/httpful/issues", + "source": "https://github.com/nategood/httpful/tree/v0.2.20" + }, "time": "2015-10-26T16:11:30+00:00" }, { @@ -1365,6 +1459,12 @@ "plaintext", "textile" ], + "support": { + "irc": "irc://irc.freenode.net/textile", + "issues": "https://github.com/textile/php-textile/issues", + "source": "https://github.com/textile/php-textile", + "wiki": "https://github.com/textile/php-textile/wiki" + }, "time": "2022-05-01T17:05:16+00:00" }, { @@ -1420,16 +1520,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "2.0.37", + "version": "2.0.39", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "c812fbb4d6b4d7f30235ab7298a12f09ba13b37c" + "reference": "f3a0e2b715c40cf1fd270d444901b63311725d63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c812fbb4d6b4d7f30235ab7298a12f09ba13b37c", - "reference": "c812fbb4d6b4d7f30235ab7298a12f09ba13b37c", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/f3a0e2b715c40cf1fd270d444901b63311725d63", + "reference": "f3a0e2b715c40cf1fd270d444901b63311725d63", "shasum": "" }, "require": { @@ -1444,7 +1544,8 @@ "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", - "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations.", + "ext-xml": "Install the XML extension to load XML formatted public keys." }, "type": "library", "autoload": { @@ -1507,7 +1608,25 @@ "x.509", "x509" ], - "time": "2022-04-04T04:57:45+00:00" + "support": { + "issues": "https://github.com/phpseclib/phpseclib/issues", + "source": "https://github.com/phpseclib/phpseclib/tree/2.0.39" + }, + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], + "time": "2022-10-24T10:49:03+00:00" }, { "name": "rmariuzzo/jquery-checkboxes", @@ -1587,6 +1706,23 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-23T09:01:57+00:00" }, { @@ -1598,15 +1734,6 @@ }, "type": "library" }, - { - "name": "tinymce/tinymce4", - "version": "4.9.11", - "dist": { - "type": "zip", - "url": "https://github.com/tinymce/tinymce-dist/archive/refs/tags/4.9.11.zip" - }, - "type": "library" - }, { "name": "tinymce/tinymce5", "version": "5.10.3", @@ -1706,6 +1833,10 @@ "keywords": [ "templating" ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/1.x" + }, "time": "2020-02-11T05:59:23+00:00" }, { @@ -1779,6 +1910,24 @@ "regex", "regular expression" ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/1.0.1" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], "time": "2022-01-21T20:24:37+00:00" }, { @@ -1826,20 +1975,39 @@ "Xdebug", "performance" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/2.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], "time": "2022-02-24T20:20:32+00:00" }, { "name": "nikic/php-parser", - "version": "v4.14.0", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", "shasum": "" }, "require": { @@ -1878,20 +2046,24 @@ "parser", "php" ], - "time": "2022-05-31T20:59:12+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + }, + "time": "2022-09-04T07:30:47+00:00" }, { "name": "pdepend/pdepend", - "version": "2.10.3", + "version": "2.12.1", "source": { "type": "git", "url": "https://github.com/pdepend/pdepend.git", - "reference": "da3166a06b4a89915920a42444f707122a1584c9" + "reference": "7a892d56ceafd804b4a2ecc85184640937ce9e84" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pdepend/pdepend/zipball/da3166a06b4a89915920a42444f707122a1584c9", - "reference": "da3166a06b4a89915920a42444f707122a1584c9", + "url": "https://api.github.com/repos/pdepend/pdepend/zipball/7a892d56ceafd804b4a2ecc85184640937ce9e84", + "reference": "7a892d56ceafd804b4a2ecc85184640937ce9e84", "shasum": "" }, "require": { @@ -1925,26 +2097,36 @@ "BSD-3-Clause" ], "description": "Official version of pdepend to be handled with Composer", - "time": "2022-02-23T07:53:09+00:00" + "support": { + "issues": "https://github.com/pdepend/pdepend/issues", + "source": "https://github.com/pdepend/pdepend/tree/2.12.1" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/pdepend/pdepend", + "type": "tidelift" + } + ], + "time": "2022-09-08T19:30:37+00:00" }, { "name": "phpmd/phpmd", - "version": "2.12.0", + "version": "2.13.0", "source": { "type": "git", "url": "https://github.com/phpmd/phpmd.git", - "reference": "c0b678ba71902f539c27c14332aa0ddcf14388ec" + "reference": "dad0228156856b3ad959992f9748514fa943f3e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpmd/phpmd/zipball/c0b678ba71902f539c27c14332aa0ddcf14388ec", - "reference": "c0b678ba71902f539c27c14332aa0ddcf14388ec", + "url": "https://api.github.com/repos/phpmd/phpmd/zipball/dad0228156856b3ad959992f9748514fa943f3e3", + "reference": "dad0228156856b3ad959992f9748514fa943f3e3", "shasum": "" }, "require": { "composer/xdebug-handler": "^1.0 || ^2.0 || ^3.0", "ext-xml": "*", - "pdepend/pdepend": "^2.10.3", + "pdepend/pdepend": "^2.12.1", "php": ">=5.3.9" }, "require-dev": { @@ -1997,7 +2179,18 @@ "phpmd", "pmd" ], - "time": "2022-03-24T13:33:01+00:00" + "support": { + "irc": "irc://irc.freenode.org/phpmd", + "issues": "https://github.com/phpmd/phpmd/issues", + "source": "https://github.com/phpmd/phpmd/tree/2.13.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/phpmd/phpmd", + "type": "tidelift" + } + ], + "time": "2022-09-10T08:44:15+00:00" }, { "name": "phpmetrics/phpmetrics", @@ -2061,6 +2254,10 @@ "quality", "testing" ], + "support": { + "issues": "https://github.com/PhpMetrics/PhpMetrics/issues", + "source": "https://github.com/phpmetrics/PhpMetrics/tree/v2.8.1" + }, "time": "2022-03-24T10:19:51+00:00" }, { @@ -2110,6 +2307,10 @@ "keywords": [ "timer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/master" + }, "time": "2017-02-26T11:10:40+00:00" }, { @@ -2159,6 +2360,10 @@ "container-interop", "psr" ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, "time": "2017-02-14T16:28:37+00:00" }, { @@ -2206,6 +2411,9 @@ "psr", "psr-3" ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, "time": "2021-05-03T11:20:27+00:00" }, { @@ -2245,6 +2453,10 @@ ], "description": "FinderFacade is a convenience wrapper for Symfony's Finder component.", "homepage": "https://github.com/sebastianbergmann/finder-facade", + "support": { + "issues": "https://github.com/sebastianbergmann/finder-facade/issues", + "source": "https://github.com/sebastianbergmann/finder-facade/tree/master" + }, "abandoned": true, "time": "2017-11-18T17:31:49+00:00" }, @@ -2296,6 +2508,10 @@ ], "description": "Copy/Paste Detector (CPD) for PHP code.", "homepage": "https://github.com/sebastianbergmann/phpcpd", + "support": { + "issues": "https://github.com/sebastianbergmann/phpcpd/issues", + "source": "https://github.com/sebastianbergmann/phpcpd/tree/master" + }, "time": "2017-11-16T08:49:28+00:00" }, { @@ -2339,6 +2555,10 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/master" + }, "time": "2016-10-03T07:35:21+00:00" }, { @@ -2390,6 +2610,11 @@ "phpcs", "standards" ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, "time": "2021-12-12T21:44:58+00:00" }, { @@ -2449,6 +2674,23 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/config/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-24T10:57:07+00:00" }, { @@ -2516,6 +2758,23 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/console/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-24T10:57:07+00:00" }, { @@ -2567,6 +2826,23 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/debug/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "abandoned": "symfony/error-handler", "time": "2020-10-24T10:57:07+00:00" }, @@ -2634,6 +2910,23 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dependency-injection/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-24T10:57:07+00:00" }, { @@ -2679,6 +2972,23 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-24T10:57:07+00:00" }, { @@ -2723,6 +3033,23 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v3.4.47" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-11-16T17:02:08+00:00" }, { @@ -2786,6 +3113,23 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.19.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], "time": "2020-10-23T09:01:57+00:00" }, { @@ -2829,6 +3173,10 @@ ], "description": "The classes contained within this repository extend the standard DOM to use exceptions at all occasions of errors instead of PHP warnings or notices. They also add various custom methods and shortcuts for convenience and to simplify the usage of DOM.", "homepage": "https://github.com/theseer/fDOMDocument", + "support": { + "issues": "https://github.com/theseer/fDOMDocument/issues", + "source": "https://github.com/theseer/fDOMDocument/tree/1.6.7" + }, "abandoned": true, "time": "2022-01-25T23:10:35+00:00" } @@ -2842,5 +3190,5 @@ "php": ">=5.6.40" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } From ac1df7691a72d95e33b48e33426ffdb3da03870e Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 11 Nov 2022 13:54:25 +0100 Subject: [PATCH 026/439] - Added new view application/views/system/messages/FAShtmlWriteTemplate.php to be used with FAS/SeaMonkey and TinyMCE3 - Replaced TinyMCE V4 with V5 - Dropped TinyMCE V4 - Added new JS public/js/messaging/fasMessageWrite.js to be included by application/views/system/messages/FAShtmlWriteTemplate.php --- .../system/messages/FASMessages.php | 4 +- application/views/person/bpk/bpkDetails.php | 1 - .../system/infocenter/infocenterDetails.php | 2 +- .../infocenter/infocenterZgvDetails.php | 2 +- .../system/messages/FAShtmlWriteTemplate.php | 197 ++++++++++++++++++ .../views/system/messages/ajaxRead.php | 2 +- .../views/system/messages/ajaxWrite.php | 2 +- .../views/system/messages/ajaxWriteReply.php | 2 +- .../views/system/messages/htmlWriteReply.php | 2 +- .../system/messages/htmlWriteTemplate.php | 2 +- .../views/system/vorlage/templatetextEdit.php | 2 +- application/views/templates/FHC-Common.php | 2 +- application/views/templates/FHC-Footer.php | 4 +- application/views/templates/FHC-Header.php | 3 - application/views/templates/header.php | 2 +- application/views/widgets/tinymce.php | 5 +- public/css/{TinyMCE.css => TinyMCE5.css} | 0 public/js/messaging/fasMessageWrite.js | 140 +++++++++++++ public/js/messaging/messageWrite.js | 11 +- public/js/messaging/write.js | 2 +- 20 files changed, 363 insertions(+), 24 deletions(-) create mode 100644 application/views/system/messages/FAShtmlWriteTemplate.php rename public/css/{TinyMCE.css => TinyMCE5.css} (100%) create mode 100644 public/js/messaging/fasMessageWrite.js diff --git a/application/controllers/system/messages/FASMessages.php b/application/controllers/system/messages/FASMessages.php index 55d1da25f..e2169af9b 100644 --- a/application/controllers/system/messages/FASMessages.php +++ b/application/controllers/system/messages/FASMessages.php @@ -37,7 +37,7 @@ class FASMessages extends Auth_Controller // Loads the view to write a new message with a template $this->load->view( - 'system/messages/htmlWriteTemplate', + 'system/messages/FAShtmlWriteTemplate', $this->CLMessagesModel->prepareHtmlWriteTemplatePrestudents($prestudents) ); } @@ -53,7 +53,7 @@ class FASMessages extends Auth_Controller // Loads the view to write a new message with a template $this->load->view( - 'system/messages/htmlWriteTemplate', + 'system/messages/FAShtmlWriteTemplate', $this->CLMessagesModel->prepareHtmlWriteTemplatePrestudents($prestudents, $message_id, $recipient_id) ); } diff --git a/application/views/person/bpk/bpkDetails.php b/application/views/person/bpk/bpkDetails.php index 198065c24..6b7d4430d 100644 --- a/application/views/person/bpk/bpkDetails.php +++ b/application/views/person/bpk/bpkDetails.php @@ -9,7 +9,6 @@ 'jqueryui1' => true, 'ajaxlib' => true, 'tablesorter2' => true, - 'tinymce4' => true, 'sbadmintemplate3' => true, 'addons' => true, 'navigationwidget' => true, diff --git a/application/views/system/infocenter/infocenterDetails.php b/application/views/system/infocenter/infocenterDetails.php index 158feeb2c..15eca90c2 100644 --- a/application/views/system/infocenter/infocenterDetails.php +++ b/application/views/system/infocenter/infocenterDetails.php @@ -8,7 +8,7 @@ 'dialoglib' => true, 'ajaxlib' => true, 'tablesorter2' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'sbadmintemplate3' => true, 'addons' => true, 'navigationwidget' => true, diff --git a/application/views/system/infocenter/infocenterZgvDetails.php b/application/views/system/infocenter/infocenterZgvDetails.php index cf3ffad8b..bf9f69e18 100644 --- a/application/views/system/infocenter/infocenterZgvDetails.php +++ b/application/views/system/infocenter/infocenterZgvDetails.php @@ -10,7 +10,7 @@ 'dialoglib' => true, 'ajaxlib' => true, 'tablesorter2' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'sbadmintemplate3' => true, 'addons' => true, 'navigationwidget' => true, diff --git a/application/views/system/messages/FAShtmlWriteTemplate.php b/application/views/system/messages/FAShtmlWriteTemplate.php new file mode 100644 index 000000000..691629c10 --- /dev/null +++ b/application/views/system/messages/FAShtmlWriteTemplate.php @@ -0,0 +1,197 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'Write a new message or reply using templates', + 'jquery3' => true, + 'jqueryui1' => true, + 'bootstrap3' => true, + 'ajaxlib' => true, + 'fontawesome4' => true, + 'tinymce3' => true, + 'sbadmintemplate3' => true, + 'dialoglib' => true, + 'widgets' => true, + 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), + 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/fasMessageWrite.js') + ) + ); +?> + +

+
+
+
+
+ +
+
+
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+   +
+ +
+
+
+
+
+
+ + +
+
+
+ + + 19 ? 19 : count($variables); + echo $this->widgetlib->widget( + 'MultipleDropdown_widget', + array('elements' => success($variables)), + array( + 'name' => 'variables[]', + 'id' => 'variables', + 'size' => $size, + 'multiple' => true + ) + ); + ?> +
+
+
+ + + 5 ? 5 : count($user_fields); + echo $this->widgetlib->widget( + 'MultipleDropdown_widget', + array('elements' => success($user_fields)), + array( + 'name' => 'user_fields[]', + 'id' => 'user_fields', + 'size' => $size, + 'multiple' => true + ) + ); + ?> +
+
+
+
+
+
+ + widgetlib->widget( + 'Vorlage_widget', + array('oe_kurzbz' => $organisationUnits, 'isAdmin' => $senderIsAdmin), + array('name' => 'vorlage', 'id' => 'vorlageDnD') + ); + ?> + +
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+
+
+ widgetlib->widget( + 'Dropdown_widget', + array( + 'elements' => success($recipientsArray), + 'emptyElement' => ucfirst($this->p->t('global', 'empfaenger')).'...' + ), + array( + 'name' => 'recipients[]', + 'id' => 'recipients' + ) + ); + ?> + + + p->t('ui', 'refresh')); ?> + + +
+
+
+
+
+ +
+ + + + + +
+
+
+
+ + +load->view("templates/FHC-Footer"); ?> + diff --git a/application/views/system/messages/ajaxRead.php b/application/views/system/messages/ajaxRead.php index 2cb88708e..4c1a77deb 100644 --- a/application/views/system/messages/ajaxRead.php +++ b/application/views/system/messages/ajaxRead.php @@ -12,7 +12,7 @@ 'tabulator4' => true, 'ajaxlib' => true, 'dialoglib' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'phrases' => array('global', 'ui'), 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/read.js') diff --git a/application/views/system/messages/ajaxWrite.php b/application/views/system/messages/ajaxWrite.php index 3b1582f22..b3a598506 100644 --- a/application/views/system/messages/ajaxWrite.php +++ b/application/views/system/messages/ajaxWrite.php @@ -10,7 +10,7 @@ 'sbadmintemplate3' => true, 'ajaxlib' => true, 'dialoglib' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'phrases' => array('global', 'ui'), 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/write.js') diff --git a/application/views/system/messages/ajaxWriteReply.php b/application/views/system/messages/ajaxWriteReply.php index 0a496c93e..08dc188fa 100644 --- a/application/views/system/messages/ajaxWriteReply.php +++ b/application/views/system/messages/ajaxWriteReply.php @@ -10,7 +10,7 @@ 'sbadmintemplate3' => true, 'ajaxlib' => true, 'dialoglib' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'phrases' => array('global', 'ui'), 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/writeReply.js') diff --git a/application/views/system/messages/htmlWriteReply.php b/application/views/system/messages/htmlWriteReply.php index 9106d802b..d2150c1fb 100644 --- a/application/views/system/messages/htmlWriteReply.php +++ b/application/views/system/messages/htmlWriteReply.php @@ -6,7 +6,7 @@ 'jquery3' => true, 'bootstrap3' => true, 'fontawesome4' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'sbadmintemplate3' => true, 'customCSSs' => array('public/css/sbadmin2/admintemplate_contentonly.css', 'public/css/messaging/message.css'), 'customJSs' => array('public/js/bootstrapper.js', 'public/js/messaging/messageWriteReply.js') diff --git a/application/views/system/messages/htmlWriteTemplate.php b/application/views/system/messages/htmlWriteTemplate.php index 761e05f96..42a31f374 100644 --- a/application/views/system/messages/htmlWriteTemplate.php +++ b/application/views/system/messages/htmlWriteTemplate.php @@ -8,7 +8,7 @@ 'bootstrap3' => true, 'ajaxlib' => true, 'fontawesome4' => true, - 'tinymce4' => true, + 'tinymce5' => true, 'sbadmintemplate3' => true, 'dialoglib' => true, 'widgets' => true, diff --git a/application/views/system/vorlage/templatetextEdit.php b/application/views/system/vorlage/templatetextEdit.php index 42efc1519..cc2487959 100644 --- a/application/views/system/vorlage/templatetextEdit.php +++ b/application/views/system/vorlage/templatetextEdit.php @@ -1,5 +1,5 @@ load->view('templates/header', array('title' => 'VorlageEdit', 'tinymce4' => true, 'jsonforms' => true)); + $this->load->view('templates/header', array('title' => 'VorlageEdit', 'tinymce5' => true, 'jsonforms' => true)); ?>
diff --git a/application/views/templates/FHC-Common.php b/application/views/templates/FHC-Common.php index dd1d8ae1c..27282bc11 100644 --- a/application/views/templates/FHC-Common.php +++ b/application/views/templates/FHC-Common.php @@ -23,7 +23,7 @@ $tablesorter2 = isset($tablesorter2) ? $tablesorter2 : false; $tabulator4 = isset($tabulator4) ? $tabulator4 : false; $tabulator5 = isset($tabulator5) ? $tabulator5 : false; - $tinymce4 = isset($tinymce4) ? $tinymce4 : false; + $tinymce3 = isset($tinymce3) ? $tinymce3 : false; $tinymce5 = isset($tinymce5) ? $tinymce5 : false; $vue3 = isset($vue3) ? $vue3 : false; $primevue3 = isset($primevue3) ? $primevue3 : false; diff --git a/application/views/templates/FHC-Footer.php b/application/views/templates/FHC-Footer.php index 0c3782fea..ee13c69d2 100644 --- a/application/views/templates/FHC-Footer.php +++ b/application/views/templates/FHC-Footer.php @@ -100,8 +100,8 @@ // Tabulator 5 JS if ($tabulator5 === true) generateJSsInclude('vendor/olifolkerd/tabulator5/dist/js/tabulator.min.js'); - // Tinymce 4 JS - if ($tinymce4 === true) generateJSsInclude('vendor/tinymce/tinymce4/tinymce.min.js'); + // Tinymce 3 JS + if ($tinymce3 === true) generateJSsInclude('include/tiny_mce/tiny_mce.js'); // Tinymce 5 JS if ($tinymce5 === true) generateJSsInclude('vendor/tinymce/tinymce5/tinymce.min.js'); diff --git a/application/views/templates/FHC-Header.php b/application/views/templates/FHC-Header.php index aa63541c5..47eea34ec 100644 --- a/application/views/templates/FHC-Header.php +++ b/application/views/templates/FHC-Header.php @@ -79,9 +79,6 @@ // Tabulator 5 CSS if ($tabulator5 === true) generateCSSsInclude('vendor/olifolkerd/tabulator5/dist/css/tabulator_bootstrap5.min.css'); - // Tinymce 4 CSS - if ($tinymce4 === true) generateCSSsInclude('public/css/TinyMCE4.css'); - // Tinymce 5 CSS if ($tinymce5 === true) generateCSSsInclude('public/css/TinyMCE5.css'); diff --git a/application/views/templates/header.php b/application/views/templates/header.php index 637eb3c7a..e75acca4f 100644 --- a/application/views/templates/header.php +++ b/application/views/templates/header.php @@ -95,7 +95,7 @@ if($jqueryV1 && $jqueryV2) show_error("Two JQuery versions used: composer and in - + diff --git a/application/views/widgets/tinymce.php b/application/views/widgets/tinymce.php index 3e2093e55..618cb4836 100644 --- a/application/views/widgets/tinymce.php +++ b/application/views/widgets/tinymce.php @@ -5,5 +5,6 @@ plugins: [], toolbar: "" }); - - < name="" style="">> + +< name="" style="">> + diff --git a/public/css/TinyMCE.css b/public/css/TinyMCE5.css similarity index 100% rename from public/css/TinyMCE.css rename to public/css/TinyMCE5.css diff --git a/public/js/messaging/fasMessageWrite.js b/public/js/messaging/fasMessageWrite.js new file mode 100644 index 000000000..d32f80fac --- /dev/null +++ b/public/js/messaging/fasMessageWrite.js @@ -0,0 +1,140 @@ +// ******************************************************** +// JS used by view system/messages/htmlWriteTemplate +// ******************************************************** + +function tinymcePreviewSetContent() +{ + if ($("#tinymcePreview")) + { + if ($("#recipients").children(":selected").val() > -1) + { + parseMessageText($("#recipients").children(":selected").val(), tinyMCE.get("bodyTextArea").getContent()); + } + else + { + tinyMCE.get("tinymcePreview").setContent(""); + } + } +} + +function parseMessageText(receiver_id, text) +{ + FHC_AjaxClient.ajaxCallPost( + "system/messages/Messages/parseMessageText", + { + receiver_id: receiver_id, + text: text, + type: $("#type").val() + }, + { + successCallback: function(data, textStatus, jqXHR) { + + if (FHC_AjaxClient.hasData(data)) + { + tinyMCE.get("tinymcePreview").setContent(FHC_AjaxClient.getData(data)); + } + else if (FHC_AjaxClient.isError(data)) + { + FHC_DialogLib.alertError(data.retval); + } + } + } + ); +} + +$(document).ready(function () +{ + + tinymce.init({ + theme : "advanced", + mode : "textareas" + }); + + if ($("#variables")) + { + $("#variables").dblclick(function () + { + if ($("#bodyTextArea")) + { + //if editor active add at cursor position, otherwise at end + if (tinymce.activeEditor.id === "bodyTextArea") + tinymce.activeEditor.execCommand('mceInsertContent', false, $(this).children(":selected").val()); + else + tinyMCE.get("bodyTextArea").setContent(tinyMCE.get("bodyTextArea").getContent() + $(this).children(":selected").val()); + } + }); + } + + if ($("#user_fields")) + { + $("#user_fields").dblclick(function () + { + if ($("#bodyTextArea")) + { + //if editor active add at cursor position, otherwise at end + if (tinymce.activeEditor.id === "bodyTextArea") + tinymce.activeEditor.execCommand('mceInsertContent', false, $(this).children(":selected").val()); + else + tinyMCE.get("bodyTextArea").setContent(tinyMCE.get("bodyTextArea").getContent() + $(this).children(":selected").val()); + } + }); + } + + if ($("#recipients")) + { + $("#recipients").change(tinymcePreviewSetContent); + } + + if ($("#refresh")) + { + $("#refresh").click(tinymcePreviewSetContent); + } + + if ($("#sendButton") && $("#sendForm")) + { + $("#sendButton").click(function () + { + if ($("#subject") && $("#subject").val() != '' && tinyMCE.get("bodyTextArea").getContent() != '') + { + $("#sendForm").submit(); + } + else + { + FHC_DialogLib.alertInfo("Subject and text are required fields!"); + } + }); + } + + if ($("#vorlageDnD")) + { + $("#vorlageDnD").change(function () + { + var vorlage_kurzbz = this.value; + + if (vorlage_kurzbz != '') + { + FHC_AjaxClient.ajaxCallGet( + "system/messages/Messages/getVorlage", + { + vorlage_kurzbz: vorlage_kurzbz + }, + { + successCallback: function(data, textStatus, jqXHR) { + + if (FHC_AjaxClient.hasData(data)) + { + var msg = FHC_AjaxClient.getData(data); + + tinyMCE.get("bodyTextArea").setContent(msg[0].text); + $("#subject").val(msg[0].subject); + } + } + } + ); + } + }); + } + + $("#subject").focus(); + +}); diff --git a/public/js/messaging/messageWrite.js b/public/js/messaging/messageWrite.js index 8b1d73bdf..382e79948 100644 --- a/public/js/messaging/messageWrite.js +++ b/public/js/messaging/messageWrite.js @@ -42,8 +42,8 @@ function parseMessageText(receiver_id, text) ); } -$(document).ready(function () -{ +$(document).ready(function () { + tinymce.init({ selector: "#bodyTextArea", plugins: "autoresize", @@ -60,7 +60,12 @@ $(document).ready(function () menubar: false, toolbar: false, statusbar: false, - readonly: 1 + readonly: 1, + autoresize_on_init: false, + autoresize_min_height: 400, + autoresize_max_height: 700, + autoresize_bottom_margin: 10, + auto_focus: "bodyTextArea" }); if ($("#variables")) diff --git a/public/js/messaging/write.js b/public/js/messaging/write.js index 1370fb2e0..bff451c2e 100644 --- a/public/js/messaging/write.js +++ b/public/js/messaging/write.js @@ -63,7 +63,7 @@ $(document).ready(function () { tinymce.init({ selector: "#body", plugins: "autoresize", - autoresize_min_height: 150, + autoresize_min_height: 300, autoresize_max_height: 600, autoresize_bottom_margin: 10 }); From a412db7356eb9e6ed64d1637b1617be5d38a1ff5 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Fri, 11 Nov 2022 14:27:06 +0100 Subject: [PATCH 027/439] Attribut raumtyp_aktiv als boolean parsen --- include/raumtyp.class.php | 6 ++---- rdf/raumtyp.rdf.php | 10 +++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/include/raumtyp.class.php b/include/raumtyp.class.php index 6aa54254e..ec274df7a 100644 --- a/include/raumtyp.class.php +++ b/include/raumtyp.class.php @@ -68,8 +68,7 @@ class raumtyp extends basis_db $raumtyp_obj->beschreibung = $row->beschreibung; $raumtyp_obj->raumtyp_kurzbz = $row->raumtyp_kurzbz; - $raumtyp_obj->aktiv = $row->aktiv; - + $raumtyp_obj->aktiv = $this->db_parse_bool($row->aktiv); $this->result[] = $raumtyp_obj; } @@ -101,8 +100,7 @@ class raumtyp extends basis_db { $this->beschreibung = $row->beschreibung; $this->raumtyp_kurzbz = $row->kurzbz; - $this->aktiv = $row->aktiv; - + $this->aktiv = $this->db_parse_bool($row->aktiv); } else { diff --git a/rdf/raumtyp.rdf.php b/rdf/raumtyp.rdf.php index 56da76b5b..1f7289747 100644 --- a/rdf/raumtyp.rdf.php +++ b/rdf/raumtyp.rdf.php @@ -56,11 +56,11 @@ foreach ($raumtypDAO->result as $rt) { ?> - - raumtyp_kurzbz ?> - beschreibung ?> - aktiv=='t'?'true':'false') ?> - + + raumtyp_kurzbz ?> + beschreibung ?> + aktiv ? "true" : "false") ?> + Date: Tue, 15 Nov 2022 11:22:47 +0100 Subject: [PATCH 028/439] 26198 Notenimport ausschliesslich bei vorhandener Note --- .../lehre/benotungstool/nachpruefungeintragen.php | 12 +++++++++++- locale/de-AT/benotungstool.php | 3 ++- locale/en-US/benotungstool.php | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/cis/private/lehre/benotungstool/nachpruefungeintragen.php b/cis/private/lehre/benotungstool/nachpruefungeintragen.php index 290113179..bf0d4b197 100644 --- a/cis/private/lehre/benotungstool/nachpruefungeintragen.php +++ b/cis/private/lehre/benotungstool/nachpruefungeintragen.php @@ -95,6 +95,8 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) { $errorMatrnr = ''; $errorDatum = ''; + $errorNachp = ''; + foreach ($_POST as $row => $val) { if(mb_strstr(mb_strtolower($row), 'student_uid_')) @@ -140,6 +142,14 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) } } + //check ob eine Note vorhanden ist oder (intern) angerechnet wurde + $lvnote = new lvgesamtnote(); + if (!$lvnote->load($lvid, $student_uid, $stsem)) + { + $errorNachp.="\n".$p->t('benotungstool/NachpruefungNichtZulaessig', array($student_uid)); + continue; + } + $lehreinheit_id = getLehreinheit($db, $lvid, $student_uid, $stsem); if(isset($_POST['student_uid_'.$id]) && (isset($_POST['note_'.$id]) || isset($_POST['punkte_'.$id])) && isset($_POST['datumNachp_'.$id])) @@ -152,7 +162,7 @@ if (isset($_REQUEST['sammel']) && $_REQUEST["sammel"] == 1) } } } - echo $errorMatrnr . $errorDatum; + echo $errorMatrnr . $errorDatum . $errorNachp; } else { diff --git a/locale/de-AT/benotungstool.php b/locale/de-AT/benotungstool.php index feac092f6..d6e77d3ce 100644 --- a/locale/de-AT/benotungstool.php +++ b/locale/de-AT/benotungstool.php @@ -150,8 +150,9 @@ $this->phrasen['benotungstool/kreuzerltool']='Kreuzerltool'; $this->phrasen['benotungstool/studentIstLvNichtZugeordnet']='Der Student %s %s (%s) ist dieser Lehrveranstaltung nicht zugeordnet. Die Note wird nicht uebernommen!'; $this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student*in mit Matrikelnummer %s existiert nicht.'; $this->phrasen['benotungstool/datumsformatUnzulaessig']='Das Datum %s entspricht nicht dem Format TT.MM.JJJJ!'; +$this->phrasen['benotungstool/NachpruefungNichtZulaessig']='Nachprüfung für Student*in %s nicht zulässig.'; $this->phrasen['benotungstool/noteUnzulaessig']='Die Note %s ist nicht zulaessig. Die Zeile wurde uebersprungen.'; -$this->phrasen['benotungstool/noteNichtUeberschreibbar']='Für Student mit Matrikelnummer %s eingetragene Zeugnisote %s ist nicht überschreibbar'; +$this->phrasen['benotungstool/noteNichtUeberschreibbar']='Für Student mit Matrikelnummer %s eingetragene Zeugnisnote %s ist nicht überschreibbar'; $this->phrasen['benotungstool/fehlerhafteNoteBeiStudent']='Fehlerhafte Note bei Student %s %s'; $this->phrasen['benotungstool/keineKreuzerllistenFuerDieseLehrveranstaltung']='Derzeit gibt es keine Kreuzerllisten für diese Lehrveranstaltung'; $this->phrasen['benotungstool/notenuebersichtFuer']='Notenübersicht für'; diff --git a/locale/en-US/benotungstool.php b/locale/en-US/benotungstool.php index f482409d8..73a3bd343 100644 --- a/locale/en-US/benotungstool.php +++ b/locale/en-US/benotungstool.php @@ -148,6 +148,7 @@ $this->phrasen['benotungstool/pruefungAnlegenFuer']='Create an examination for ' $this->phrasen['benotungstool/kreuzerltool']='"Kreuzerl" tool'; $this->phrasen['benotungstool/studentIstLvNichtZugeordnet']='Student is not assigned to this course. The grade was not accepted!'; $this->phrasen['benotungstool/studentMitMatrikelnummerExistiertNicht']='Student with student ID number %s does not exist.'; +$this->phrasen['benotungstool/NachpruefungNichtZulaessig']='Re-examination for student %s not allowed.'; $this->phrasen['benotungstool/datumsformatUnzulaessig']='The date %s is not in valid format TT.MM.JJJJ.'; $this->phrasen['benotungstool/noteNichtUeberschreibbar']='Transcript grade %2$s for student with Personal identifier %1$s is not rewritable'; $this->phrasen['benotungstool/fehlerhafteNoteBeiStudent']='Incorrect grade for student %s %s'; From 01107e361fdcbf01723c57e70e77e3f6b8ff0713 Mon Sep 17 00:00:00 2001 From: Nikolaus Krondraf Date: Fri, 18 Nov 2022 10:01:39 +0100 Subject: [PATCH 029/439] =?UTF-8?q?Studierende=20k=C3=B6nnen=20sich=20fr?= =?UTF-8?q?=C3=BChestens=202=20Monate=20vor=20Pr=C3=BCfung=20anmelden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cis/private/lehre/pruefung/pruefung.js.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/cis/private/lehre/pruefung/pruefung.js.php b/cis/private/lehre/pruefung/pruefung.js.php index f2435828d..6dda6e0fe 100644 --- a/cis/private/lehre/pruefung/pruefung.js.php +++ b/cis/private/lehre/pruefung/pruefung.js.php @@ -353,10 +353,9 @@ function writePruefungsTable(e, data, anmeldung) var time = termin[1].substring(0,5); termin = termin[0].split("-"); - // Wie viele Monate vor Prüfungen dürfen sich Studierende anmelden? - // Sperre "deaktiviert" indem man sich 24 Monate vorher anmelden darf + // Studierende dürfen sich 2 Monate vor Prüfungen anmelden? var minimumFrist = new Date(termin[0], termin[1]-1,termin[2]); - minimumFrist.setMonth(minimumFrist.getMonth() - 24); + minimumFrist.setMonth(minimumFrist.getMonth() - 2); termin = new Date(termin[0], termin[1]-1,termin[2]); var frist = termin; From 1ec742b8fe1f8fa366e69f371b40faf0b38df44d Mon Sep 17 00:00:00 2001 From: Nikolaus Krondraf Date: Fri, 18 Nov 2022 10:05:38 +0100 Subject: [PATCH 030/439] typo --- cis/private/lehre/pruefung/pruefung.js.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cis/private/lehre/pruefung/pruefung.js.php b/cis/private/lehre/pruefung/pruefung.js.php index 6dda6e0fe..f1bafe192 100644 --- a/cis/private/lehre/pruefung/pruefung.js.php +++ b/cis/private/lehre/pruefung/pruefung.js.php @@ -353,7 +353,7 @@ function writePruefungsTable(e, data, anmeldung) var time = termin[1].substring(0,5); termin = termin[0].split("-"); - // Studierende dürfen sich 2 Monate vor Prüfungen anmelden? + // Studierende dürfen sich 2 Monate vor Prüfungen anmelden var minimumFrist = new Date(termin[0], termin[1]-1,termin[2]); minimumFrist.setMonth(minimumFrist.getMonth() - 2); From 7cdb7688c4cb858c0fca8044c0ea4cc53276db89 Mon Sep 17 00:00:00 2001 From: Cris Date: Mon, 28 Nov 2022 17:27:39 +0100 Subject: [PATCH 031/439] =?UTF-8?q?Fixed:=20Vergangene=20Anrechnungen=20k?= =?UTF-8?q?=C3=B6nnen=20jetzt=20eingesehen=20werden?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manche vergangene Anrechnungen konnten nicht eingesehen werden, weil die Zuordnung der Studenten zu den Lehrveranstaltungen aufgelöst bzw. geändert werden. Gefixt, indem nun bei einer bestehenden Anrechnung die bei der Anrechnung hinterlegten Lehrveranstaltung herangezogen wird. --- .../anrechnung/ApproveAnrechnungDetail.php | 3 +- .../lehre/anrechnung/RequestAnrechnung.php | 2 +- .../anrechnung/ReviewAnrechnungDetail.php | 3 +- application/libraries/AnrechnungLib.php | 28 ++++++++++++++----- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php index 1f5c853db..b7953456c 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -90,7 +90,8 @@ class approveAnrechnungDetail extends Auth_Controller $antragData = $this->anrechnunglib->getAntragData( $anrechnungData->prestudent_id, $anrechnungData->studiensemester_kurzbz, - $anrechnungData->lehrveranstaltung_id + $anrechnungData->lehrveranstaltung_id, + $anrechnungData->anrechnung_id ); // Get Empfehlung data diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php index fbaac9b3e..3f9138f04 100644 --- a/application/controllers/lehre/anrechnung/RequestAnrechnung.php +++ b/application/controllers/lehre/anrechnung/RequestAnrechnung.php @@ -93,7 +93,7 @@ class requestAnrechnung extends Auth_Controller $anrechnungData = $this->anrechnunglib->getAnrechnungDataByLv($lehrveranstaltung_id, $studiensemester_kurzbz, $prestudent_id); // Get Antrag data - $antragData = $this->anrechnunglib->getAntragData($prestudent_id, $studiensemester_kurzbz, $lehrveranstaltung_id); + $antragData = $this->anrechnunglib->getAntragData($prestudent_id, $studiensemester_kurzbz, $lehrveranstaltung_id, $anrechnungData->anrechnung_id); $viewData = array( 'antragData' => $antragData, diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php index 1bd92004d..d2a3696b3 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php @@ -84,7 +84,8 @@ class reviewAnrechnungDetail extends Auth_Controller $antragData = $this->anrechnunglib->getAntragData( $anrechnungData->prestudent_id, $anrechnungData->studiensemester_kurzbz, - $anrechnungData->lehrveranstaltung_id + $anrechnungData->lehrveranstaltung_id, + $anrechnungData->anrechnung_id ); // Get Empfehlung data diff --git a/application/libraries/AnrechnungLib.php b/application/libraries/AnrechnungLib.php index 86a81fb55..dfa733d8d 100644 --- a/application/libraries/AnrechnungLib.php +++ b/application/libraries/AnrechnungLib.php @@ -37,18 +37,32 @@ class AnrechnungLib * @param $lv_id * @return StdClass */ - public function getAntragData($prestudent_id, $studiensemester_kurzbz, $lv_id) + public function getAntragData($prestudent_id, $studiensemester_kurzbz, $lv_id, $anrechnung_id) { $antrag_data = new StdClass(); // Get students UID. $uid = $this->ci->StudentModel->getUID($prestudent_id); - - // Get lehrveranstaltung data. Break, if course is not assigned to student. - if(!$lv = getData($this->ci->LehrveranstaltungModel->getLvByStudent($uid, $studiensemester_kurzbz, $lv_id))[0]) - { - show_error('You are not assigned to this course yet.'); - } + + // Get lehrveranstaltung data. + // If it is a first time request for Anrechnung... + if (isEmptyString($anrechnung_id)) + { + //...get LV by student to check also, if student is assigned to that lv + $result = $this->ci->LehrveranstaltungModel->getLvByStudent($uid, $studiensemester_kurzbz, $lv_id); + if (!hasData($result)) + { + // ...and break, if course is not assigned to student + show_error('You are not assigned to this course yet.'); + } + } + //...in any other case (STGL View; Lector View; Student View when Anrechnung exist) + else + { + $result = $this->ci->LehrveranstaltungModel->load($lv_id); + } + + $lv = getData($result)[0]; // Get the students personal data if (!$person = getData($this->ci->PersonModel->getByUid($uid))[0]) From ca217f186979c9eb5d8ded9b65bf940a511e2748 Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 29 Nov 2022 18:10:39 +0100 Subject: [PATCH 032/439] Fixed: Downloadlink erzeugt nach Page Reload keine Fehlermeldung mehr --- .../anrechnung/approveAnrechnungUebersichtData.php | 6 +----- .../anrechnung/reviewAnrechnungUebersichtData.php | 6 +----- .../anrechnung/approveAnrechnungUebersicht.js | 14 ++++++++++++++ .../lehre/anrechnung/reviewAnrechnungUebersicht.js | 14 ++++++++++++++ 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php index 83370769f..1eade50d2 100644 --- a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php +++ b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php @@ -213,11 +213,7 @@ $filterWidgetArray = array( begruendung: {headerFilter:"input", visible: true}, student: {headerFilter:"input"}, zgv: {visible: false, headerFilter:"input"}, - dokument_bezeichnung: {headerFilter:"input", formatter:"link", formatterParams:{ - labelField:"dokument_bezeichnung", - url:function(cell){return "'. current_url() .'/download?dms_id=" + cell.getData().dms_id}, - target:"_blank" - }}, + dokument_bezeichnung: {headerFilter:"input", formatter:"link", formatterParams: paramLookup_dokBez}, anmerkung_student: {headerFilter:"input"}, antragsdatum: {align:"center", headerFilter:"input", mutator: mut_formatStringDate}, empfehlung_anrechnung: {headerFilter:"input", align:"center", formatter: format_empfehlung_anrechnung, headerFilterFunc: hf_filterTrueFalse}, diff --git a/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php index 89b3ba70f..d48018171 100644 --- a/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php +++ b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php @@ -134,11 +134,7 @@ $filterWidgetArray = array( student: {headerFilter:"input"}, begruendung: {headerFilter:"input"}, zgv: {visible: false, headerFilter:"input"}, - dokument_bezeichnung: {headerFilter:"input", formatter:"link", formatterParams:{ - labelField:"dokument_bezeichnung", - url:function(cell){return "'. current_url() .'/download?dms_id=" + cell.getData().dms_id}, - target:"_blank" - }}, + dokument_bezeichnung: {headerFilter:"input", formatter:"link", formatterParams: paramLookup_dokBez}, anmerkung_student: {headerFilter:"input"}, antragsdatum: {align:"center", headerFilter:"input", mutator: mut_formatStringDate}, empfehlung_anrechnung: {headerFilter:"input", align:"center", formatter: format_empfehlung_anrechnung, headerFilterFunc: hf_filterTrueFalse}, diff --git a/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js b/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js index e831856d8..15d657b81 100644 --- a/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js +++ b/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js @@ -1,4 +1,6 @@ const BASE_URL = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router; +const CALLED_PATH = FHC_JS_DATA_STORAGE_OBJECT.called_path; +const CONTROLLER_URL = BASE_URL + '/' + CALLED_PATH; const APPROVE_ANRECHNUNG_DETAIL_URI = "lehre/anrechnung/ApproveAnrechnungDetail"; const ANRECHNUNGSTATUS_PROGRESSED_BY_STGL = 'inProgressDP'; @@ -203,6 +205,18 @@ var format_empfehlung_anrechnung = function(cell, formatterParams){ : FHC_PhrasesLib.t("ui", "nein"); } +/** + * Returns formatter params for field dokument_bezeichnung (= Spalte Nachweisdokumente) + * NOTE: Returning a formatter param object fixes the problem, that tabulator did not know the url after refreshing the page. + */ +function paramLookup_dokBez(cell){ + return { + labelField: 'dokument_bezeichnung', + url: CONTROLLER_URL + '/download?dms_id=' + cell.getData().dms_id, + target: '_blank' + } +} + /* * Hook to overwrite TableWigdgets select-all-button behaviour * Select all (filtered) rows that are progressed by stg leiter. diff --git a/public/js/lehre/anrechnung/reviewAnrechnungUebersicht.js b/public/js/lehre/anrechnung/reviewAnrechnungUebersicht.js index fd7155fa0..47b2a2dc5 100644 --- a/public/js/lehre/anrechnung/reviewAnrechnungUebersicht.js +++ b/public/js/lehre/anrechnung/reviewAnrechnungUebersicht.js @@ -1,4 +1,6 @@ const BASE_URL = FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router; +const CALLED_PATH = FHC_JS_DATA_STORAGE_OBJECT.called_path; +const CONTROLLER_URL = BASE_URL + '/' + CALLED_PATH; const APPROVE_ANRECHNUNG_DETAIL_URI = "lehre/anrechnung/ReviewAnrechnungDetail"; const ANRECHNUNGSTATUS_PROGRESSED_BY_STGL = 'inProgressDP'; @@ -121,6 +123,18 @@ var format_empfehlung_anrechnung = function(cell, formatterParams){ : FHC_PhrasesLib.t("ui", "nein"); } +/** + * Returns formatter params for field dokument_bezeichnung (= Spalte Nachweisdokumente) + * NOTE: Returning a formatter param object fixes the problem, that tabulator did not know the url after refreshing the page. + */ +function paramLookup_dokBez(cell){ + return { + labelField: 'dokument_bezeichnung', + url: CONTROLLER_URL + '/download?dms_id=' + cell.getData().dms_id, + target: '_blank' + } +} + /* * Hook to overwrite TableWigdgets select-all-button behaviour * Select all (filtered) rows that are progressed by stg leiter. From cee15a68ba5a0b53e7575d873b4db0d49a4ce710 Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 10:48:52 +0100 Subject: [PATCH 033/439] Added config['fbl'] and config['send_mail'] to anrechnungen . config['fbl'] enables Fachbereichsleitung instead of LektorInnen . config['send_mail'] enables sending Info Mails --- application/config/anrechnung.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/application/config/anrechnung.php b/application/config/anrechnung.php index c2e38385c..2c7ec1a5b 100644 --- a/application/config/anrechnung.php +++ b/application/config/anrechnung.php @@ -7,8 +7,8 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); $config['interval_blocking_application'] = 'P1M'; // Application submission period given by start- and enddate. -$config['submit_application_start'] = '05.09.2022'; -$config['submit_application_end'] = '22.09.2022'; +//$config['submit_application_start'] = '05.09.2022'; +//$config['submit_application_end'] = '22.10.2022'; // Lehrveranstaltungen with these grades will be blocked for application $config['grades_blocking_application'] = array( @@ -19,4 +19,9 @@ $config['grades_blocking_application'] = array( 14, // nicht bestanden, 15, // nicht teilgenommen 18 // unentschuldigt -); \ No newline at end of file +); + +//Enables Fachbereichsleiter instead of LV Leiter +$config['fbl'] = FALSE; +//Enables Info Mails +$config['send_mail'] = TRUE; \ No newline at end of file From 10ed780b6c76847b9d2bf0f928669591d8cc40eb Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 10:50:08 +0100 Subject: [PATCH 034/439] Added method getFachbereichsleitungByLv to Lehrveranstaltung_model Gets all fachbereichsleiter of a Lehrveranstaltung --- .../education/Lehrveranstaltung_model.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index f54443955..b0c7d23a6 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -200,6 +200,29 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($query, array($lehrveranstaltung_id, $studiensemester_kurzbz)); } + /** + * Gets all fachbereichsleiter of a Lehrveranstaltung + * @param $lehrveranstaltung_id + * @return array|null + */ + public function getFachbereichByLv($lehrveranstaltung_id) + { + $query = "select distinct vorname, nachname, uid, true as lvleiter + FROM + lehre.tbl_lehrveranstaltung lv + JOIN public.tbl_organisationseinheit og using (oe_kurzbz) + JOIN public.tbl_benutzerfunktion bf using (oe_kurzbz) + join public.tbl_benutzer b using (uid) + join public.tbl_person p using (person_id) + where + bf.datum_von <= now()::date + and (bf.datum_bis >= now()::date or bf.datum_bis is null) + and bf.funktion_kurzbz = 'Leitung' + AND og.organisationseinheittyp_kurzbz = 'Fachbereich' + and lehrveranstaltung_id = ?"; + + return $this->execQuery($query, array($lehrveranstaltung_id)); + } /** * Gets Lehrveranstaltungen of a student From 88246c443a85df82fa2b20712d7cd808599af01c Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 10:53:21 +0100 Subject: [PATCH 035/439] Added function getFachbereichleitung to AnrechnungLib ...plus adaptation to getEmpfehlungData to use this function. --- application/libraries/AnrechnungLib.php | 57 +++++++++++++++++++++---- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/application/libraries/AnrechnungLib.php b/application/libraries/AnrechnungLib.php index 86a81fb55..82410b398 100644 --- a/application/libraries/AnrechnungLib.php +++ b/application/libraries/AnrechnungLib.php @@ -274,14 +274,21 @@ class AnrechnungLib if (hasData($result)) { $empfehlung_data->empfehlungsanfrageAm = (new DateTime($result->retval[0]->insertamum))->format('d.m.Y'); - - // Get lectors who received request for recommendation - $lector_arr = self::getLectors($anrechnung_id); - - if (!isEmptyArray($lector_arr)) - { - $empfehlung_data->empfehlungsanfrageAn = implode(', ', array_column($lector_arr, 'fullname')); - } + + // Get users who received request for recommendation (Fachbereichsleitung / Lektor) + if($this->ci->config->item('fbl') === TRUE) + { + $res = $this->getFachbereichleitung($anrechnung_id); + } + else + { + $res = $this->getLectors($anrechnung_id); + } + + if (!isEmptyArray($res)) + { + $empfehlung_data->empfehlungsanfrageAn = implode(', ', array_column($res, 'fullname')); + } } if (is_null($anrechnung->empfehlung_anrechnung)) @@ -803,6 +810,40 @@ class AnrechnungLib return $lector_arr; } + /** + * Get Fachbereichsleitung. + * + * @param $anrechnung_id + * @return false|mixed|null + */ + public function getFachbereichleitung($anrechnung_id) + { + $this->ci->AnrechnungModel->addSelect('lehrveranstaltung_id'); + $result = $this->ci->AnrechnungModel->load($anrechnung_id); + + $lehrveranstaltung_id = getData($result)[0]->lehrveranstaltung_id; + + // Get FBLs + $result = $this->ci->LehrveranstaltungModel->getFachbereichByLv($lehrveranstaltung_id); + + if (!hasData($result)) + { + return false; + } + + $fbl_arr = getData($result); + + foreach ($fbl_arr as $fbl) + { + $fbl->fullname = $fbl->vorname. ' '. $fbl->nachname; + } + + // Now make the fbl array unique + $fbl_arr = array_unique($fbl_arr, SORT_REGULAR); + + return $fbl_arr; + } + // Return an object with Anrechnungdata private function _setAnrechnungDataObject($anrechnung) { From 4a87fb49e908091a3612bf82b1c5e131abc3b713 Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 13:22:48 +0100 Subject: [PATCH 036/439] Created new Review Anrechnung Uebersicht Tabulator for Fachbereichsleitung --- .../reviewAnrechnungUebersichtData_fbl.php | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 application/views/lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php diff --git a/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php new file mode 100644 index 000000000..a20d85f9f --- /dev/null +++ b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php @@ -0,0 +1,159 @@ +>' . $LANGUAGE_INDEX . ', + array_to_json(zgv.bezeichnung::varchar[])->>' . $LANGUAGE_INDEX . ' + ) AS zgv + FROM public.tbl_prestudent + LEFT JOIN bis.tbl_zgv zgv USING (zgv_code) + LEFT JOIN bis.tbl_zgvmaster zgvmaster USING (zgvmas_code) + WHERE prestudent_id = anrechnung.prestudent_id + ) AS zgv, + anrechnung.insertamum::date AS "antragsdatum", + empfehlung_anrechnung, + (SELECT status_kurzbz + FROM lehre.tbl_anrechnungstatus + JOIN lehre.tbl_anrechnung_anrechnungstatus USING (status_kurzbz) + WHERE anrechnung_id = anrechnung.anrechnung_id + ORDER BY insertamum DESC + LIMIT 1 + ) AS status_kurzbz + FROM lehre.tbl_anrechnung AS anrechnung + JOIN public.tbl_prestudent USING (prestudent_id) + JOIN public.tbl_person AS person USING (person_id) + JOIN public.tbl_studiengang AS stg USING (studiengang_kz) + JOIN lehre.tbl_lehrveranstaltung AS lv USING (lehrveranstaltung_id) + LEFT JOIN campus.tbl_dms_version AS dmsversion USING (dms_id) + JOIN lehre.tbl_anrechnung_anrechnungstatus USING (anrechnung_id) + JOIN lehre.tbl_anrechnung_begruendung AS begruendung USING (begruendung_id) + ) + +SELECT DISTINCT /*ON (anrechnungen.*, bf.uid)*/ anrechnungen.*, + array_to_json(anrechnungstatus.bezeichnung_mehrsprachig::varchar[])->>' . $LANGUAGE_INDEX . ' AS "status_bezeichnung" + FROM anrechnungen + JOIN lehre.tbl_anrechnungstatus as anrechnungstatus ON (anrechnungstatus.status_kurzbz = anrechnungen.status_kurzbz) + JOIN lehre.tbl_lehreinheit le USING (lehrveranstaltung_id) +/*JOIN lehre.tbl_lehreinheitmitarbeiter lema USING (lehreinheit_id)*/ +JOIN lehre.tbl_lehrveranstaltung lv using (lehrveranstaltung_id) +JOIN public.tbl_organisationseinheit og using (oe_kurzbz) +JOIN public.tbl_benutzerfunktion bf using (oe_kurzbz) + WHERE anrechnungen.studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' + AND le.studiensemester_kurzbz = anrechnungen.studiensemester_kurzbz +/*AND lema.mitarbeiter_uid = \'' . $LEKTOR_UID . '\'*/ + AND le.lehre = TRUE +AND bf.funktion_kurzbz = \'Leitung\' +AND og.organisationseinheittyp_kurzbz = \'Fachbereich\' +AND bf.uid = \'' . $LEKTOR_UID . '\' + AND EXISTS ( + SELECT 1 + FROM lehre.tbl_anrechnung_anrechnungstatus + WHERE anrechnung_id = anrechnungen.anrechnung_id + AND status_kurzbz=\'inProgressLektor\' + ) +order by empfehlung_anrechnung NULLS FIRST, antragsdatum +'; + +$filterWidgetArray = array( + 'query' => $query, + 'tableUniqueId' => 'approveAnrechnungUebersicht', + 'requiredPermissions' => 'lehre/anrechnung_empfehlen', + 'datasetRepresentation' => 'tabulator', + 'columnsAliases' => array( + 'anrechnung_id', + 'lehrveranstaltung_id', + 'begruendung_id', + 'dms_id', + 'studiensemester_kurzbz', + 'studiengang_kz', + ucfirst($this->p->t('lehre', 'studiengang')), + ucfirst($this->p->t('lehre', 'lehrveranstaltung')), + 'ECTS', + ucfirst($this->p->t('person', 'studentIn')), + ucfirst($this->p->t('global', 'begruendung')), + ucfirst($this->p->t('anrechnung', 'nachweisdokumente')), + ucfirst($this->p->t('anrechnung', 'herkunft')), + ucfirst($this->p->t('global', 'zgv')), + ucfirst($this->p->t('anrechnung', 'antragdatum')), + ucfirst($this->p->t('anrechnung', 'empfehlung')), + 'status_kurzbz', + 'Status' + ), + 'datasetRepOptions' => '{ + height: func_height(this), + layout: "fitColumns", // fit columns to width of table + persistentLayout:true, + persistentSort:true, + autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated + headerFilterPlaceholder: " ", + index: "anrechnung_id", // assign specific column as unique id (important for row indexing) + selectable: true, // allow row selection + selectableRangeMode: "click", // allow range selection using shift end click on end of range + selectablePersistence:false, // deselect previously selected rows when table is filtered, sorted or paginated + tableBuilt: function(){ + func_tableBuilt(this); + }, + tableWidgetFooter: { + selectButtons: true + }, + selectableCheck: function(row){ + return func_selectableCheck(row); + }, + rowFormatter:function(row){ + func_rowFormatter(row); + }, + rowUpdated:function(row){ + func_rowUpdated(row); + }, + tooltips: function(cell){ + return func_tooltips(cell); + } + }', // tabulator properties + 'datasetRepFieldsDefs' => '{ + anrechnung_id: {visible: false, headerFilter:"input"}, + lehrveranstaltung_id: {visible: false, headerFilter:"input"}, + begruendung_id: {visible: false, headerFilter:"input"}, + dms_id: {visible: false, headerFilter:"input"}, + studiensemester_kurzbz: {visible: false, headerFilter:"input"}, + studiengang_kz: {visible: false, headerFilter:"input"}, + stg_bezeichnung: {headerFilter:"input"}, + lv_bezeichnung: {headerFilter:"input"}, + ects: {headerFilter:"input", align:"center"}, + student: {headerFilter:"input"}, + begruendung: {headerFilter:"input"}, + zgv: {visible: false, headerFilter:"input"}, + dokument_bezeichnung: {headerFilter:"input", formatter:"link", formatterParams:{ + labelField:"dokument_bezeichnung", + url:function(cell){return "'. current_url() .'/download?dms_id=" + cell.getData().dms_id}, + target:"_blank" + }}, + anmerkung_student: {headerFilter:"input"}, + antragsdatum: {align:"center", headerFilter:"input", mutator: mut_formatStringDate}, + empfehlung_anrechnung: {headerFilter:"input", align:"center", formatter: format_empfehlung_anrechnung, headerFilterFunc: hf_filterTrueFalse}, + status_kurzbz: {visible: false, headerFilter:"input"}, + status_bezeichnung: {headerFilter:"input"} + }', // col properties +); + +echo $this->widgetlib->widget('TableWidget', $filterWidgetArray); + +?> \ No newline at end of file From fe2601b29ae15bbf7b92136ed24305e920506a0d Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 13:25:25 +0100 Subject: [PATCH 037/439] Adapt view to use Fachbereichsleitungs-DataView --- .../views/lehre/anrechnung/reviewAnrechnungUebersicht.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/application/views/lehre/anrechnung/reviewAnrechnungUebersicht.php b/application/views/lehre/anrechnung/reviewAnrechnungUebersicht.php index ae5e08055..82e66487f 100644 --- a/application/views/lehre/anrechnung/reviewAnrechnungUebersicht.php +++ b/application/views/lehre/anrechnung/reviewAnrechnungUebersicht.php @@ -117,7 +117,13 @@ $this->load->view(
- load->view('lehre/anrechnung/reviewAnrechnungUebersichtData.php'); ?> + load->config('anrechnung'); + if($this->config->item('fbl')===TRUE) + $this->load->view('lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php'); + else + $this->load->view('lehre/anrechnung/reviewAnrechnungUebersichtData.php');?>
From 0197e5b175cd81a2e059d845cbe2cbd98f468e67 Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 13:33:28 +0100 Subject: [PATCH 038/439] Adapted STGL Views to display Fachbereichsleitung (as 'Empfaenger') after recommendation --- .../anrechnung/ApproveAnrechnungDetail.php | 23 +++++++++++-------- .../ApproveAnrechnungUebersicht.php | 23 +++++++++++++------ 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php index 1f5c853db..ccdabf4e0 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -33,6 +33,9 @@ class approveAnrechnungDetail extends Auth_Controller ) ); + //Load configs + $this->load->config('anrechnung'); + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel'); @@ -227,16 +230,18 @@ class approveAnrechnungDetail extends Auth_Controller // Count up LV with no lector $counter++; - // Break, if LV has no lector - break; - } + // Get Fachbereichsleitung or LV Leitung. + if($this->config->item('fbl') === TRUE) + { + $result = $this->anrechnunglib->getFachbereichleitung($anrechnung_id); + } + else + { + // If LV Leitung is not present, gets all LV lectors. + $result = $this->anrechnunglib->getLectors($anrechnung_id); + } - // Get full name of LV Leitung. - // If LV Leitung is not present, get full name of LV lectors. - $lector_arr = $this->anrechnunglib->getLectors($item['anrechnung_id']); - $empfehlungsanfrage_an = !isEmptyArray($lector_arr) - ? implode(', ', array_column($lector_arr, 'fullname')) - : ''; + $empfehlungsanfrage_an = !isEmptyArray($result) ? implode(', ', array_column($result, 'fullname')) : ''; // Request Recommendation if($this->anrechnunglib->requestRecommendation($item['anrechnung_id'])) diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php index 9eb0c9734..b6bae4b32 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php @@ -28,6 +28,9 @@ class approveAnrechnungUebersicht extends Auth_Controller ) ); + // Load configs + $this->load->config('anrechnung'); + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel'); @@ -207,14 +210,20 @@ class approveAnrechnungUebersicht extends Auth_Controller // Request Recommendation if($this->anrechnunglib->requestRecommendation($item['anrechnung_id'])) { - // Get full name of LV Leitung. - // If LV Leitung is not present, get full name of LV lectors. - $lector_arr = $this->anrechnunglib->getLectors($item['anrechnung_id']); - $empfehlungsanfrage_an = !isEmptyArray($lector_arr) - ? implode(', ', array_column($lector_arr, 'fullname')) - : ''; + // Get full name of Fachbereichsleitung or LV Leitung. + if($this->config->item('fbl') === TRUE) + { + $result = $this->anrechnunglib->getFachbereichleitung($item['anrechnung_id']); + } + else + { + // If LV Leitung is not present, get full name of LV lectors. + $result = $this->anrechnunglib->getLectors($item['anrechnung_id']); + } - $retval[]= array( + $empfehlungsanfrage_an = !isEmptyArray($result) ? implode(', ', array_column($result, 'fullname')) : ''; + + $retval[]= array( 'anrechnung_id' => $item['anrechnung_id'], 'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR, 'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR), From d3a1ed222c449a934761477bdafcd0ff2768c42f Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 13:40:58 +0100 Subject: [PATCH 039/439] Adapted to send mails only if config['mail'] is TRUE --- .../anrechnung/ApproveAnrechnungDetail.php | 5 +++- .../ApproveAnrechnungUebersicht.php | 7 +++-- .../anrechnung/ReviewAnrechnungDetail.php | 25 +++++++++++------ .../anrechnung/ReviewAnrechnungUebersicht.php | 27 ++++++++++++------- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php index ccdabf4e0..8bcf3ef7a 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -264,7 +264,10 @@ class approveAnrechnungDetail extends Auth_Controller * */ if (!isEmptyArray($retval)) { - self::_sendSanchoMailToLectors($retval); + if ($this->config->item('send_mail') === TRUE) + { + $this->_sendSanchoMailToLectors($anrechnung_id); + } // Output json to ajax return $this->outputJsonSuccess($retval); diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php index b6bae4b32..836e7f719 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php @@ -235,13 +235,16 @@ class approveAnrechnungUebersicht extends Auth_Controller } /** - * Send mails to lectors + * Send mails * NOTE: mails are sent at the end to ensure sending only ONE mail to each LV-Leitung or lector * even if they are required for more recommendations * */ if (!isEmptyArray($retval)) { - self::_sendSanchoMailToLectors($retval); + if ($this->config->item('send_mail') === TRUE) + { + $this->_sendSanchoMail($retval); + } } // Output json to ajax diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php index 1bd92004d..53c4bb815 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php @@ -28,6 +28,9 @@ class reviewAnrechnungDetail extends Auth_Controller ) ); + // Load configs + $this->load->config('anrechnung'); + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel'); @@ -140,10 +143,13 @@ class reviewAnrechnungDetail extends Auth_Controller * Send mails to STGL (if not present STGL, send to STGL assistance) * NOTE: mails are sent at the end to ensure sending only one mail to each STGL * */ - if (!$this->_sendSanchoMails($json, true)) - { - return $this->outputJsonError('Failed sending emails'); - } + if ($this->config->item('send_mail') === TRUE) + { + if (!$this->_sendSanchoMails($json, true)) + { + return $this->outputJsonError('Failed sending emails'); + } + } return $this->outputJsonSuccess($json); } @@ -191,10 +197,13 @@ class reviewAnrechnungDetail extends Auth_Controller if (isset($json) && !isEmptyArray($json)) { // Send mails to STGL (if not present STGL, send to STGL assistance) - if (!$this->_sendSanchoMails($json, false)) - { - return $this->outputJsonError('Failed sending emails'); - } + if ($this->config->item('send_mail') === TRUE) + { + if (!$this->_sendSanchoMails($json, false)) + { + return $this->outputJsonError('Failed sending emails'); + } + } return $this->outputJsonSuccess($json); } diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php index c63d0af69..74d13698a 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php @@ -26,6 +26,9 @@ class reviewAnrechnungUebersicht extends Auth_Controller ) ); + // Load configs + $this->load->config('anrechnung'); + // Load models $this->load->model('education/Anrechnung_model', 'AnrechnungModel'); $this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel'); @@ -111,16 +114,19 @@ class reviewAnrechnungUebersicht extends Auth_Controller * Send mails to STGL (if not present STGL, send to STGL assistance) * NOTE: mails are sent at the end to ensure sending only one mail to each STGL * */ - if (!$this->_sendSanchoMails($json, true)) - { - show_error('Failed sending emails'); - } + if ($this->config->item('send_mail') === TRUE) + { + if (!$this->_sendSanchoMails($json, true)) + { + show_error('Failed sending emails'); + } + } return $this->outputJsonSuccess($json); } else { - return $this->outputJsonError($this->p->t('ui', 'errorNichtAusgefuehrt')); + $this->terminateWithJsonError($this->p->t('ui', 'errorNichtAusgefuehrt')); } } @@ -154,10 +160,13 @@ class reviewAnrechnungUebersicht extends Auth_Controller if (isset($json) && !isEmptyArray($json)) { // Send mails to STGL (if not present STGL, send to STGL assistance) - if (!$this->_sendSanchoMails($json, false)) - { - show_error('Failed sending emails'); - } + if ($this->config->item('send_mail') === TRUE) + { + if (!$this->_sendSanchoMails($json, false)) + { + show_error('Failed sending emails'); + } + } return $this->outputJsonSuccess($json); } From e148d8c2f48a25f8da6a00ff099ab04b9f9b170d Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 13:49:23 +0100 Subject: [PATCH 040/439] Added function to get Fachbereich as mail receivers --- .../anrechnung/ApproveAnrechnungDetail.php | 30 +++++++--- .../ApproveAnrechnungUebersicht.php | 57 +++++++++++++++---- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php index 8bcf3ef7a..bc5f19bd8 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -496,18 +496,24 @@ class approveAnrechnungDetail extends Auth_Controller /** - * Get lectors (prio for LV-Leitung, if not present to all lectors of LV. + * Get mail receivers. + * If config is default (lectors): prio for LV-Leitung, if not present to all lectors of LV. * Anyway this function will receive a unique array to avoid sending more mails to one and the same lector. * **/ - $lector_arr = $this->_getLectors($anrechnung_arr); + if ($this->config->item('fbl') === TRUE) + { + $receiver_arr = $this->_getFachbereichleitung($lehrveranstaltung_id); + } + else + { + $receiver_arr = $this->_getLectors($studiensemester_kurzbz, $lehrveranstaltung_id); + } - - - // Send mail to lectors - foreach ($lector_arr as $lector) + // Send mail + foreach ($receiver_arr as $receiver) { - $to = $lector->uid; - $vorname = $lector->vorname; + $to = $receiver->uid. '@'. DOMAIN;; + $vorname = $receiver->vorname; // Get full name of stgl $this->load->model('person/Person_model', 'PersonModel'); @@ -592,6 +598,14 @@ class approveAnrechnungDetail extends Auth_Controller } + // Get Fachbereichsleitungen + private function _getFachbereichleitung($lehrveranstaltung_id) + { + $result = $this->LehrveranstaltungModel->getFachbereichByLv($lehrveranstaltung_id); + + return hasData($result) ? getData($result) : show_error('Failed retrieving Fachbereichsleitung'); + } + private function _saveEmpfehlungsNotiz($anrechnung_id, $empfehlungstext, $notiz_id) { $this->load->model('person/Notiz_model', 'NotizModel'); diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php index 836e7f719..c647138c9 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php @@ -328,7 +328,7 @@ class approveAnrechnungUebersicht extends Auth_Controller * @param $mail_params * @return bool */ - private function _sendSanchoMailToLectors($mail_params) + private function _sendSanchoMail($mail_params) { // Get Lehrveranstaltungen $anrechnung_arr = array(); @@ -344,18 +344,25 @@ class approveAnrechnungUebersicht extends Auth_Controller $anrechnung_arr = array_unique($anrechnung_arr, SORT_REGULAR); - - /** - * Get lectors (prio for LV-Leitung, if not present to all lectors of LV. - * Anyway this function will receive a unique array to avoid sending more mails to one and the same lector. - * **/ - $lector_arr = $this->_getLectors($anrechnung_arr); + /** + * Get mail receivers. + * If retrieving lectors: prio for LV-Leitung, if not present to all lectors of LV. + * This function will receive a unique array to avoid sending more mails to one and the same user. + **/ + if($this->config->item('fbl') === TRUE) + { + $receiver_arr = $this->_getFachbereichleitung($anrechnung_arr); + } + else + { + $receiver_arr = $this->_getLectors($anrechnung_arr); + } // Send mail to lectors - foreach ($lector_arr as $lector) + foreach ($receiver_arr as $receiver) { - $to = $lector->uid; - $vorname = $lector->vorname; + $to = $receiver->uid. '@'. DOMAIN; + $vorname = $receiver->vorname; // Get full name of stgl $this->load->model('person/Person_model', 'PersonModel'); @@ -439,4 +446,34 @@ class approveAnrechnungUebersicht extends Auth_Controller return $lector_arr; } + + /** + * Get Fachbereichsleitung with unique uids. + * + * @param $anrechnung_arr + * @return array + */ + private function _getFachbereichleitung($anrechnung_arr) + { + $fbl_arr = array(); + + // Get lectors + foreach($anrechnung_arr as $anrechnung) + { + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + $result = $this->LehrveranstaltungModel->getFachbereichByLv($anrechnung['lehrveranstaltung_id']); + + if (!hasData($result)) + { + show_error('No Fachbereichsleitung found'); + } + + $fbl_arr = array_merge($fbl_arr, getData($result)); + } + + // Make Fachbereichsleiter array unique + $fbl_arr = array_unique($fbl_arr, SORT_REGULAR); + + return $fbl_arr; + } } From 21060b31dc07b03fb108614a3e30049a6edd904f Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 13:59:28 +0100 Subject: [PATCH 041/439] Bugfixed error message when LV has no lectors and only one recommendation is requested --- .../anrechnung/ApproveAnrechnungDetail.php | 19 ++++++++----------- .../ApproveAnrechnungUebersicht.php | 9 +++++++-- .../anrechnung/approveAnrechnungUebersicht.js | 8 ++++---- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php index bc5f19bd8..3f8f67639 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -220,15 +220,12 @@ class approveAnrechnungDetail extends Auth_Controller } $retval = array(); - $counter = 0; - - foreach ($data as $item) - { - // Check if Anrechnungs-LV has lector - if (!$this->anrechnunglib->LVhasLector($item['anrechnung_id'])) - { - // Count up LV with no lector - $counter++; + + // Check if Anrechnungs-LV has lector + if (!$this->anrechnunglib->LVhasLector($anrechnung_id)) + { + $this->terminateWithJsonError('LV has no lector'); + } // Get Fachbereichsleitung or LV Leitung. if($this->config->item('fbl') === TRUE) @@ -274,9 +271,9 @@ class approveAnrechnungDetail extends Auth_Controller } // Output json to ajax - if (isEmptyArray($retval) && $counter > 0) + if (isEmptyArray($retval)) { - return $this->outputJsonError( + $this->terminateWithJsonError( "Empfehlung wurde nicht angefordert,\nDer LV sind keine LektorInnen zugeteilt." ); } diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php index c647138c9..77ee5bb40 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php @@ -248,9 +248,14 @@ class approveAnrechnungUebersicht extends Auth_Controller } // Output json to ajax - if (isEmptyArray($retval) && $counter == 0) + if (isEmptyArray($retval)) { - return $this->outputJsonError('Es wurden keine Empfehlungen angefordert'); + if ($counter > 0) + { + $this->terminateWithJsonError('Bei '. $counter.' LV sind keine LektorInnen zugeteilt.'); + } + + $this->terminateWithJsonError('Es wurden keine Empfehlungen angefordert'); } return $this->outputJsonSuccess($retval); diff --git a/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js b/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js index e831856d8..0198bfb26 100644 --- a/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js +++ b/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js @@ -603,14 +603,14 @@ $(function(){ // Print success message FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "empfehlungWurdeAngefordert")); } - } //Update status 'genehmigt' $('#tableWidgetTabulator').tabulator('updateData', data); - // Deselect rows - var indexesToDeselect = data.map(x => x.anrechnung_id); - $("#tableWidgetTabulator").tabulator('deselectRow', indexesToDeselect); + // Deselect rows + var indexesToDeselect = data.map(x => x.anrechnung_id); + $("#tableWidgetTabulator").tabulator('deselectRow', indexesToDeselect); + } }, errorCallback: function (jqXHR, textStatus, errorThrown) { From 8735318545cfc070377b7a005643658c0738d443 Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 14:03:22 +0100 Subject: [PATCH 042/439] Enhanced code readability --- .../anrechnung/ApproveAnrechnungDetail.php | 119 ++++++++---------- .../anrechnung/ReviewAnrechnungUebersicht.php | 4 +- .../anrechnung/approveAnrechnungDetail.js | 10 +- .../anrechnung/approveAnrechnungUebersicht.js | 19 +-- 4 files changed, 57 insertions(+), 95 deletions(-) diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php index 3f8f67639..6c03aeb07 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungDetail.php @@ -212,9 +212,9 @@ class approveAnrechnungDetail extends Auth_Controller */ public function requestRecommendation() { - $data = $this->input->post('data'); + $anrechnung_id = $this->input->post('anrechnung_id'); - if(isEmptyArray($data)) + if(isEmptyString($anrechnung_id)) { return $this->outputJsonError('Fehler beim Übertragen der Daten.'); } @@ -227,32 +227,31 @@ class approveAnrechnungDetail extends Auth_Controller $this->terminateWithJsonError('LV has no lector'); } - // Get Fachbereichsleitung or LV Leitung. - if($this->config->item('fbl') === TRUE) - { - $result = $this->anrechnunglib->getFachbereichleitung($anrechnung_id); - } - else - { - // If LV Leitung is not present, gets all LV lectors. - $result = $this->anrechnunglib->getLectors($anrechnung_id); - } + // Get Fachbereichsleitung or LV Leitung. + if($this->config->item('fbl') === TRUE) + { + $result = $this->anrechnunglib->getFachbereichleitung($anrechnung_id); + } + else + { + // If LV Leitung is not present, gets all LV lectors. + $result = $this->anrechnunglib->getLectors($anrechnung_id); + } - $empfehlungsanfrage_an = !isEmptyArray($result) ? implode(', ', array_column($result, 'fullname')) : ''; + $empfehlungsanfrage_an = !isEmptyArray($result) ? implode(', ', array_column($result, 'fullname')) : ''; - // Request Recommendation - if($this->anrechnunglib->requestRecommendation($item['anrechnung_id'])) - { - $retval[]= array( - 'anrechnung_id' => $item['anrechnung_id'], - 'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR, - 'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR), - 'empfehlung_anrechnung' => null, - 'empfehlungsanfrageAm' => (new DateTime())->format('d.m.Y'), - 'empfehlungsanfrageAn' => $empfehlungsanfrage_an - ); - } - } + // Request Recommendation + if($this->anrechnunglib->requestRecommendation($anrechnung_id)) + { + $retval[]= array( + 'anrechnung_id' => $anrechnung_id, + 'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR, + 'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR), + 'empfehlung_anrechnung' => null, + 'empfehlungsanfrageAm' => (new DateTime())->format('d.m.Y'), + 'empfehlungsanfrageAn' => $empfehlungsanfrage_an + ); + } /** * Send mails to lectors @@ -278,7 +277,7 @@ class approveAnrechnungDetail extends Auth_Controller ); } - return $this->outputJsonError($this->p->t('ui', 'errorNichtAusgefuehrt')); + $this->terminateWithJsonError($this->p->t('ui', 'errorNichtAusgefuehrt')); } /** @@ -472,25 +471,13 @@ class approveAnrechnungDetail extends Auth_Controller /** * Send mail to lectors asking for recommendation. (first to LV-Leitung, if not present to all lectors of lv) - * @param $mail_params + * @param $anrechnung_id * @return bool */ - private function _sendSanchoMailToLectors($mail_params) + private function _sendSanchoMailToLectors($anrechnung_id) { - // Get Lehrveranstaltungen - $anrechnung_arr = array(); - - foreach ($mail_params as $item) - { - $this->AnrechnungModel->addSelect('lehrveranstaltung_id, studiensemester_kurzbz'); - $anrechnung_arr[]= array( - 'lehrveranstaltung_id' => $this->AnrechnungModel->load($item['anrechnung_id'])->retval[0]->lehrveranstaltung_id, - 'studiensemester_kurzbz' => $this->AnrechnungModel->load($item['anrechnung_id'])->retval[0]->studiensemester_kurzbz - ); - } - - $anrechnung_arr = array_unique($anrechnung_arr, SORT_REGULAR); - + $lehrveranstaltung_id = $this->AnrechnungModel->load($anrechnung_id)->retval[0]->lehrveranstaltung_id; + $studiensemester_kurzbz = $this->AnrechnungModel->load($anrechnung_id)->retval[0]->studiensemester_kurzbz; /** * Get mail receivers. @@ -548,35 +535,30 @@ class approveAnrechnungDetail extends Auth_Controller * @param $anrechnung_arr * @return array */ - private function _getLectors($anrechnung_arr) + private function _getLectors($studiensemester_kurzbz, $lehrveranstaltung_id) { $lector_arr = array(); - // Get lectors - foreach($anrechnung_arr as $anrechnung) - { - $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); - $result = $this->LehrveranstaltungModel->getLecturersByLv($anrechnung['studiensemester_kurzbz'], $anrechnung['lehrveranstaltung_id']); + $result = $this->LehrveranstaltungModel->getLecturersByLv($studiensemester_kurzbz, $lehrveranstaltung_id); - if (!$result = getData($result)) - { - show_error('Failed retrieving lectors of Lehrveranstaltung'); - } + if (!$result = getData($result)) + { + show_error('Failed retrieving lectors of Lehrveranstaltung'); + } - // Check if lv has LV-Leitung - $key = array_search(true, array_column($result, 'lvleiter')); + // Check if lv has LV-Leitung + $key = array_search(true, array_column($result, 'lvleiter')); - // If lv has LV-Leitung, keep only the one - if ($key !== false) - { - $lector_arr[]= $result[$key]; - } - // ...otherwise keep all lectors - else - { - $lector_arr = array_merge($lector_arr, $result); - } - } + // If lv has LV-Leitung, keep only the one + if ($key !== false) + { + $lector_arr[]= $result[$key]; + } + // ...otherwise keep all lectors + else + { + $lector_arr = array_merge($lector_arr, $result); + } /** * NOTE: This step is only done to make the array unique by uid, vorname and nachname in the following step @@ -625,8 +607,5 @@ class approveAnrechnungDetail extends Auth_Controller trim($empfehlungstext), $this->_uid ); - - } - -} +} \ No newline at end of file diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php index 74d13698a..3ea7e4075 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php @@ -231,9 +231,9 @@ class reviewAnrechnungUebersicht extends Auth_Controller if($result = getData($result)) { - $entitled_lector_arr = array_column($result, 'uid'); + $entitled_uid_arr = array_column($result, 'uid'); - if (in_array($this->_uid, $entitled_lector_arr)) + if (in_array($this->_uid, $entitled_uid_arr)) { return; } diff --git a/public/js/lehre/anrechnung/approveAnrechnungDetail.js b/public/js/lehre/anrechnung/approveAnrechnungDetail.js index 3a91f4e3a..0bd92277a 100644 --- a/public/js/lehre/anrechnung/approveAnrechnungDetail.js +++ b/public/js/lehre/anrechnung/approveAnrechnungDetail.js @@ -194,17 +194,9 @@ $(function(){ // Get form data let form_data = $('#form-empfehlung').serializeArray(); - - // Prepare data object for ajax call - let data = { - 'data': [{ - 'anrechnung_id' : form_data[0].value - }] - }; - FHC_AjaxClient.ajaxCallPost( FHC_JS_DATA_STORAGE_OBJECT.called_path + "/requestRecommendation", - data, + {anrechnung_id: form_data[0].value}, { successCallback: function (data, textStatus, jqXHR) { diff --git a/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js b/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js index 0198bfb26..889316155 100644 --- a/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js +++ b/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js @@ -556,12 +556,8 @@ $(function(){ } } - selected_data.map(function(data){ - // reduce to necessary fields - return { - 'anrechnung_id' : data.anrechnung_id, - } - }); + // Reduce to necessary fields + selected_data = selected_data.map(data => ({'anrechnung_id' : data.anrechnung_id})); // Alert and exit if no anrechnung is selected if (selected_data.length == 0) @@ -570,14 +566,9 @@ $(function(){ return; } - // Prepare data object for ajax call - let data = { - 'data': selected_data - }; - FHC_AjaxClient.ajaxCallPost( FHC_JS_DATA_STORAGE_OBJECT.called_path + "/requestRecommendation", - data, + {data: selected_data}, { successCallback: function (data, textStatus, jqXHR) { @@ -604,8 +595,8 @@ $(function(){ FHC_DialogLib.alertSuccess(FHC_PhrasesLib.t("ui", "empfehlungWurdeAngefordert")); } - //Update status 'genehmigt' - $('#tableWidgetTabulator').tabulator('updateData', data); + //Update status 'genehmigt' + $('#tableWidgetTabulator').tabulator('updateData', data); // Deselect rows var indexesToDeselect = data.map(x => x.anrechnung_id); From c3e3d8e9d71349f7e51b311d8359b415ee4819dc Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 14:05:42 +0100 Subject: [PATCH 043/439] Added Fachbereichsleitung permission check to read Anrechnung and download Document --- .../anrechnung/ReviewAnrechnungDetail.php | 20 +++++++++++++++---- .../anrechnung/ReviewAnrechnungUebersicht.php | 10 ++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php index 53c4bb815..63b83df11 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php @@ -262,8 +262,14 @@ class reviewAnrechnungDetail extends Auth_Controller show_error('Failed retrieving Anrechnung'); } - $result = $this->LehrveranstaltungModel - ->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + if($this->config->item('fbl') === TRUE) + { + $result = $this->LehrveranstaltungModel->getFachbereichByLv($result->lehrveranstaltung_id); + } + else + { + $result = $this->LehrveranstaltungModel->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + } if($result = getData($result)) { @@ -291,8 +297,14 @@ class reviewAnrechnungDetail extends Auth_Controller show_error('Failed retrieving Anrechnung'); } - $result = $this->LehrveranstaltungModel - ->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + if($this->config->item('fbl') === TRUE) + { + $result = $this->LehrveranstaltungModel->getFachbereichByLv($result->lehrveranstaltung_id); + } + else + { + $result = $this->LehrveranstaltungModel->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + } if($result = getData($result)) { diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php index 3ea7e4075..77dfeeb57 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungUebersicht.php @@ -226,8 +226,14 @@ class reviewAnrechnungUebersicht extends Auth_Controller show_error('Failed retrieving Anrechnung'); } - $result = $this->LehrveranstaltungModel - ->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + if ($this->config->item('fbl') === TRUE) + { + $result = $this->LehrveranstaltungModel->getFachbereichByLv($result->lehrveranstaltung_id); + } + else + { + $result = $this->LehrveranstaltungModel->getLecturersByLv($result->studiensemester_kurzbz, $result->lehrveranstaltung_id); + } if($result = getData($result)) { From 32bdeec02eff38f57671de56d54b8f6b2fbcca90 Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 15:49:04 +0100 Subject: [PATCH 044/439] Added date check for Fachbereichsleitung in Tabulator query --- .../lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php index a20d85f9f..f586e428d 100644 --- a/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php +++ b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php @@ -62,6 +62,8 @@ JOIN public.tbl_benutzerfunktion bf using (oe_kurzbz) /*AND lema.mitarbeiter_uid = \'' . $LEKTOR_UID . '\'*/ AND le.lehre = TRUE AND bf.funktion_kurzbz = \'Leitung\' +and bf.datum_von <= now() +and (bf.datum_bis >= now() or bf.datum_bis is null) AND og.organisationseinheittyp_kurzbz = \'Fachbereich\' AND bf.uid = \'' . $LEKTOR_UID . '\' AND EXISTS ( From 40c7e1c9f0e206b13ef7d7435071fb069eb6ddd9 Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 15:52:30 +0100 Subject: [PATCH 045/439] Created new Approve Anrechnung Uebersicht for Fachbereichsleitung --- .../approveAnrechnungUebersichtData_fbl.php | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 application/views/lehre/anrechnung/approveAnrechnungUebersichtData_fbl.php diff --git a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData_fbl.php b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData_fbl.php new file mode 100644 index 000000000..08d7638fc --- /dev/null +++ b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData_fbl.php @@ -0,0 +1,235 @@ +>' . $LANGUAGE_INDEX . ', + array_to_json(zgv.bezeichnung::varchar[])->>' . $LANGUAGE_INDEX . ' + ) AS zgv + FROM public.tbl_prestudent + LEFT JOIN bis.tbl_zgv zgv USING (zgv_code) + LEFT JOIN bis.tbl_zgvmaster zgvmaster USING (zgvmas_code) + WHERE prestudent_id = anrechnung.prestudent_id + ) AS zgv, + anrechnung.insertamum::date AS "antragsdatum", + empfehlung_anrechnung, + (SELECT status_kurzbz + FROM lehre.tbl_anrechnungstatus + JOIN lehre.tbl_anrechnung_anrechnungstatus USING (status_kurzbz) + WHERE anrechnung_id = anrechnung.anrechnung_id + ORDER BY insertamum DESC + LIMIT 1 + ) AS status_kurzbz, + student.student_uid, + anrechnung.prestudent_id + FROM lehre.tbl_anrechnung AS anrechnung + JOIN public.tbl_prestudent USING (prestudent_id) + JOIN public.tbl_person AS person USING (person_id) + JOIN public.tbl_studiengang AS stg USING (studiengang_kz) + JOIN lehre.tbl_lehrveranstaltung AS lv USING (lehrveranstaltung_id) + LEFT JOIN campus.tbl_dms_version AS dmsversion USING (dms_id) + JOIN lehre.tbl_anrechnung_anrechnungstatus USING (anrechnung_id) + JOIN lehre.tbl_anrechnung_begruendung AS begruendung USING (begruendung_id) + JOIN public.tbl_student student USING (prestudent_id) + WHERE anrechnung.studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' + AND stg.studiengang_kz IN (' . $STUDIENGAENGE_ENTITLED . ') + ) + + SELECT anrechnungen.anrechnung_id, + anrechnungen.lehrveranstaltung_id, + anrechnungen.begruendung_id, + anrechnungen.dms_id, + anrechnungen.studiensemester_kurzbz, + anrechnungen.studiengang_kz, + anrechnungen.stg_bezeichnung, + anrechnungen.orgform_kurzbz, + anrechnungen.ausbildungssemester, + anrechnungen.lv_bezeichnung, + anrechnungen.ects::float4 AS ects, + NULL AS "ectsSumBisherUndNeu", + anrechnungen.ectsSumSchulisch::float4 AS "ectsSumSchulisch", + anrechnungen.ectsSumBeruflich::float4 AS "ectsSumBeruflich", + anrechnungen.begruendung, + anrechnungen.student, + anrechnungen.dokument_bezeichnung, + anrechnungen.anmerkung_student, + anrechnungen.zgv, + anrechnungen.antragsdatum, + anrechnungen.empfehlung_anrechnung, + anrechnungen.status_kurzbz, + array_to_json(anrechnungstatus.bezeichnung_mehrsprachig::varchar[])->>' . $LANGUAGE_INDEX . ' AS "status_bezeichnung", + anrechnungen.prestudent_id, + CASE + WHEN (anrechnungen.empfehlung_anrechnung IS NULL AND anrechnungen.status_kurzbz = \'' . ANRECHNUNGSTATUS_PROGRESSED_BY_STGL . '\') THEN NULL + ELSE + (SELECT insertamum::date + FROM lehre.tbl_anrechnungstatus + JOIN lehre.tbl_anrechnung_anrechnungstatus USING (status_kurzbz) + WHERE anrechnung_id = anrechnungen.anrechnung_id + AND status_kurzbz = \'' . ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR . '\' + ORDER BY insertamum DESC + LIMIT 1) + END "empfehlungsanfrageAm", + CASE + WHEN (anrechnungen.empfehlung_anrechnung IS NULL AND anrechnungen.status_kurzbz = \'' . ANRECHNUNGSTATUS_PROGRESSED_BY_STGL . '\') THEN NULL + ELSE + (SELECT COALESCE( + STRING_AGG(CONCAT_WS(\' \', vorname, nachname), \', \') + ) empfehlungsanfrageAn + FROM ( + SELECT DISTINCT ON (benutzer.uid) bf.uid, vorname, nachname + FROM lehre.tbl_lehreinheit + JOIN lehre.tbl_lehrveranstaltung lv using (lehrveranstaltung_id) + JOIN public.tbl_organisationseinheit og using (oe_kurzbz) + JOIN public.tbl_benutzerfunktion bf using (oe_kurzbz) + JOIN public.tbl_benutzer benutzer ON bf.uid = benutzer.uid + JOIN public.tbl_person USING (person_id) + WHERE studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' + and bf.datum_von <= now() + and (bf.datum_bis >= now() or bf.datum_bis is null) + AND lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id + AND benutzer.aktiv = TRUE + AND tbl_person.aktiv = TRUE + ORDER BY benutzer.uid, nachname, vorname + ) as tmp_lvlektoren + ) + END "empfehlungsanfrageAn" + FROM anrechnungen + JOIN lehre.tbl_anrechnungstatus as anrechnungstatus ON (anrechnungstatus.status_kurzbz = anrechnungen.status_kurzbz) + WHERE studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' + AND studiengang_kz IN (' . $STUDIENGAENGE_ENTITLED . ') +'; + +$filterWidgetArray = array( + 'query' => $query, + 'tableUniqueId' => 'approveAnrechnungUebersicht', + 'requiredPermissions' => 'lehre/anrechnung_genehmigen', + 'datasetRepresentation' => 'tabulator', + 'columnsAliases' => array( + 'anrechnung_id', + 'lehrveranstaltung_id', + 'begruendung_id', + 'dms_id', + 'studiensemester_kurzbz', + 'studiengang_kz', + ucfirst($this->p->t('lehre', 'studiengang')), + ucfirst($this->p->t('lehre', 'organisationsform')), + 'Semester', + ucfirst($this->p->t('lehre', 'lehrveranstaltung')), + 'ECTS (LV)', + 'ECTS (LV + Bisher)', + 'ECTS (Bisher schulisch)', + 'ECTS (Bisher beruflich', + ucfirst($this->p->t('global', 'begruendung')), + ucfirst($this->p->t('person', 'studentIn')), + ucfirst($this->p->t('anrechnung', 'nachweisdokumente')), + ucfirst($this->p->t('anrechnung', 'herkunft')), + ucfirst($this->p->t('global', 'zgv')), + ucfirst($this->p->t('anrechnung', 'antragdatum')), + ucfirst($this->p->t('anrechnung', 'empfehlung')), + 'status_kurzbz', + 'Status', + 'PrestudentID', + ucfirst($this->p->t('anrechnung', 'empfehlungsanfrageAm')), + ucfirst($this->p->t('anrechnung', 'empfehlungsanfrageAn')) + ), + 'datasetRepOptions' => '{ + height: func_height(this), + layout: "fitColumns", // fit columns to width of table + persistentLayout:true, + persistentSort:true, + persistentFilter:true, + autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated + headerFilterPlaceholder: " ", + index: "anrechnung_id", // assign specific column as unique id (important for row indexing) + selectable: true, // allow row selection + selectableRangeMode: "click", // allow range selection using shift end click on end of range + selectablePersistence:false, // deselect previously selected rows when table is filtered, sorted or paginated + tableBuilt: function(){ + func_tableBuilt(this); + }, + tableWidgetFooter: { + selectButtons: true + }, + selectableCheck: function(row){ + return func_selectableCheck(row); + }, + rowFormatter:function(row){ + func_rowFormatter(row); + }, + rowSelectionChanged:function(data, rows){ + func_rowSelectionChanged(data, rows); + }, + tooltips: function(cell){ + return func_tooltips(cell); + } + }', // tabulator properties + 'datasetRepFieldsDefs' => '{ + anrechnung_id: {visible: false, headerFilter:"input"}, + lehrveranstaltung_id: {visible: false, headerFilter:"input"}, + begruendung_id: {visible: false, headerFilter:"input"}, + dms_id: {visible: false, headerFilter:"input"}, + studiensemester_kurzbz: {visible: false, headerFilter:"input"}, + studiengang_kz: {visible: false, headerFilter:"input"}, + stg_bezeichnung: {headerFilter:"input"}, + orgform_kurzbz: {headerFilter:"input"}, + ausbildungssemester: {headerFilter:"input"}, + lv_bezeichnung: {headerFilter:"input"}, + ects: {headerFilter:"input", align:"center"}, + ectsSumBisherUndNeu: {formatter: format_ectsSumBisherUndNeu}, + ectsSumSchulisch: {visible: false, headerFilter:"input", align:"right"}, + ectsSumBeruflich: {visible: false, headerFilter:"input", align:"right"}, + begruendung: {headerFilter:"input", visible: true}, + student: {headerFilter:"input"}, + zgv: {visible: false, headerFilter:"input"}, + dokument_bezeichnung: {headerFilter:"input", formatter:"link", formatterParams:{ + labelField:"dokument_bezeichnung", + url:function(cell){return "'. current_url() .'/download?dms_id=" + cell.getData().dms_id}, + target:"_blank" + }}, + anmerkung_student: {headerFilter:"input"}, + antragsdatum: {align:"center", headerFilter:"input", mutator: mut_formatStringDate}, + empfehlung_anrechnung: {headerFilter:"input", align:"center", formatter: format_empfehlung_anrechnung, headerFilterFunc: hf_filterTrueFalse}, + status_kurzbz: {visible: false, headerFilter:"input"}, + status_bezeichnung: {headerFilter:"input"}, + prestudent_id: {visible: false, headerFilter:"input"}, + empfehlungsanfrageAm: {visible: false, align:"center", headerFilter:"input", mutator: mut_formatStringDate}, + empfehlungsanfrageAn: {visible: false, headerFilter:"input"} + }', // col properties +); + +echo $this->widgetlib->widget('TableWidget', $filterWidgetArray); + +?> From 8d221be0505c695a9920014c19780508d384575a Mon Sep 17 00:00:00 2001 From: Cris Date: Tue, 6 Dec 2022 15:53:15 +0100 Subject: [PATCH 046/439] Adapt view to use Fachbereichsleitung-DataView --- .../lehre/anrechnung/approveAnrechnungUebersicht.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php b/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php index f5d1e8214..34cb6b998 100644 --- a/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php +++ b/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php @@ -124,7 +124,14 @@ $this->load->view(
- load->view('lehre/anrechnung/approveAnrechnungUebersichtData.php'); ?> + load->config('anrechnung'); + if ($this->config->item('fbl') === TRUE) + $this->load->view('lehre/anrechnung/approveAnrechnungUebersichtData_fbl.php'); + else + $this->load->view('lehre/anrechnung/approveAnrechnungUebersichtData.php'); + ?>
From d9098179a25cf789e29dc29a1407445112ce4d06 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 14 Dec 2022 12:40:38 +0100 Subject: [PATCH 047/439] - ermoeglicht es master bewerber sich ueber das bewerbungstool anzumelden --- include/reihungstest.class.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/include/reihungstest.class.php b/include/reihungstest.class.php index 0140816ab..5c8e5854e 100644 --- a/include/reihungstest.class.php +++ b/include/reihungstest.class.php @@ -685,11 +685,15 @@ class reihungstest extends basis_db tbl_reihungstest.studiensemester_kurzbz, tbl_reihungstest.stufe, tbl_reihungstest.anmeldefrist, - tbl_reihungstest.aufnahmegruppe_kurzbz + tbl_reihungstest.aufnahmegruppe_kurzbz, + tbl_studiengang.typ, + tbl_studiengang.kurzbzlang FROM public.tbl_rt_person JOIN public.tbl_reihungstest ON (rt_id=reihungstest_id) + LEFT JOIN + public.tbl_studiengang ON tbl_reihungstest.studiengang_kz = tbl_studiengang.studiengang_kz WHERE tbl_rt_person.person_id=".$this->db_add_param($person_id); @@ -728,6 +732,8 @@ class reihungstest extends basis_db $obj->stufe = $row->stufe; $obj->anmeldefrist = $row->anmeldefrist; $obj->aufnahmegruppe_kurzbz = $row->aufnahmegruppe_kurzbz; + $obj->typ = $row->typ; + $obj->kurzbzlang = $row->kurzbzlang; $this->result[] = $obj; } From ed99325bb933d7fee02fffc50014d28f287f8d01 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Tue, 10 Jan 2023 09:04:53 +0100 Subject: [PATCH 048/439] - anpassungen fuer master bewerbungen --- include/reihungstest.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/reihungstest.class.php b/include/reihungstest.class.php index 5c8e5854e..42af8ea7a 100644 --- a/include/reihungstest.class.php +++ b/include/reihungstest.class.php @@ -687,7 +687,7 @@ class reihungstest extends basis_db tbl_reihungstest.anmeldefrist, tbl_reihungstest.aufnahmegruppe_kurzbz, tbl_studiengang.typ, - tbl_studiengang.kurzbzlang + UPPER(typ::varchar(1) || kurzbz) AS stg_kuerzel FROM public.tbl_rt_person JOIN @@ -733,7 +733,7 @@ class reihungstest extends basis_db $obj->anmeldefrist = $row->anmeldefrist; $obj->aufnahmegruppe_kurzbz = $row->aufnahmegruppe_kurzbz; $obj->typ = $row->typ; - $obj->kurzbzlang = $row->kurzbzlang; + $obj->stg_kuerzel = $row->stg_kuerzel; $this->result[] = $obj; } From 29f1760a7c6573e27781125af8d1f60372d71a1e Mon Sep 17 00:00:00 2001 From: Cris Date: Wed, 11 Jan 2023 13:45:18 +0100 Subject: [PATCH 049/439] =?UTF-8?q?Added:=20LektorInnen=20sehen=20jetzt=20?= =?UTF-8?q?nur=20Anrechnungen,=20f=C3=BCr=20die=20sie=20eine=20Empfehlung?= =?UTF-8?q?=20abgeben=20d=C3=BCrfen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Es gibt eine neue Spalte 'empfehlungsberechtigt' in der Anrechnungentabelle. Defaultmäßig werden nur 'empfehlungsberechtigt' Anrechnungen angezeigt, wo LektorIn: - LV Leitung der LV ist ODER - die LV keine LV-Leitung hat Über den Filter können aber auch alle angezeigt werden. --- .../reviewAnrechnungUebersichtData.php | 41 ++++++++++++++++--- .../anrechnung/reviewAnrechnungUebersicht.js | 12 +++++- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php index d48018171..aa28d7fc0 100644 --- a/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php +++ b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php @@ -46,16 +46,40 @@ $query = ' LEFT JOIN campus.tbl_dms_version AS dmsversion USING (dms_id) JOIN lehre.tbl_anrechnung_anrechnungstatus USING (anrechnung_id) JOIN lehre.tbl_anrechnung_begruendung AS begruendung USING (begruendung_id) - ) + WHERE studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' + ), + tbl_lvleitungen AS + ( + SELECT DISTINCT ON (benutzer.uid, lehrveranstaltung_id) lehrveranstaltung_id, uid, + CASE WHEN lehrfunktion_kurzbz = \'LV-Leitung\' THEN TRUE + ELSE FALSE + END AS lvleiter + FROM lehre.tbl_lehreinheit + JOIN lehre.tbl_lehreinheitmitarbeiter lema USING (lehreinheit_id) + JOIN public.tbl_benutzer benutzer ON lema.mitarbeiter_uid = benutzer.uid + JOIN public.tbl_person USING (person_id) + JOIN lehre.tbl_anrechnung USING (lehrveranstaltung_id) + WHERE tbl_lehreinheit.studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' + AND benutzer.aktiv = TRUE + AND tbl_person.aktiv = TRUE + ORDER BY lehrveranstaltung_id, benutzer.uid, lehrfunktion_kurzbz DESC + ) SELECT DISTINCT ON (anrechnungen.*, lema.mitarbeiter_uid) anrechnungen.*, - array_to_json(anrechnungstatus.bezeichnung_mehrsprachig::varchar[])->>' . $LANGUAGE_INDEX . ' AS "status_bezeichnung" + array_to_json(anrechnungstatus.bezeichnung_mehrsprachig::varchar[])->>' . $LANGUAGE_INDEX . ' AS "status_bezeichnung", + CASE + -- erst prüfen, ob es überhaupt eine LV Leitung gibt (wenn nicht, dann immer empfehlungsberechtigt) + WHEN EXISTS (SELECT 1 FROM tbl_lvleitungen WHERE lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id AND lvleiter = TRUE) + -- wenn ja, return true, wenn user LV Leitung ist oder false, wenn nicht + THEN (SELECT EXISTS (SELECT 1 FROM tbl_lvleitungen WHERE lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id AND lvleiter = TRUE AND uid = \'' . $LEKTOR_UID . '\')) + -- wenn es keine LV Leitung, return immer true + ELSE TRUE + END AS empfehlungsberechtigt FROM anrechnungen JOIN lehre.tbl_anrechnungstatus as anrechnungstatus ON (anrechnungstatus.status_kurzbz = anrechnungen.status_kurzbz) JOIN lehre.tbl_lehreinheit le USING (lehrveranstaltung_id) JOIN lehre.tbl_lehreinheitmitarbeiter lema USING (lehreinheit_id) - WHERE anrechnungen.studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' - AND le.studiensemester_kurzbz = anrechnungen.studiensemester_kurzbz + WHERE le.studiensemester_kurzbz = anrechnungen.studiensemester_kurzbz AND lema.mitarbeiter_uid = \'' . $LEKTOR_UID . '\' AND le.lehre = TRUE AND EXISTS ( @@ -89,7 +113,8 @@ $filterWidgetArray = array( ucfirst($this->p->t('anrechnung', 'antragdatum')), ucfirst($this->p->t('anrechnung', 'empfehlung')), 'status_kurzbz', - 'Status' + 'Status', + 'empfehlungsberechtigt' ), 'datasetRepOptions' => '{ height: func_height(this), @@ -98,6 +123,7 @@ $filterWidgetArray = array( persistentSort:true, autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated headerFilterPlaceholder: " ", + initialHeaderFilter: [{field:"empfehlungsberechtigt", value: true}], index: "anrechnung_id", // assign specific column as unique id (important for row indexing) selectable: true, // allow row selection selectableRangeMode: "click", // allow range selection using shift end click on end of range @@ -139,7 +165,10 @@ $filterWidgetArray = array( antragsdatum: {align:"center", headerFilter:"input", mutator: mut_formatStringDate}, empfehlung_anrechnung: {headerFilter:"input", align:"center", formatter: format_empfehlung_anrechnung, headerFilterFunc: hf_filterTrueFalse}, status_kurzbz: {visible: false, headerFilter:"input"}, - status_bezeichnung: {headerFilter:"input"} + status_bezeichnung: {headerFilter:"input"}, + empfehlungsberechtigt: {formatter:"tickCross", align:"center", + headerFilter:"tickCross", headerFilterParams:{"tristate": true, "initial": true}, headerFilterFunc: hf_empfehlungsberechtigt + } }', // col properties ); diff --git a/public/js/lehre/anrechnung/reviewAnrechnungUebersicht.js b/public/js/lehre/anrechnung/reviewAnrechnungUebersicht.js index 47b2a2dc5..b948ecab4 100644 --- a/public/js/lehre/anrechnung/reviewAnrechnungUebersicht.js +++ b/public/js/lehre/anrechnung/reviewAnrechnungUebersicht.js @@ -51,6 +51,12 @@ function hf_filterTrueFalse(headerValue, rowValue){ } } +// Filters empfehlungsberechtigt boolean values +function hf_empfehlungsberechtigt(headerValue, rowValue){ + + return rowValue == headerValue.toString(); +} + // Adds column details function func_tableBuilt(table) { table.addColumn( @@ -74,9 +80,10 @@ function func_tableBuilt(table) { // Formats the rows function func_rowFormatter(row){ let status_kurzbz = row.getData().status_kurzbz; + let empfehlungsberechtigt = row.getData().empfehlungsberechtigt; row.getCells().forEach(function(cell){ - if (status_kurzbz != ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR) + if (status_kurzbz != ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR || empfehlungsberechtigt == "false") { row.getElement().style["background-color"] = COLOR_LIGHTGREY; // default } @@ -86,9 +93,10 @@ function func_rowFormatter(row){ // Formats row selectable/unselectable function func_selectableCheck(row){ let status_kurzbz = row.getData().status_kurzbz; + let empfehlungsberechtigt = row.getData().empfehlungsberechtigt; return ( - status_kurzbz == ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR + status_kurzbz == ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR || empfehlungsberechtigt == "false" ); } From d1319a23ad7f608f7a4b6cb184bb2c6d145e6c10 Mon Sep 17 00:00:00 2001 From: Cris Date: Wed, 11 Jan 2023 13:47:23 +0100 Subject: [PATCH 050/439] =?UTF-8?q?Added:=20STGLs=20sehen=20jetzt=20nur=20?= =?UTF-8?q?Anrechnungen=20von=20STGs,=20f=C3=BCr=20die=20sie=20eine=20Bere?= =?UTF-8?q?chtigung=20haben?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Es gibt eine neue Spalte 'schreibberechtigt' in der Anrechnungentabelle. Defaultmäßig werden nur 'schreibberechtigte' Anrechnungen angezeigt, wo STGL die Berechtigung auf die OE hat. Über den Filter können aber auch alle angezeigt werden. --- .../ApproveAnrechnungUebersicht.php | 16 +++++++++- .../approveAnrechnungUebersichtData.php | 14 ++++++++- .../anrechnung/approveAnrechnungUebersicht.js | 29 ++++++++++++------- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php index 77ee5bb40..7e1853b47 100644 --- a/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php +++ b/application/controllers/lehre/anrechnung/ApproveAnrechnungUebersicht.php @@ -81,6 +81,19 @@ class approveAnrechnungUebersicht extends Auth_Controller show_error(getError($studiengang_kz_arr)); } + // Get oes the user is entitled for + $oe_kurzbz_arr_schreibberechtigt = array(); + if ($oe_arr = $this->permissionlib->getOE_isEntitledFor(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN)) + { + foreach($oe_arr as $oe) + { + $berechtigt = $this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN, 'suid', $oe); + + if ($berechtigt) $oe_kurzbz_arr_schreibberechtigt[]= $oe; + } + } + + // Check if permission is readonly $hasReadOnlyAccess = $this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN, 's') && !$this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN, 'suid'); @@ -90,7 +103,8 @@ class approveAnrechnungUebersicht extends Auth_Controller $viewData = array( 'studiensemester_selected' => $studiensemester_kurzbz, - 'studiengaenge_entitled' => $studiengang_kz_arr, + 'studiengaenge_entitled' => $studiengang_kz_arr, // alle STG mit Lese- und Schreibberechtigung + 'oes_schreibberechtigt' => $oe_kurzbz_arr_schreibberechtigt, // alle STG nur mit Schreibberechtigung 'hasReadOnlyAccess' => $hasReadOnlyAccess, 'hasCreateAnrechnungAccess' => $hasCreateAnrechnungAccess ); diff --git a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php index 1eade50d2..87ba57b6f 100644 --- a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php +++ b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php @@ -3,7 +3,8 @@ const ANRECHNUNGSTATUS_PROGRESSED_BY_STGL = 'inProgressDP'; const ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR = 'inProgressLektor'; $STUDIENSEMESTER = $studiensemester_selected; -$STUDIENGAENGE_ENTITLED = implode(', ', $studiengaenge_entitled); +$STUDIENGAENGE_ENTITLED = implode(', ', $studiengaenge_entitled); // alle STG mit Lese- und Schreibberechtigung +$ORGANISATIONSEINHEITEN_SCHREIBBERECHTIGT = "'". implode(', ', $oes_schreibberechtigt). "'"; // alle STG nur mit Schreibberechtigung $LANGUAGE_INDEX = getUserLanguage() == 'German' ? '0' : '1'; $query = ' @@ -14,6 +15,10 @@ $query = ' anrechnung.lehrveranstaltung_id, anrechnung.begruendung_id, anrechnung.dms_id, + CASE + WHEN stg.typ || stg.kurzbz IN (' . $ORGANISATIONSEINHEITEN_SCHREIBBERECHTIGT . ') THEN TRUE + ELSE FALSE + END "schreibberechtigt", anrechnung.studiensemester_kurzbz, stg.studiengang_kz, stg.bezeichnung AS stg_bezeichnung, @@ -71,6 +76,7 @@ $query = ' anrechnungen.lehrveranstaltung_id, anrechnungen.begruendung_id, anrechnungen.dms_id, + anrechnungen.schreibberechtigt, anrechnungen.studiensemester_kurzbz, anrechnungen.studiengang_kz, anrechnungen.stg_bezeichnung, @@ -141,6 +147,7 @@ $filterWidgetArray = array( 'lehrveranstaltung_id', 'begruendung_id', 'dms_id', + 'schreibberechtigt', 'studiensemester_kurzbz', 'studiengang_kz', ucfirst($this->p->t('lehre', 'studiengang')), @@ -172,6 +179,7 @@ $filterWidgetArray = array( persistentFilter:true, autoResize: false, // prevent auto resizing of table (false to allow adapting table size when cols are (de-)activated headerFilterPlaceholder: " ", + initialHeaderFilter: [{field:"schreibberechtigt", value: true}], index: "anrechnung_id", // assign specific column as unique id (important for row indexing) selectable: true, // allow row selection selectableRangeMode: "click", // allow range selection using shift end click on end of range @@ -200,6 +208,10 @@ $filterWidgetArray = array( lehrveranstaltung_id: {visible: false, headerFilter:"input"}, begruendung_id: {visible: false, headerFilter:"input"}, dms_id: {visible: false, headerFilter:"input"}, + schreibberechtigt: { + formatter:"tickCross", align:"center", + headerFilter:"tickCross", headerFilterParams:{"tristate": true, "initial": true}, headerFilterFunc: hf_schreibberechtigt + }, studiensemester_kurzbz: {visible: false, headerFilter:"input"}, studiengang_kz: {visible: false, headerFilter:"input"}, stg_bezeichnung: {headerFilter:"input"}, diff --git a/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js b/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js index 395937950..c2a115961 100644 --- a/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js +++ b/public/js/lehre/anrechnung/approveAnrechnungUebersicht.js @@ -57,6 +57,12 @@ function hf_filterTrueFalse(headerValue, rowValue){ } } +// Filters schreibberechtigt boolean values +function hf_schreibberechtigt(headerValue, rowValue){ + + return rowValue == headerValue.toString(); +} + // Adds column details // Sets focus on filterbutton, if table starts with stored filter. function func_tableBuilt(table) { @@ -173,19 +179,22 @@ function func_selectableCheck(row){ // data = selected data, rows = selected rows function func_rowSelectionChanged(data, rows){ - // Sum up over all anzurechnenden LV-ECTS by Prestudent - selectedPrestudentWithAccumulatedLvEcts = approveAnrechnung.getSumLvEctsByPreStudent(data); + if (tabulator != null) + { + // Sum up over all anzurechnenden LV-ECTS by Prestudent + selectedPrestudentWithAccumulatedLvEcts = approveAnrechnung.getSumLvEctsByPreStudent(data); - // Loop through all active rows - var rowManager = tabulator.rowManager; - for (var i = 0; i < rowManager.activeRows.length; i++) { + // Loop through all active rows + var rowManager = tabulator.rowManager; + for (var i = 0; i < rowManager.activeRows.length; i++) { - // Reinitialize row -> triggers formatters. - rowManager.activeRows[i].reinitialize(); + // Reinitialize row -> triggers formatters. + rowManager.activeRows[i].reinitialize(); + } + + // Show number of selected rows. + approveAnrechnung.showNumberSelectedRows(rows); } - - // Show number of selected rows. - approveAnrechnung.showNumberSelectedRows(rows); } // Returns tooltip From fb4f9981f0493918413ce1e9b013239523a65bfc Mon Sep 17 00:00:00 2001 From: Cris Date: Wed, 11 Jan 2023 13:52:44 +0100 Subject: [PATCH 051/439] Corrected: Anzeige aller LV-Leitungen, an die Empfehlung gesendet wurde In der STGL Anrechnungs-Detailsicht wurde bisher nur die erste LV-Leitung aus dem Ergebnisarray ausgelesen. Nun werden alle angezeigt. --- application/libraries/AnrechnungLib.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/application/libraries/AnrechnungLib.php b/application/libraries/AnrechnungLib.php index b37aa46b6..d5168910b 100644 --- a/application/libraries/AnrechnungLib.php +++ b/application/libraries/AnrechnungLib.php @@ -795,11 +795,14 @@ class AnrechnungLib // Check if lv has LV-Leitung $key = array_search(true, array_column($result, 'lvleiter')); - - // If lv has LV-Leitung, keep only the one + + // If lv has 1 or more LV-Leitungen, keep only them if ($key !== false) { - $lector_arr[]= $result[$key]; + foreach ($result as $lector) + { + if ($lector->lvleiter) $lector_arr[]= $lector; + } } // ...otherwise keep all lectors else From 3f4efbcd163089e6f557ed500bdc65517e246953 Mon Sep 17 00:00:00 2001 From: Cris Date: Wed, 11 Jan 2023 18:05:49 +0100 Subject: [PATCH 052/439] Added function isEmpfehlungsberechtigt to AnrechnungLib Checks if user is allowed to recommend Anrechnung. --- application/libraries/AnrechnungLib.php | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/application/libraries/AnrechnungLib.php b/application/libraries/AnrechnungLib.php index d5168910b..7a0a4b892 100644 --- a/application/libraries/AnrechnungLib.php +++ b/application/libraries/AnrechnungLib.php @@ -762,6 +762,21 @@ class AnrechnungLib // Continue, if LV has no lector (there is no one to ask for recommendation) return hasData($result) ? true : false; } + + /** + * Check if user is allowed to recommend Anrechnung. + * + * @param $anrechnung_id + * @return bool + */ + public function isEmpfehlungsberechtigt($anrechnung_id) + { + // Get lv-leitungen or, if not present, all lectors of lv. + $lector_arr = $this->getLectors($anrechnung_id); + + // Return false if lv-leitung is present and user is not lv-leitung. Otherways return always true. + return in_array(getAuthUID(), array_column($lector_arr, 'uid')); + } /** * Get LV Leitung. If not present, get all LV lectors. From f2231fcba2d3262de6bc99b37afc26677231afb1 Mon Sep 17 00:00:00 2001 From: Cris Date: Wed, 11 Jan 2023 18:13:14 +0100 Subject: [PATCH 053/439] Disabled recommendation buttons if Lector is not empfehlungsberechtigt If lector should see Anrechnung but not give a recommendation (because is not the LV-Leitung), then recommendation buttons are disabled. --- .../controllers/lehre/anrechnung/ReviewAnrechnungDetail.php | 6 +++++- .../views/lehre/anrechnung/reviewAnrechnungDetail.php | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php index 8cb6e3d79..a3859a1b6 100644 --- a/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php +++ b/application/controllers/lehre/anrechnung/ReviewAnrechnungDetail.php @@ -94,10 +94,14 @@ class reviewAnrechnungDetail extends Auth_Controller // Get Empfehlung data $empfehlungData = $this->anrechnunglib->getEmpfehlungData($anrechnung_id); + // False if LV-Leitung is present and user is not LV-Leitung. Otherwise always true. + $isEmpfehlungsberechtigt = $this->anrechnunglib->isEmpfehlungsberechtigt($anrechnung_id); + $viewData = array( 'antragData' => $antragData, 'anrechnungData' => $anrechnungData, - 'empfehlungData' => $empfehlungData + 'empfehlungData' => $empfehlungData, + 'isEmpfehlungsberechtigt' => $isEmpfehlungsberechtigt ); $this->load->view('lehre/anrechnung/reviewAnrechnungDetail.php', $viewData); diff --git a/application/views/lehre/anrechnung/reviewAnrechnungDetail.php b/application/views/lehre/anrechnung/reviewAnrechnungDetail.php index 462124666..9b0748979 100644 --- a/application/views/lehre/anrechnung/reviewAnrechnungDetail.php +++ b/application/views/lehre/anrechnung/reviewAnrechnungDetail.php @@ -287,12 +287,12 @@ $this->load->view(
From 8bd007b6ea31f2840fc85dea9ef3b587ebab2cfb Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 12 Jan 2023 09:38:41 +0100 Subject: [PATCH 054/439] Merged Fachbereichsleitungs-files into core files . approveAnrechnungUebersichtData_fbl.php into approveAnrechnungUebersichtData.php . reviewAnrechnungUebersichtData_fbl.php into reviewAnrechnungUebersichtData.php --- .../approveAnrechnungUebersicht.php | 9 +- .../approveAnrechnungUebersichtData.php | 43 ++++++- .../anrechnung/reviewAnrechnungUebersicht.php | 8 +- .../reviewAnrechnungUebersichtData.php | 109 +++++++++++++----- 4 files changed, 117 insertions(+), 52 deletions(-) diff --git a/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php b/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php index 34cb6b998..dec7dcaff 100644 --- a/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php +++ b/application/views/lehre/anrechnung/approveAnrechnungUebersicht.php @@ -124,14 +124,7 @@ $this->load->view(
- load->config('anrechnung'); - if ($this->config->item('fbl') === TRUE) - $this->load->view('lehre/anrechnung/approveAnrechnungUebersichtData_fbl.php'); - else - $this->load->view('lehre/anrechnung/approveAnrechnungUebersichtData.php'); - ?> + load->view('lehre/anrechnung/approveAnrechnungUebersichtData.php'); ?>
diff --git a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php index 87ba57b6f..0a0d33c3b 100644 --- a/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php +++ b/application/views/lehre/anrechnung/approveAnrechnungUebersichtData.php @@ -107,8 +107,39 @@ $query = ' AND status_kurzbz = \'' . ANRECHNUNGSTATUS_PROGRESSED_BY_LEKTOR . '\' ORDER BY insertamum DESC LIMIT 1) - END "empfehlungsanfrageAm", - CASE + END "empfehlungsanfrageAm",'; + +$this->load->config('anrechnung'); +if ($this->config->item('fbl') === TRUE) +{ + $query.= ' CASE + WHEN (anrechnungen.empfehlung_anrechnung IS NULL AND anrechnungen.status_kurzbz = \'' . ANRECHNUNGSTATUS_PROGRESSED_BY_STGL . '\') THEN NULL + ELSE + (SELECT COALESCE( + STRING_AGG(CONCAT_WS(\' \', vorname, nachname), \', \') + ) empfehlungsanfrageAn + FROM ( + SELECT DISTINCT ON (benutzer.uid) bf.uid, vorname, nachname + FROM lehre.tbl_lehreinheit + JOIN lehre.tbl_lehrveranstaltung lv using (lehrveranstaltung_id) + JOIN public.tbl_organisationseinheit og using (oe_kurzbz) + JOIN public.tbl_benutzerfunktion bf using (oe_kurzbz) + JOIN public.tbl_benutzer benutzer ON bf.uid = benutzer.uid + JOIN public.tbl_person USING (person_id) + WHERE studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' + and bf.datum_von <= now() + and (bf.datum_bis >= now() or bf.datum_bis is null) + AND lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id + AND benutzer.aktiv = TRUE + AND tbl_person.aktiv = TRUE + ORDER BY benutzer.uid, nachname, vorname + ) as tmp_lvlektoren + ) + END "empfehlungsanfrageAn"'; +} +else +{ + $query.= ' CASE WHEN (anrechnungen.empfehlung_anrechnung IS NULL AND anrechnungen.status_kurzbz = \'' . ANRECHNUNGSTATUS_PROGRESSED_BY_STGL . '\') THEN NULL ELSE (SELECT COALESCE( @@ -130,8 +161,10 @@ $query = ' ORDER BY benutzer.uid, lvleiter DESC, nachname, vorname ) as tmp_lvlektoren ) - END "empfehlungsanfrageAn" - FROM anrechnungen + END "empfehlungsanfrageAn"'; +} + +$query.= ' FROM anrechnungen JOIN lehre.tbl_anrechnungstatus as anrechnungstatus ON (anrechnungstatus.status_kurzbz = anrechnungen.status_kurzbz) WHERE studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' AND studiengang_kz IN (' . $STUDIENGAENGE_ENTITLED . ') @@ -147,7 +180,7 @@ $filterWidgetArray = array( 'lehrveranstaltung_id', 'begruendung_id', 'dms_id', - 'schreibberechtigt', + 'Schreibberechtigt', 'studiensemester_kurzbz', 'studiengang_kz', ucfirst($this->p->t('lehre', 'studiengang')), diff --git a/application/views/lehre/anrechnung/reviewAnrechnungUebersicht.php b/application/views/lehre/anrechnung/reviewAnrechnungUebersicht.php index 82e66487f..e3de15084 100644 --- a/application/views/lehre/anrechnung/reviewAnrechnungUebersicht.php +++ b/application/views/lehre/anrechnung/reviewAnrechnungUebersicht.php @@ -117,13 +117,7 @@ $this->load->view(
- load->config('anrechnung'); - if($this->config->item('fbl')===TRUE) - $this->load->view('lehre/anrechnung/reviewAnrechnungUebersichtData_fbl.php'); - else - $this->load->view('lehre/anrechnung/reviewAnrechnungUebersichtData.php');?> + load->view('lehre/anrechnung/reviewAnrechnungUebersichtData.php');?>
diff --git a/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php index aa28d7fc0..ca086506f 100644 --- a/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php +++ b/application/views/lehre/anrechnung/reviewAnrechnungUebersichtData.php @@ -63,32 +63,77 @@ $query = ' AND benutzer.aktiv = TRUE AND tbl_person.aktiv = TRUE ORDER BY lehrveranstaltung_id, benutzer.uid, lehrfunktion_kurzbz DESC - ) - - SELECT DISTINCT ON (anrechnungen.*, lema.mitarbeiter_uid) anrechnungen.*, - array_to_json(anrechnungstatus.bezeichnung_mehrsprachig::varchar[])->>' . $LANGUAGE_INDEX . ' AS "status_bezeichnung", - CASE - -- erst prüfen, ob es überhaupt eine LV Leitung gibt (wenn nicht, dann immer empfehlungsberechtigt) - WHEN EXISTS (SELECT 1 FROM tbl_lvleitungen WHERE lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id AND lvleiter = TRUE) - -- wenn ja, return true, wenn user LV Leitung ist oder false, wenn nicht - THEN (SELECT EXISTS (SELECT 1 FROM tbl_lvleitungen WHERE lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id AND lvleiter = TRUE AND uid = \'' . $LEKTOR_UID . '\')) - -- wenn es keine LV Leitung, return immer true - ELSE TRUE - END AS empfehlungsberechtigt - FROM anrechnungen - JOIN lehre.tbl_anrechnungstatus as anrechnungstatus ON (anrechnungstatus.status_kurzbz = anrechnungen.status_kurzbz) - JOIN lehre.tbl_lehreinheit le USING (lehrveranstaltung_id) - JOIN lehre.tbl_lehreinheitmitarbeiter lema USING (lehreinheit_id) - WHERE le.studiensemester_kurzbz = anrechnungen.studiensemester_kurzbz - AND lema.mitarbeiter_uid = \'' . $LEKTOR_UID . '\' - AND le.lehre = TRUE - AND EXISTS ( - SELECT 1 - FROM lehre.tbl_anrechnung_anrechnungstatus - WHERE anrechnung_id = anrechnungen.anrechnung_id - AND status_kurzbz=\'inProgressLektor\' - ) -'; + )'; + +$this->load->config('anrechnung'); +if ($this->config->item('fbl') === TRUE) +{ + $query.= ' + SELECT DISTINCT /*ON (anrechnungen.*, bf.uid)*/ + CASE + -- erst prüfen, ob es überhaupt eine LV Leitung gibt (wenn nicht, dann immer empfehlungsberechtigt) + WHEN EXISTS (SELECT 1 FROM tbl_lvleitungen WHERE lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id AND lvleiter = TRUE) + -- wenn ja, return true, wenn user LV Leitung ist oder false, wenn nicht + THEN (SELECT EXISTS (SELECT 1 FROM tbl_lvleitungen WHERE lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id AND lvleiter = TRUE AND uid = \'' . $LEKTOR_UID . '\')) + -- wenn es keine LV Leitung, return immer true + ELSE TRUE + END AS empfehlungsberechtigt, + anrechnungen.*, + array_to_json(anrechnungstatus.bezeichnung_mehrsprachig::varchar[])->>' . $LANGUAGE_INDEX . ' AS "status_bezeichnung" + FROM anrechnungen + JOIN lehre.tbl_anrechnungstatus as anrechnungstatus ON (anrechnungstatus.status_kurzbz = anrechnungen.status_kurzbz) + JOIN lehre.tbl_lehreinheit le USING (lehrveranstaltung_id) + /*JOIN lehre.tbl_lehreinheitmitarbeiter lema USING (lehreinheit_id)*/ + JOIN lehre.tbl_lehrveranstaltung lv using (lehrveranstaltung_id) + JOIN public.tbl_organisationseinheit og using (oe_kurzbz) + JOIN public.tbl_benutzerfunktion bf using (oe_kurzbz) + WHERE anrechnungen.studiensemester_kurzbz = \'' . $STUDIENSEMESTER . '\' + AND le.studiensemester_kurzbz = anrechnungen.studiensemester_kurzbz + /*AND lema.mitarbeiter_uid = \'' . $LEKTOR_UID . '\'*/ + AND le.lehre = TRUE + AND bf.funktion_kurzbz = \'Leitung\' + and bf.datum_von <= now() + and (bf.datum_bis >= now() or bf.datum_bis is null) + AND og.organisationseinheittyp_kurzbz = \'Fachbereich\' + AND bf.uid = \'' . $LEKTOR_UID . '\' + AND EXISTS ( + SELECT 1 + FROM lehre.tbl_anrechnung_anrechnungstatus + WHERE anrechnung_id = anrechnungen.anrechnung_id + AND status_kurzbz=\'inProgressLektor\' + ) + order by empfehlung_anrechnung NULLS FIRST, antragsdatum + '; +} +else +{ + $query.= ' + SELECT DISTINCT ON (anrechnungen.*, lema.mitarbeiter_uid) + CASE + -- erst prüfen, ob es überhaupt eine LV Leitung gibt (wenn nicht, dann immer empfehlungsberechtigt) + WHEN EXISTS (SELECT 1 FROM tbl_lvleitungen WHERE lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id AND lvleiter = TRUE) + -- wenn ja, return true, wenn user LV Leitung ist oder false, wenn nicht + THEN (SELECT EXISTS (SELECT 1 FROM tbl_lvleitungen WHERE lehrveranstaltung_id = anrechnungen.lehrveranstaltung_id AND lvleiter = TRUE AND uid = \'' . $LEKTOR_UID . '\')) + -- wenn es keine LV Leitung, return immer true + ELSE TRUE + END AS empfehlungsberechtigt, + anrechnungen.*, + array_to_json(anrechnungstatus.bezeichnung_mehrsprachig::varchar[])->>' . $LANGUAGE_INDEX . ' AS "status_bezeichnung" + FROM anrechnungen + JOIN lehre.tbl_anrechnungstatus as anrechnungstatus ON (anrechnungstatus.status_kurzbz = anrechnungen.status_kurzbz) + JOIN lehre.tbl_lehreinheit le USING (lehrveranstaltung_id) + JOIN lehre.tbl_lehreinheitmitarbeiter lema USING (lehreinheit_id) + WHERE le.studiensemester_kurzbz = anrechnungen.studiensemester_kurzbz + AND lema.mitarbeiter_uid = \'' . $LEKTOR_UID . '\' + AND le.lehre = TRUE + AND EXISTS ( + SELECT 1 + FROM lehre.tbl_anrechnung_anrechnungstatus + WHERE anrechnung_id = anrechnungen.anrechnung_id + AND status_kurzbz=\'inProgressLektor\' + ) + '; +} $filterWidgetArray = array( 'query' => $query, @@ -96,6 +141,7 @@ $filterWidgetArray = array( 'requiredPermissions' => 'lehre/anrechnung_empfehlen', 'datasetRepresentation' => 'tabulator', 'columnsAliases' => array( + 'Empfehlungsberechtigt', 'anrechnung_id', 'lehrveranstaltung_id', 'begruendung_id', @@ -113,8 +159,7 @@ $filterWidgetArray = array( ucfirst($this->p->t('anrechnung', 'antragdatum')), ucfirst($this->p->t('anrechnung', 'empfehlung')), 'status_kurzbz', - 'Status', - 'empfehlungsberechtigt' + 'Status' ), 'datasetRepOptions' => '{ height: func_height(this), @@ -148,6 +193,9 @@ $filterWidgetArray = array( } }', // tabulator properties 'datasetRepFieldsDefs' => '{ + empfehlungsberechtigt: {formatter:"tickCross", align:"center", headerTooltip:"Berechtigt wenn man die LV leitet oder wenn der LV keine LV-Leitung zugeordnet ist.", + headerFilter:"tickCross", headerFilterParams:{"tristate": true, "initial": true}, headerFilterFunc: hf_empfehlungsberechtigt + }, anrechnung_id: {visible: false, headerFilter:"input"}, lehrveranstaltung_id: {visible: false, headerFilter:"input"}, begruendung_id: {visible: false, headerFilter:"input"}, @@ -165,10 +213,7 @@ $filterWidgetArray = array( antragsdatum: {align:"center", headerFilter:"input", mutator: mut_formatStringDate}, empfehlung_anrechnung: {headerFilter:"input", align:"center", formatter: format_empfehlung_anrechnung, headerFilterFunc: hf_filterTrueFalse}, status_kurzbz: {visible: false, headerFilter:"input"}, - status_bezeichnung: {headerFilter:"input"}, - empfehlungsberechtigt: {formatter:"tickCross", align:"center", - headerFilter:"tickCross", headerFilterParams:{"tristate": true, "initial": true}, headerFilterFunc: hf_empfehlungsberechtigt - } + status_bezeichnung: {headerFilter:"input"} }', // col properties ); From f0b1c14ea4640f9aba2515e2bc9192012bd02692 Mon Sep 17 00:00:00 2001 From: Manfred Date: Tue, 17 Jan 2023 15:57:01 +0100 Subject: [PATCH 055/439] Contents unchanged --- vilesci/stammdaten/benutzerberechtigung_uebersicht.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vilesci/stammdaten/benutzerberechtigung_uebersicht.php b/vilesci/stammdaten/benutzerberechtigung_uebersicht.php index 655ce058e..2361af438 100644 --- a/vilesci/stammdaten/benutzerberechtigung_uebersicht.php +++ b/vilesci/stammdaten/benutzerberechtigung_uebersicht.php @@ -21,7 +21,7 @@ * Gerald Simane-Sequens < gerald.simane-sequens@technikum-wien.at > * Manfred Kindl */ -require_once('../../config/vilesci.config.inc.php'); +require_once('../../config/vilesci.config.inc.php'); require_once('../../include/functions.inc.php'); require_once('../../include/studiengang.class.php'); require_once('../../include/benutzerberechtigung.class.php'); From 44bfe52529c22ea33953d3ecb7e597a2abc8cb91 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Thu, 26 Jan 2023 11:35:22 +0100 Subject: [PATCH 056/439] - fas filter hinzugefuegt --- include/prestudent.class.php | 36 +++++++++++++++++++++++++ rdf/lehrverbandsgruppe.rdf.php | 48 ++++++++++++++++++++++++++++++++-- rdf/student.rdf.php | 2 +- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/include/prestudent.class.php b/include/prestudent.class.php index 3bd7cd733..13f3e5e00 100644 --- a/include/prestudent.class.php +++ b/include/prestudent.class.php @@ -834,6 +834,42 @@ class prestudent extends person case "statusbestaetigt": $qry.=" AND a.rolle='Interessent' AND bestaetigtam is not null"; break; + case "statusbestaetigtrtnichtangemeldet": + $qry.=" AND a.rolle='Interessent' AND bestaetigtam is not null + AND NOT EXISTS ( + SELECT + 1 + FROM + public.tbl_rt_person + JOIN public.tbl_reihungstest ON (rt_id = reihungstest_id) + WHERE + person_id=a.person_id + AND studienplan_id IN ( + SELECT studienplan_id FROM lehre.tbl_studienplan + JOIN lehre.tbl_studienordnung USING(studienordnung_id) + WHERE tbl_studienordnung.studiengang_kz=a.studiengang_kz + ) + AND tbl_reihungstest.studiensemester_kurzbz=".$this->db_add_param($studiensemester_kurzbz)." + )"; + break; + case "statusbestaetigtrtangemeldet": + $qry.=" AND a.rolle='Interessent' AND bestaetigtam is not null + AND EXISTS ( + SELECT + 1 + FROM + public.tbl_rt_person + JOIN public.tbl_reihungstest ON (rt_id = reihungstest_id) + WHERE + person_id=a.person_id + AND studienplan_id IN ( + SELECT studienplan_id FROM lehre.tbl_studienplan + JOIN lehre.tbl_studienordnung USING(studienordnung_id) + WHERE tbl_studienordnung.studiengang_kz=a.studiengang_kz + ) + AND tbl_reihungstest.studiensemester_kurzbz=".$this->db_add_param($studiensemester_kurzbz)." + )"; + break; case "zgv": $stg_obj = new studiengang(); $stg_obj->load($studiengang_kz); diff --git a/rdf/lehrverbandsgruppe.rdf.php b/rdf/lehrverbandsgruppe.rdf.php index 79ac0c948..20956d279 100644 --- a/rdf/lehrverbandsgruppe.rdf.php +++ b/rdf/lehrverbandsgruppe.rdf.php @@ -246,6 +246,24 @@ function draw_orgformsubmenu($stg_kz, $orgform) + + Nicht zum Reihungstest angemeldet + + + studiensemester_kurzbz.']]> + statusbestaetigtrtnichtangemeldet + + + + + Reihungstest angemeldet + + + studiensemester_kurzbz.']]> + statusbestaetigtrtangemeldet + + + Nicht zum Reihungstest angemeldet @@ -316,7 +334,12 @@ function draw_orgformsubmenu($stg_kz, $orgform) $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/bewerbungnichtabgeschickt\" />\n"; $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/bewerbungabgeschickt\" />\n"; $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/zgv\" />\n"; - $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/statusbestaetigt\" />\n"; + $orgform_sequence[$stg_kz].= "\t\t\t"; + $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/statusbestaetigt\">\n"; + $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/statusbestaetigt/reihungstestnichtangemeldet\" />\n"; + $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/statusbestaetigt/reihungstestangemeldet\" />\n"; + $orgform_sequence[$stg_kz].= "\t\t\t\t"; + $orgform_sequence[$stg_kz].= "\n\t\t\t\n"; $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/reihungstestnichtangemeldet\" />\n"; $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/reihungstestangemeldet\" />\n"; $orgform_sequence[$stg_kz].= "\t\t\t\t"; @@ -561,6 +584,22 @@ while ($row=$dbo->db_fetch_object()) + + + ]]> + studiengang_kz; ?>]]> + studiensemester_kurzbz; ?>]]> + + + + + + ]]> + studiengang_kz; ?>]]> + studiensemester_kurzbz; ?>]]> + + + ]]> @@ -783,7 +822,12 @@ draw_orgformpart($stg_kz); echo "\t\t\t\tstudiensemester_kurzbz/interessenten/bewerbungnichtabgeschickt\" />\n"; echo "\t\t\t\tstudiensemester_kurzbz/interessenten/bewerbungabgeschickt\" />\n"; echo "\t\t\t\tstudiensemester_kurzbz/interessenten/zgv\" />\n"; - echo "\t\t\t\tstudiensemester_kurzbz/interessenten/statusbestaetigt\" />\n"; + echo "\t\t\t"; + echo "\t\t\t\tstudiensemester_kurzbz/interessenten/statusbestaetigt\">\n"; + echo "\t\t\t\tstudiensemester_kurzbz/interessenten/statusbestaetigt/reihungstestnichtangemeldet\" />\n"; + echo "\t\t\t\tstudiensemester_kurzbz/interessenten/statusbestaetigt/reihungstestangemeldet\" />\n"; + echo "\t\t\t\t"; + echo "\n\t\t\t\n"; echo "\t\t\t\tstudiensemester_kurzbz/interessenten/reihungstestnichtangemeldet\" />\n"; echo "\t\t\t\tstudiensemester_kurzbz/interessenten/reihungstestangemeldet\" />\n"; echo "\t\t\t\t"; diff --git a/rdf/student.rdf.php b/rdf/student.rdf.php index af0bbe82d..5e0c9d1c5 100644 --- a/rdf/student.rdf.php +++ b/rdf/student.rdf.php @@ -737,7 +737,7 @@ if($xmlformat=='rdf') } elseif(in_array($typ, array('prestudent', 'interessenten', 'bewerber', 'aufgenommen', 'warteliste', 'absage', 'zgv', 'reihungstestangemeldet', 'reihungstestnichtangemeldet', 'absolvent', - 'diplomand', 'bewerbungnichtabgeschickt', 'bewerbungabgeschickt', 'statusbestaetigt'))) + 'diplomand', 'bewerbungnichtabgeschickt', 'bewerbungabgeschickt', 'statusbestaetigt', 'statusbestaetigtrtnichtangemeldet', 'statusbestaetigtrtangemeldet'))) { $prestd = new prestudent(); From feb14a9f39ae9192a011373ecf4e7c822278ec58 Mon Sep 17 00:00:00 2001 From: Manfred Date: Mon, 13 Feb 2023 11:27:54 +0100 Subject: [PATCH 057/439] Anpassung Speicherbutton, Tooltips, Alertmessages --- .../benutzerberechtigung_details.php | 159 +++++++++++++----- .../benutzerberechtigung_uebersicht.php | 2 +- 2 files changed, 122 insertions(+), 39 deletions(-) diff --git a/vilesci/stammdaten/benutzerberechtigung_details.php b/vilesci/stammdaten/benutzerberechtigung_details.php index c8dff5491..26c105049 100644 --- a/vilesci/stammdaten/benutzerberechtigung_details.php +++ b/vilesci/stammdaten/benutzerberechtigung_details.php @@ -473,7 +473,23 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $name->load($uid); $htmlstr .= "Berechtigungen von ".$name->nachname." ".$name->vorname." (".$uid.")"; - $htmlstr .= "

".$errorstr."

".$successstr."

"; + $message = ''; + $class = ''; + if ($errorstr != '' || $successstr != '') + { + if ($successstr != '') + { + $class = 'class="alert alert-success"'; + $message = $successstr; + } + elseif ($errorstr != '') + { + $class = 'class="alert alert-danger"'; + $message = $errorstr; + } + } + $htmlstr .= '
'.$message.'
'; + //$htmlstr .= "

".$errorstr."

".$successstr."

"; //Formular zum Kopieren von Berechtigungen //$htmlstr .= "
"; @@ -562,8 +578,6 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) Gültig ab Gültig bis Anmerkung - Info - "; @@ -641,7 +655,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) //Anmerkung $htmlstr .= " "; - $htmlstr .= " "; + $htmlstr .= " "; $htmlstr .= "
"; $htmlstr .= " "; @@ -656,32 +670,32 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $htmlstr .= ""; $htmlstr .= ""; - $htmlstr .= " + /*$htmlstr .= "
- - +
- "; + ";*/ $htmlstr .= ""; - $htmlstr .= ""; + $htmlstr .= ""; $htmlstr .= " - + - + - + "; foreach($rights->berechtigungen as $b) @@ -743,7 +757,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $htmlstr .= " "; if ($b->rolle_kurzbz != '') { - $htmlstr .= " "; + $htmlstr .= " "; } $htmlstr.=""; @@ -754,7 +768,11 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) class='berechtigung_autocomplete' name='dataset[$b->benutzerberechtigung_id][berechtigung_kurzbz]' value='".$b->berechtigung_kurzbz."' - title='".($b->berechtigung_kurzbz != '' ? $berechtigung_arr[$b->berechtigung_kurzbz] : '')."'>"; + title='".($b->berechtigung_kurzbz != '' ? $berechtigung_arr[$b->berechtigung_kurzbz] : '')."' + data-toggle='tooltip' + data-html='true' + data-placement='auto' + data-original-title='Foo'>"; $htmlstr .= " "; //Art @@ -827,20 +845,36 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $htmlstr .= " "; //Info - $htmlstr .= " "; + $htmlstr .= " "; $htmlstr .= " "; $htmlstr .= " "; } $htmlstr .= "
+ Rolle Berechtigung Art Organisationseinheit KostenstelleNeg Gültig ab Gültig bis Anmerkung Info
information + + "; - $htmlstr .= " "; - $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= " "; $htmlstr .= "
"; - $htmlstr .= '
-
'; - $htmlstr .= ''; - $htmlstr .= ' - + $htmlstr .= '
+
+ +
+ +
+ +
+
+ +
'; $htmlstr .= ""; @@ -856,18 +890,19 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) + - + - + - + - Lehrveranstaltungen - Übersicht - - - - -   - - - - - - - - - - - -
-  Lehrveranstaltungen - Übersicht ('.$stsem->studiensemester_kurzbz.') -
 
- '; - - $qry = "SELECT - tbl_lehrveranstaltung.lehrveranstaltung_id, tbl_lehrveranstaltung.studiengang_kz, - tbl_lehrveranstaltung.bezeichnung, tbl_lehrveranstaltung.semester, - tbl_lehrveranstaltung.bezeichnung_english, tbl_lehrveranstaltung.incoming, - tbl_lehrveranstaltung.sprache, - ( - SELECT - count(*) - FROM - campus.vw_student_lehrveranstaltung - JOIN public.tbl_student ON(uid=student_uid) - JOIN public.tbl_prestudentstatus USING(prestudent_id) - WHERE - lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id AND - lehreinheit_id in (SELECT lehreinheit_id FROM lehre.tbl_lehreinheit - WHERE lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id - AND tbl_lehreinheit.studiensemester_kurzbz='$stsem->studiensemester_kurzbz') - AND tbl_prestudentstatus.status_kurzbz='Incoming' - AND tbl_prestudentstatus.status_kurzbz='$stsem->studiensemester_kurzbz' - GROUP BY uid - ) as anzahlincoming - FROM - lehre.tbl_lehrveranstaltung JOIN public.tbl_studiengang USING(studiengang_kz) - WHERE - tbl_lehrveranstaltung.incoming>0 AND - tbl_lehrveranstaltung.aktiv AND - tbl_lehrveranstaltung.lehre - AND tbl_lehrveranstaltung.studiengang_kz>0 AND tbl_lehrveranstaltung.studiengang_kz<10000 - AND tbl_studiengang.aktiv - "; - - echo ' - - - - - - - - - - - - - - '; - if($result = $db->db_query($qry)) - { - $i=0; - while($row = $db->db_fetch_object($result)) - { - $freieplaetze = $row->incoming - $row->anzahlincoming; - if($freieplaetze<0) - $freieplaetze=0; - - $i++; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - echo ''; - } - } - echo '
IDStudiengangSemesterSpracheLehrveranstaltungLehrveranstaltung EnglischLV-InfoPlätze gesamtFreie Plätze
',$row->lehrveranstaltung_id,'',$stg->kuerzel_arr[$row->studiengang_kz],'',$row->semester,'',$row->sprache,'',$row->bezeichnung,'',$row->bezeichnung_english,' - Deutsch  - Englisch - ',$row->incoming,'',$freieplaetze,'
'; -?> -
- - - - - - diff --git a/include/tw/cis_menu_lv.inc.php b/include/tw/cis_menu_lv.inc.php index 4b3005c07..16abdc48a 100644 --- a/include/tw/cis_menu_lv.inc.php +++ b/include/tw/cis_menu_lv.inc.php @@ -68,29 +68,8 @@ function checkZeilenUmbruch() if(!defined('CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN) { $text=''; - - $qry = "SELECT * FROM campus.tbl_lvinfo WHERE lehrveranstaltung_id=".$db->db_add_param($lvid, FHC_INTEGER)." AND genehmigt=true AND sprache='".ATTR_SPRACHE_DE."' AND aktiv=true"; $need_br=false; - if($result=$db->db_query($qry)) - { - if($db->db_num_rows($result)>0) - { - $text.= "".$p->t('global/deutsch')." "; - $need_br=true; - } - } - $qry = "SELECT * FROM campus.tbl_lvinfo WHERE lehrveranstaltung_id=".$db->db_add_param($lvid, FHC_INTEGER)." AND genehmigt=true AND sprache='".ATTR_SPRACHE_EN."' AND aktiv=true"; - if($result=$db->db_query($qry)) - { - if($db->db_num_rows($result)>0) - { - $row1=$db->db_fetch_object($result); - $text.= "".$p->t('global/englisch').""; - $need_br=true; - } - } - // Bearbeiten Button anzeigen wenn Lektor der LV und bearbeiten fuer Lektoren aktiviert ist // Oder Berechtigung zum Bearbeiten eingetragen ist if((!defined('CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT') && $lektor_der_lv) From 7bb340a4158bf54a1554da9d8416afa2101ac957 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 1 Mar 2023 10:44:47 +0100 Subject: [PATCH 066/439] - checksystem auf 3.4 umgebaut - vilesci raumtypen inaktive raumtypen werden markiert - tempus karteireiter ort zeigt nur aktive raumtypen an - raumsuche auf aktive raumtypen eingeschraenkt --- cis/private/lvplan/raumsuche.php | 12 ++++++------ include/raumtyp.class.php | 8 ++++++-- rdf/ort.rdf.php | 6 ++++-- system/dbupdate_3.3.php | 14 -------------- system/dbupdate_3.4.php | 1 + ...24913_tabelle_raumtyp_neues_attribut_aktiv.php | 15 +++++++++++++++ vilesci/lehre/lehrveranstaltung_details.php | 7 ++++++- vilesci/stammdaten/raum_details.php | 6 +++++- 8 files changed, 43 insertions(+), 26 deletions(-) create mode 100644 system/dbupdate_3.4/24913_tabelle_raumtyp_neues_attribut_aktiv.php diff --git a/cis/private/lvplan/raumsuche.php b/cis/private/lvplan/raumsuche.php index 0cb9677d4..7be028be8 100644 --- a/cis/private/lvplan/raumsuche.php +++ b/cis/private/lvplan/raumsuche.php @@ -47,11 +47,11 @@ echo ' - - - - - + + + + + "; + +} + if(isset($_POST['schick'])) { if($rechte->isBerechtigt('basis/berechtigung', null, 'suid')) @@ -418,9 +482,10 @@ if (!$b = new berechtigung()) $b->getRollen(); foreach($b->result as $berechtigung) { - $rolle_arr[] = $berechtigung->rolle_kurzbz; + $rolle_arr[$berechtigung->rolle_kurzbz] = $berechtigung->beschreibung; } -sort($rolle_arr); +ksort($rolle_arr, SORT_STRING | SORT_FLAG_CASE); + $b->getBerechtigungen(); foreach($b->result as $berechtigung) { @@ -592,10 +657,10 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) //Rolle $htmlstr .= " "; @@ -683,8 +748,8 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $htmlstr .= " - Rolle - Berechtigung + Rolle + Berechtigung Art Organisationseinheit Kostenstelle @@ -742,22 +807,32 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) //Rolle $htmlstr .= " "; - $htmlstr .= " "; $htmlstr .= " "; - for ($i = 0; $i < sizeof($rolle_arr); $i++) + foreach ($rolle_arr AS $key => $value) { - if ($b->rolle_kurzbz == $rolle_arr[$i]) + if ($b->rolle_kurzbz == $key) { - $sel = " selected"; + $sel = " selected='selected'"; } else $sel = ""; - $htmlstr .= ""; + $htmlstr .= ""; } $htmlstr .= " "; if ($b->rolle_kurzbz != '') { - $htmlstr .= " "; + $htmlstr .= " "; } $htmlstr.=""; @@ -827,13 +902,13 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $htmlstr .= " "; //Gültig ab - $htmlstr .= " "; + $htmlstr .= " "; $htmlstr .= " ".$b->start.""; $htmlstr .= " "; $htmlstr .= " "; // Gültig bis - $htmlstr .= " "; + $htmlstr .= " "; $htmlstr .= " ".$b->ende.""; $htmlstr .= " "; $htmlstr .= " "; @@ -842,7 +917,8 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $htmlstr .= " "; $htmlstr .= " anmerkung))."' data-toggle='tooltip' @@ -856,36 +932,54 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) $htmlstr .= " + data-placement='auto'> "; - $htmlstr .= " "; - $htmlstr .= " "; - $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= " "; + $htmlstr .= " "; $htmlstr .= " "; $htmlstr .= " "; } $htmlstr .= ""; $htmlstr .= '
- -
- -
- + +
+
+ +
+ +
+ +
-
'; $htmlstr .= ""; - + $htmlstr .= "
















"; } ?> @@ -910,7 +1004,203 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) ?> - + + + + + + + + + + + + + +

+ + + + + From 43f613b0bc286bf9c85981727fe187d7e3890447 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Wed, 5 Apr 2023 13:32:32 +0200 Subject: [PATCH 135/439] =?UTF-8?q?=C3=84nderung=20FHStG=20auf=20FHG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- rdf/diplomasupplement.xml.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rdf/diplomasupplement.xml.php b/rdf/diplomasupplement.xml.php index 47da798b7..4f19566d2 100644 --- a/rdf/diplomasupplement.xml.php +++ b/rdf/diplomasupplement.xml.php @@ -257,7 +257,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml") if($row->typ=='d') { echo ' UNESCO ISCED 7'; - echo ' '; + echo ' '; echo ' '; echo ' '; echo ' '; @@ -269,7 +269,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml") elseif($row->typ=='m') { echo ' UNESCO ISCED 7'; - echo ' '; + echo ' '; echo ' '; echo ' '; echo ' '; @@ -281,7 +281,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml") elseif($row->typ=='b') { echo ' UNESCO ISCED 6'; - echo ' '; + echo ' '; echo ' '; echo ' '; echo ' '; @@ -299,8 +299,8 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml") elseif($row->typ=='l' || $row->typ=='k' || $row->typ=='e') { echo ' UNESCO ISCED 7'; - echo ' Lehrgang zur Weiterbildung nach §9 FHStG idgF.'; - echo ' Certificate Program for Further Education subjected to § 9 FHStG'; + echo ' Lehrgang zur Weiterbildung nach §9 FHG idgF.'; + echo ' Certificate Program for Further Education subjected to § 9 FHG'; echo ' '; echo ' '; echo ' '; From e46d5a2433df617f2f5cb93c8280f1b192313a5e Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 5 Apr 2023 15:22:49 +0200 Subject: [PATCH 136/439] application/views/templates/FHC-Footer.php now includes the bootstrap5 bundle JS --- application/views/templates/FHC-Footer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/views/templates/FHC-Footer.php b/application/views/templates/FHC-Footer.php index 0c3782fea..c461dd8b0 100644 --- a/application/views/templates/FHC-Footer.php +++ b/application/views/templates/FHC-Footer.php @@ -60,7 +60,7 @@ if ($bootstrap3 === true) generateJSsInclude('vendor/twbs/bootstrap3/dist/js/bootstrap.min.js'); // Bootstrap 5 JS - if ($bootstrap5 === true) generateJSsInclude('vendor/twbs/bootstrap5/dist/js/bootstrap.min.js'); + if ($bootstrap5 === true) generateJSsInclude('vendor/twbs/bootstrap5/dist/js/bootstrap.bundle.min.js'); // Moment JS if ($momentjs2 === true) From 326b53544a47dcc8e0fc5a61eb40f94023cc47b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Wed, 5 Apr 2023 16:28:19 +0200 Subject: [PATCH 137/439] =?UTF-8?q?=C3=9Cbernahme=20Optimierung=20der=20An?= =?UTF-8?q?wesenheitsabfrage=20von=20BFI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/anwesenheit.class.php | 1373 +++++++++++++++++---------------- 1 file changed, 714 insertions(+), 659 deletions(-) diff --git a/include/anwesenheit.class.php b/include/anwesenheit.class.php index 3365e6d68..2b8389c79 100644 --- a/include/anwesenheit.class.php +++ b/include/anwesenheit.class.php @@ -1,659 +1,714 @@ - - */ -/** - * Klasse zur Verwaltung der Anwesenheiten der Studierenden - */ -require_once(dirname(__FILE__).'/basis_db.class.php'); -require_once(dirname(__FILE__).'/../config/global.config.inc.php'); - -class anwesenheit extends basis_db -{ - public $new=true; // boolean - public $result = array(); - - public $anwesenheit_id; // serial - public $uid; // varchar(32) - public $einheiten; // numeric(3,1) - public $datum; // date - public $anwesend; // boolean - public $lehreinheit_id; // bigint - public $anmerkung; // varchar(256) - - /** - * Konstruktor - * @param $anwesenheit_id ID des Datensatzes der geladen werden soll (Default=null) - */ - public function __construct($anwesenheit_id=null) - { - parent::__construct(); - - if(!is_null($anwesenheit_id)) - $this->load($anwesenheit_id); - } - - /** - * Laedt den Datensatz mit der ID $anwesenheit_id - * @param $anwesenheit_id ID des Datensatzes - * @return true wenn ok, false im Fehlerfall - */ - public function load($anwesenheit_id) - { - //Pruefen ob anwesenheit_id eine gueltige Zahl ist - if(!is_numeric($anwesenheit_id) || $anwesenheit_id == '') - { - $this->errormsg = 'Anwesenheit_id muss eine Zahl sein'; - return false; - } - - //Daten aus der Datenbank lesen - $qry = "SELECT * FROM campus.tbl_anwesenheit WHERE anwesenheit_id=".$this->db_add_param($anwesenheit_id, FHC_INTEGER, false); - - if(!$this->db_query($qry)) - { - $this->errormsg = 'Fehler bei einer Datenbankabfrage'; - return false; - } - - if($row = $this->db_fetch_object()) - { - $this->anwesenheit_id = $row->anwesenheit_id; - $this->uid = $row->uid; - $this->einheiten = $row->einheiten; - $this->datum = $row->datum; - $this->anwesend = $this->db_parse_bool($row->anwesend); - $this->lehreinheit_id = $row->lehreinheit_id; - $this->anmerkung = $row->anmerkung; - $this->new=false; - } - else - { - $this->errormsg = 'Es ist kein Datensatz mit dieser ID vorhanden'; - return false; - } - - return true; - } - - /** - * Prueft die Variablen auf Gueltigkeit - * @return true wenn ok, false im Fehlerfall - */ - protected function validate() - { - //Zahlenfelder pruefen - if(!is_numeric($this->anwesenheit_id) && $this->anwesenheit_id!='') - { - $this->errormsg='anwesenheit_id enthaelt ungueltige Zeichen'; - return false; - } - - //Gesamtlaenge pruefen - if(mb_strlen($this->anmerkung)>255) - { - $this->errormsg = 'Anmerkung darf nicht länger als 255 Zeichen sein'; - return false; - } - - $this->errormsg = ''; - return true; - } - - /** - * Speichert den aktuellen Datensatz in die Datenbank - * Wenn $neu auf true gesetzt ist wird ein neuer Datensatz angelegt - * andernfalls wird der bestehende Datensatz aktualisiert - * @return true wenn ok, false im Fehlerfall - */ - public function save() - { - //Variablen pruefen - if(!$this->validate()) - return false; - - if($this->new) - { - //Neuen Datensatz einfuegen - $qry='BEGIN;INSERT INTO campus.tbl_anwesenheit (uid, einheiten, anwesend, datum, lehreinheit_id, anmerkung) VALUES('. - $this->db_add_param($this->uid).', '. - $this->db_add_param($this->einheiten).', '. - $this->db_add_param($this->anwesend, FHC_BOOLEAN).', '. - $this->db_add_param($this->datum).', '. - $this->db_add_param($this->lehreinheit_id).', '. - $this->db_add_param($this->anmerkung).');'; - } - else - { - //Pruefen ob id eine gueltige Zahl ist - if(!is_numeric($this->anwesenheit_id)) - { - $this->errormsg = 'anwesenheit_id muss eine gueltige Zahl sein'; - return false; - } - $qry='UPDATE campus.tbl_anwesenheit SET'. - ' uid='.$this->db_add_param($this->uid).', '. - ' einheiten='.$this->db_add_param($this->einheiten).', '. - ' anwesend='.$this->db_add_param($this->anwesend,FHC_BOOLEAN).', '. - ' datum='.$this->db_add_param($this->datum).', '. - ' lehreinheit_id='.$this->db_add_param($this->lehreinheit_id, FHC_INTEGER).', '. - ' anmerkung='.$this->db_add_param($this->anmerkung).' '. - 'WHERE anwesenheit_id='.$this->db_add_param($this->anwesenheit_id, FHC_INTEGER, false).';'; - } - - if($this->db_query($qry)) - { - if($this->new) - { - //naechste ID aus der Sequence holen - $qry="SELECT currval('campus.seq_anwesenheit_anwesenheit_id') as id;"; - if($this->db_query($qry)) - { - if($row = $this->db_fetch_object()) - { - $this->anwesenheit_id = $row->id; - $this->db_query('COMMIT'); - } - else - { - $this->db_query('ROLLBACK'); - $this->errormsg = "Fehler beim Auslesen der Sequence"; - return false; - } - } - else - { - $this->db_query('ROLLBACK'); - $this->errormsg = 'Fehler beim Auslesen der Sequence'; - return false; - } - } - - } - else - { - $this->errormsg = 'Fehler beim Speichern des Datensatzes'; - return false; - } - return $this->anwesenheit_id; - } - - /** - * Laedt die Anwesenheiten einer Lehreinheit/Datum - * @param $lehreinheit_id - * @param $datum - * @return boolean true wenn ok, false im Fehlerfall - */ - public function getAnwesenheitLehreinheit($lehreinheit_id, $datum=null) - { - $qry = "SELECT * FROM campus.tbl_anwesenheit - WHERE - lehreinheit_id=".$this->db_add_param($lehreinheit_id, FHC_INTEGER); - - if(!is_null($datum)) - $qry.=" AND datum=".$this->db_add_param($datum); - - if($result = $this->db_query($qry)) - { - while($row = $this->db_fetch_object($result)) - { - $obj = new anwesenheit(); - - $obj->anwesenheit_id = $row->anwesenheit_id; - $obj->uid = $row->uid; - $obj->einheiten = $row->einheiten; - $obj->datum = $row->datum; - $obj->anwesend = $this->db_parse_bool($row->anwesend); - $obj->lehreinheit_id = $row->lehreinheit_id; - $obj->anmerkung = $row->anmerkung; - - $this->result[] = $obj; - } - return true; - } - else - { - $this->errormsg = 'Fehler beim Laden der Daten'; - return false; - } - } - - public function loadAnwesenheitMitarbeiter($mitarbeiter_uid, $lehreinheit_id) - { - $qry = "SELECT - datum, a.einheiten, - (SELECT true FROM campus.tbl_anwesenheit - WHERE lehreinheit_id=".$this->db_add_param($lehreinheit_id)." AND datum=a.datum LIMIT 1) as anwesend, - (SELECT stundensatz FROM lehre.tbl_lehreinheitmitarbeiter WHERE lehreinheit_id=".$this->db_add_param($lehreinheit_id)." - AND mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid).") as stundensatz - FROM - (SELECT datum, count(distinct stunde) as einheiten FROM lehre.tbl_stundenplan - WHERE - lehreinheit_id=".$this->db_add_param($lehreinheit_id)." - AND mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid)." - GROUP by datum) as a - "; - - if($result = $this->db_query($qry)) - { - $this->anzahl_termine=0; - $this->anzahl_anwesend=0; - $this->anwesenheit = array(); - - while($row = $this->db_fetch_object($result)) - { - $anwesend = $this->db_parse_bool($row->anwesend); - $key = $lehreinheit_id.'/'.$row->datum; - - $this->anwesenheit[$key]['anwesend'] = ($anwesend?true:false); - $this->anwesenheit[$key]['lehreinheit_id'] = $lehreinheit_id; - $this->anwesenheit[$key]['datum']=$row->datum; - $this->anwesenheit[$key]['einheiten']=$row->einheiten; - $this->anwesenheit[$key]['stundensatz']=$row->stundensatz; - - $this->anzahl_termine++; - if($anwesend) - $this->anzahl_anwesend++; - } - if($this->anzahl_termine>0) - { - $this->prozent_anwesend=$this->anzahl_anwesend/$this->anzahl_termine*100; - } - return true; - } - else - { - $this->errormsg='Fehler beim Laden der Daten'; - return false; - } - } - - /** - * Liefert für Student und Einheit wieviel Einheiten als anwesend/abwesend - * eingetragen sind. - * - * @param string $uid - * @param int $lehreinheit_id - * @param bool $anwesend - * @return int - */ - public function getAnwesenheit($uid, $lehreinheit_id, $anwesend = FALSE) - { - $qry = 'SELECT sum(einheiten) AS einheiten ' - . 'FROM campus.tbl_anwesenheit ' - . 'WHERE uid = ' . $this->db_add_param($uid) - . ' AND lehreinheit_id = ' . $this->db_add_param($lehreinheit_id, FHC_INTEGER) - . ' AND anwesend = ' . $this->db_add_param($anwesend, FHC_BOOLEAN); - - $result = $this->db_query($qry); - $row = $this->db_fetch_object($result); - - return $row->einheiten; - } - - /** - * Liefert die Anwesenheiten/Abwesenheiten eines Studenten bei einer LV - * - * @param string $student_uid - * @param int $lehrveranstaltung_id - * @param string $studiensemester_kurzbz - * @param boolean $anwesend - * @return boolean - */ - public function getAnwesenheitLehrveranstaltung($student_uid, $lehrveranstaltung_id, $studiensemester_kurzbz, $anwesend=false) - { - $qry = 'SELECT - distinct tbl_anwesenheit.* - FROM - campus.tbl_anwesenheit - JOIN campus.vw_student_lehrveranstaltung USING(uid) - WHERE - uid='.$this->db_add_param($student_uid).' - AND vw_student_lehrveranstaltung.lehreinheit_id=tbl_anwesenheit.lehreinheit_id - AND lehrveranstaltung_id='.$this->db_add_param($lehrveranstaltung_id, FHC_INTEGER).' - AND studiensemester_kurzbz='.$this->db_add_param($studiensemester_kurzbz).' - AND anwesend=' . $this->db_add_param($anwesend, FHC_BOOLEAN).' - ORDER BY datum'; - - if($result = $this->db_query($qry)) - { - while($row = $this->db_fetch_object($result)) - { - $obj = new anwesenheit(); - - $obj->anwesenheit_id = $row->anwesenheit_id; - $obj->uid = $row->uid; - $obj->einheiten = $row->einheiten; - $obj->datum = $row->datum; - $obj->anwesend = $this->db_parse_bool($row->anwesend); - $obj->lehreinheit_id = $row->lehreinheit_id; - $obj->anmerkung = $row->anmerkung; - - $this->result[] = $obj; - } - return true; - } - else - { - $this->errormsg = 'Fehler beim Laden der Daten'; - return false; - } - } - - /** - * Liefert die Termine an denen eine Abwesenheit eingetragen ist. - * - * @param string $uid - * @param int $lehreinheit_id - * @return array - */ - public function getAbwesendTermine($uid, $lehreinheit_id) - { - - $qry = 'SELECT datum, einheiten ' - . 'FROM campus.tbl_anwesenheit ' - . 'WHERE uid = ' . $this->db_add_param($uid) - . ' AND lehreinheit_id = ' . $this->db_add_param($lehreinheit_id) - . ' AND anwesend = FALSE ' - . 'ORDER BY datum'; - - $result = $this->db_query($qry); - $ret_obj = array(); - - while($row = $this->db_fetch_object($result)) - { - $ret_obj[] = $row; - } - - return $ret_obj; - } - - public function getAmpel($anwesenheit_relativ) - { - - if($anwesenheit_relativ < FAS_ANWESENHEIT_ROT) - { - return 'red'; - } - elseif($anwesenheit_relativ < FAS_ANWESENHEIT_GELB) - { - return 'yellow'; - } - else - { - return 'green'; - } - } - - /** - * Prueft ob Anwesenheiten erfasst wurden - * @param $lehreinheit_id ID der Lehreinheit - * @param $datum Datum - * @param $uid UID des Studierenden - * @return boolean true wenn vorhanden, sonst false - */ - public function AnwesenheitExists($lehreinheit_id, $datum, $uid=null) - { - $qry = "SELECT - 1 - FROM - campus.tbl_anwesenheit - WHERE - anwesend=true - AND lehreinheit_id=".$this->db_add_param($lehreinheit_id)." - AND datum=".$this->db_add_param($datum); - - if($uid!='') - $qry.=" AND uid=".$this->db_add_param($uid); - - if($result = $this->db_query($qry)) - { - if($this->db_num_rows($result)>0) - return true; - else - return false; - } - else - { - $this->errormsg = 'Fehler beim Laden der Daten'; - return false; - } - } - - /** - * Prueft ob Anwesenheiten erfasst wurden - * @param $lehreinheit_id ID der Lehreinheit - * @param $datum Datum - * @param $uid UID des Studierenden - * @return boolean true wenn vorhanden, sonst false - */ - public function AnwesenheitEntryExists($lehreinheit_id, $datum, $uid=null) - { - $qry = "SELECT - 1 - FROM - campus.tbl_anwesenheit - WHERE - lehreinheit_id=".$this->db_add_param($lehreinheit_id)." - AND datum=".$this->db_add_param($datum)." - AND uid=".$this->db_add_param($uid); - - if($result = $this->db_query($qry)) - { - if($this->db_num_rows($result)>0) - return true; - else - return false; - } - else - { - $this->errormsg = 'Fehler beim Laden der Daten'; - return false; - } - } - - /** - * Laedt die Anwesenheiten in Prozent von Studierenden bei Lehrveranstaltungen - * Wenn die StudentUID uebergeben wird, werden alle Lehrveranstaltungen zu denen der Studierenden zugeteilt ist inkl Prozent der Anwesenheit - * Wenn die LehrveranstaltungID uebergeben wird, werden alle Studierenden geholt die zugeteilt sind inkl Prozent der Anwesenheit - * Es werden pro Student die Anwesenheiten berechnet aufgrund der Lehreinheit zu der sie zugeordnet sind - * @param $studiensemester_kurzbz - * @param $student_uid - * @param $lehrveranstaltung_id - * @return boolean true wenn ok, false im fehlerfall - */ - public function loadAnwesenheitStudiensemester($studiensemester_kurzbz, $student_uid=null, $lehrveranstaltung_id=null) - { - $qry = "SELECT lehrveranstaltung_id, bezeichnung, vorname, wahlname, nachname,uid, sum(anwesend) as anwesend, sum(nichtanwesend) as nichtanwesend, sum(gesamtstunden) as gesamtstunden FROM ( - SELECT - lehrveranstaltung_id, bezeichnung, vorname, wahlname, nachname, uid, - ( - SELECT - sum(einheiten) - FROM - campus.tbl_anwesenheit - WHERE - lehreinheit_id=vw_student_lehrveranstaltung.lehreinheit_id - AND uid=vw_student_lehrveranstaltung.uid - AND anwesend - ) as anwesend, - ( - SELECT - sum(einheiten) - FROM - campus.tbl_anwesenheit - WHERE - lehreinheit_id=vw_student_lehrveranstaltung.lehreinheit_id - AND uid=vw_student_lehrveranstaltung.uid - AND NOT anwesend - ) as nichtanwesend, - ( - SELECT count(*) anzahl FROM - (SELECT datum, stunde FROM campus.vw_stundenplan - WHERE lehreinheit_id=vw_student_lehrveranstaltung.lehreinheit_id - AND (vw_stundenplan.titel not like '%Nebenprüfung%' OR vw_stundenplan.titel is null) GROUP BY datum, stunde) as a - ) as gesamtstunden - FROM - campus.vw_student_lehrveranstaltung - JOIN public.tbl_benutzer USING(uid) - JOIN public.tbl_person USING(person_id) - WHERE - studiensemester_kurzbz=".$this->db_add_param($studiensemester_kurzbz); - - if(!is_null($lehrveranstaltung_id)) - $qry.=" AND lehrveranstaltung_id=".$this->db_add_param($lehrveranstaltung_id); - if(!is_null($student_uid)) - $qry.=" AND uid=".$this->db_add_param($student_uid); - - $qry.=") as b GROUP BY lehrveranstaltung_id, bezeichnung, vorname, wahlname, nachname, uid"; - - if($lehrveranstaltung_id!='') - $qry.=" order by nachname, vorname "; - elseif($student_uid!='') - $qry.=" order by bezeichnung"; - - if($result = $this->db_query($qry)) - { - while($row = $this->db_fetch_object($result)) - { - $obj = new stdClass(); - $obj->bezeichnung = $row->bezeichnung; - $obj->anwesend = $row->anwesend; - $obj->nichtanwesend = $row->nichtanwesend; - $obj->gesamtstunden = $row->gesamtstunden; - - $obj->erfassteanwesenheit = $row->anwesend+$row->nichtanwesend; - if($row->gesamtstunden=='' || $obj->erfassteanwesenheit=='') - $obj->prozent=100; - else - $obj->prozent = number_format(100-(100/$obj->gesamtstunden*$row->nichtanwesend),2); - $obj->vorname = $row->vorname; - $obj->wahlname = $row->wahlname; - $obj->nachname = $row->nachname; - $obj->uid = $row->uid; - $obj->lehrveranstaltung_id = $row->lehrveranstaltung_id; - $this->result[] = $obj; - } - return true; - } - else - { - $this->errormsg='Fehler beim Laden der Daten'; - return false; - } - } - - /** - * Aendert die bestehende Anwesenheit - * @param $lehreinheit_id ID der Lehreinheit - * @param $datum Datum - * @param $uid UID des Studierenden - * @return boolean true ok, sonst false - */ - public function AnwesenheitToggle($lehreinheit_id, $datum, $uid) - { - if($this->AnwesenheitEntryExists($lehreinheit_id, $datum, $uid)) - { - $qry = "UPDATE - campus.tbl_anwesenheit - SET anwesend= NOT anwesend - WHERE - lehreinheit_id=".$this->db_add_param($lehreinheit_id)." - AND datum=".$this->db_add_param($datum)." - AND uid=".$this->db_add_param($uid); - - if($result = $this->db_query($qry)) - { - if($this->db_affected_rows($result)>0) - return true; - else - { - $this->errormsg='Anwesenheitsliste wurde noch nicht erfasst'; - return false; - } - } - else - { - $this->errormsg = 'Fehler beim Laden der Daten'; - return false; - } - } - else - { - // Anwesenheitsliste wurde noch nicht erfasst. Eintrag neu anlegen - - // Einheiten ermitteln - $qry = "SELECT - distinct stunde - FROM - lehre.tbl_stundenplan - WHERE - lehreinheit_id=".$this->db_add_param($lehreinheit_id)." - AND datum=".$this->db_add_param($datum); - - if($result = $this->db_query($qry)) - { - if($anzahl = $this->db_num_rows($result)) - { - $einheiten = $anzahl; - } - } - if($einheiten>0) - { - $this->lehreinheit_id=$lehreinheit_id; - $this->datum = $datum; - $this->uid = $uid; - $this->anwesend=true; - $this->new=true; - $this->einheiten=$einheiten; - if($this->save()) - return true; - else - { - $this->errormsg = 'Fehler beim Speichern der Daten'; - return true; - } - } - else - { - $this->errormsg = 'Anzahl der Einheiten fuer diesen Tag konnte nicht ermittelt werden'; - return false; - } - } - } - - /** - * Loescht eine Anwesenheit - * @param anwesenheit_id integer ID der Anwesenheit. - * @return boolean true wenn ok , false im fehlerfall - */ - public function delete($anwesenheit_id) - { - $qry = "DELETE FROM campus.tbl_anwesenheit WHERE anwesenheit_id=".$this->db_add_param($anwesenheit_id, FHC_INTEGER).";"; - - if($this->db_query($qry)) - { - return true; - } - else - { - $this->errormsg = 'Fehler beim Löschen der Anwesenheit'; - return false; - } - } -} + + */ +/** + * Klasse zur Verwaltung der Anwesenheiten der Studierenden + */ +require_once(dirname(__FILE__).'/basis_db.class.php'); +require_once(dirname(__FILE__).'/../config/global.config.inc.php'); + +class anwesenheit extends basis_db +{ + public $new=true; // boolean + public $result = array(); + + public $anwesenheit_id; // serial + public $uid; // varchar(32) + public $einheiten; // numeric(3,1) + public $datum; // date + public $anwesend; // boolean + public $lehreinheit_id; // bigint + public $anmerkung; // varchar(256) + + /** + * Konstruktor + * @param $anwesenheit_id ID des Datensatzes der geladen werden soll (Default=null) + */ + public function __construct($anwesenheit_id=null) + { + parent::__construct(); + + if(!is_null($anwesenheit_id)) + $this->load($anwesenheit_id); + } + + /** + * Laedt den Datensatz mit der ID $anwesenheit_id + * @param $anwesenheit_id ID des Datensatzes + * @return true wenn ok, false im Fehlerfall + */ + public function load($anwesenheit_id) + { + //Pruefen ob anwesenheit_id eine gueltige Zahl ist + if(!is_numeric($anwesenheit_id) || $anwesenheit_id == '') + { + $this->errormsg = 'Anwesenheit_id muss eine Zahl sein'; + return false; + } + + //Daten aus der Datenbank lesen + $qry = "SELECT * FROM campus.tbl_anwesenheit WHERE anwesenheit_id=".$this->db_add_param($anwesenheit_id, FHC_INTEGER, false); + + if(!$this->db_query($qry)) + { + $this->errormsg = 'Fehler bei einer Datenbankabfrage'; + return false; + } + + if($row = $this->db_fetch_object()) + { + $this->anwesenheit_id = $row->anwesenheit_id; + $this->uid = $row->uid; + $this->einheiten = $row->einheiten; + $this->datum = $row->datum; + $this->anwesend = $this->db_parse_bool($row->anwesend); + $this->lehreinheit_id = $row->lehreinheit_id; + $this->anmerkung = $row->anmerkung; + $this->new=false; + } + else + { + $this->errormsg = 'Es ist kein Datensatz mit dieser ID vorhanden'; + return false; + } + + return true; + } + + /** + * Prueft die Variablen auf Gueltigkeit + * @return true wenn ok, false im Fehlerfall + */ + protected function validate() + { + //Zahlenfelder pruefen + if(!is_numeric($this->anwesenheit_id) && $this->anwesenheit_id!='') + { + $this->errormsg='anwesenheit_id enthaelt ungueltige Zeichen'; + return false; + } + + //Gesamtlaenge pruefen + if(mb_strlen($this->anmerkung)>255) + { + $this->errormsg = 'Anmerkung darf nicht länger als 255 Zeichen sein'; + return false; + } + + $this->errormsg = ''; + return true; + } + + /** + * Speichert den aktuellen Datensatz in die Datenbank + * Wenn $neu auf true gesetzt ist wird ein neuer Datensatz angelegt + * andernfalls wird der bestehende Datensatz aktualisiert + * @return true wenn ok, false im Fehlerfall + */ + public function save() + { + //Variablen pruefen + if(!$this->validate()) + return false; + + if($this->new) + { + //Neuen Datensatz einfuegen + $qry='BEGIN;INSERT INTO campus.tbl_anwesenheit (uid, einheiten, anwesend, datum, lehreinheit_id, anmerkung) VALUES('. + $this->db_add_param($this->uid).', '. + $this->db_add_param($this->einheiten).', '. + $this->db_add_param($this->anwesend, FHC_BOOLEAN).', '. + $this->db_add_param($this->datum).', '. + $this->db_add_param($this->lehreinheit_id).', '. + $this->db_add_param($this->anmerkung).');'; + } + else + { + //Pruefen ob id eine gueltige Zahl ist + if(!is_numeric($this->anwesenheit_id)) + { + $this->errormsg = 'anwesenheit_id muss eine gueltige Zahl sein'; + return false; + } + $qry='UPDATE campus.tbl_anwesenheit SET'. + ' uid='.$this->db_add_param($this->uid).', '. + ' einheiten='.$this->db_add_param($this->einheiten).', '. + ' anwesend='.$this->db_add_param($this->anwesend,FHC_BOOLEAN).', '. + ' datum='.$this->db_add_param($this->datum).', '. + ' lehreinheit_id='.$this->db_add_param($this->lehreinheit_id, FHC_INTEGER).', '. + ' anmerkung='.$this->db_add_param($this->anmerkung).' '. + 'WHERE anwesenheit_id='.$this->db_add_param($this->anwesenheit_id, FHC_INTEGER, false).';'; + } + + if($this->db_query($qry)) + { + if($this->new) + { + //naechste ID aus der Sequence holen + $qry="SELECT currval('campus.seq_anwesenheit_anwesenheit_id') as id;"; + if($this->db_query($qry)) + { + if($row = $this->db_fetch_object()) + { + $this->anwesenheit_id = $row->id; + $this->db_query('COMMIT'); + } + else + { + $this->db_query('ROLLBACK'); + $this->errormsg = "Fehler beim Auslesen der Sequence"; + return false; + } + } + else + { + $this->db_query('ROLLBACK'); + $this->errormsg = 'Fehler beim Auslesen der Sequence'; + return false; + } + } + + } + else + { + $this->errormsg = 'Fehler beim Speichern des Datensatzes'; + return false; + } + return $this->anwesenheit_id; + } + + /** + * Laedt die Anwesenheiten einer Lehreinheit/Datum + * @param $lehreinheit_id + * @param $datum + * @return boolean true wenn ok, false im Fehlerfall + */ + public function getAnwesenheitLehreinheit($lehreinheit_id, $datum=null) + { + $qry = "SELECT * FROM campus.tbl_anwesenheit + WHERE + lehreinheit_id=".$this->db_add_param($lehreinheit_id, FHC_INTEGER); + + if(!is_null($datum)) + $qry.=" AND datum=".$this->db_add_param($datum); + + if($result = $this->db_query($qry)) + { + while($row = $this->db_fetch_object($result)) + { + $obj = new anwesenheit(); + + $obj->anwesenheit_id = $row->anwesenheit_id; + $obj->uid = $row->uid; + $obj->einheiten = $row->einheiten; + $obj->datum = $row->datum; + $obj->anwesend = $this->db_parse_bool($row->anwesend); + $obj->lehreinheit_id = $row->lehreinheit_id; + $obj->anmerkung = $row->anmerkung; + + $this->result[] = $obj; + } + return true; + } + else + { + $this->errormsg = 'Fehler beim Laden der Daten'; + return false; + } + } + + public function loadAnwesenheitMitarbeiter($mitarbeiter_uid, $lehreinheit_id) + { + $qry = "SELECT + datum, a.einheiten, + (SELECT true FROM campus.tbl_anwesenheit + WHERE lehreinheit_id=".$this->db_add_param($lehreinheit_id)." AND datum=a.datum LIMIT 1) as anwesend, + (SELECT stundensatz FROM lehre.tbl_lehreinheitmitarbeiter WHERE lehreinheit_id=".$this->db_add_param($lehreinheit_id)." + AND mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid).") as stundensatz + FROM + (SELECT datum, count(distinct stunde) as einheiten FROM lehre.tbl_stundenplan + WHERE + lehreinheit_id=".$this->db_add_param($lehreinheit_id)." + AND mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid)." + GROUP by datum) as a + "; + + if($result = $this->db_query($qry)) + { + $this->anzahl_termine=0; + $this->anzahl_anwesend=0; + $this->anwesenheit = array(); + + while($row = $this->db_fetch_object($result)) + { + $anwesend = $this->db_parse_bool($row->anwesend); + $key = $lehreinheit_id.'/'.$row->datum; + + $this->anwesenheit[$key]['anwesend'] = ($anwesend?true:false); + $this->anwesenheit[$key]['lehreinheit_id'] = $lehreinheit_id; + $this->anwesenheit[$key]['datum']=$row->datum; + $this->anwesenheit[$key]['einheiten']=$row->einheiten; + $this->anwesenheit[$key]['stundensatz']=$row->stundensatz; + + $this->anzahl_termine++; + if($anwesend) + $this->anzahl_anwesend++; + } + if($this->anzahl_termine>0) + { + $this->prozent_anwesend=$this->anzahl_anwesend/$this->anzahl_termine*100; + } + return true; + } + else + { + $this->errormsg='Fehler beim Laden der Daten'; + return false; + } + } + + /** + * Liefert für Student und Einheit wieviel Einheiten als anwesend/abwesend + * eingetragen sind. + * + * @param string $uid + * @param int $lehreinheit_id + * @param bool $anwesend + * @return int + */ + public function getAnwesenheit($uid, $lehreinheit_id, $anwesend = FALSE) + { + $qry = 'SELECT sum(einheiten) AS einheiten ' + . 'FROM campus.tbl_anwesenheit ' + . 'WHERE uid = ' . $this->db_add_param($uid) + . ' AND lehreinheit_id = ' . $this->db_add_param($lehreinheit_id, FHC_INTEGER) + . ' AND anwesend = ' . $this->db_add_param($anwesend, FHC_BOOLEAN); + + $result = $this->db_query($qry); + $row = $this->db_fetch_object($result); + + return $row->einheiten; + } + + /** + * Liefert die Anwesenheiten/Abwesenheiten eines Studenten bei einer LV + * + * @param string $student_uid + * @param int $lehrveranstaltung_id + * @param string $studiensemester_kurzbz + * @param boolean $anwesend + * @return boolean + */ + public function getAnwesenheitLehrveranstaltung($student_uid, $lehrveranstaltung_id, $studiensemester_kurzbz, $anwesend=false) + { + $qry = 'SELECT + distinct tbl_anwesenheit.* + FROM + campus.tbl_anwesenheit + JOIN campus.vw_student_lehrveranstaltung USING(uid) + WHERE + uid='.$this->db_add_param($student_uid).' + AND vw_student_lehrveranstaltung.lehreinheit_id=tbl_anwesenheit.lehreinheit_id + AND lehrveranstaltung_id='.$this->db_add_param($lehrveranstaltung_id, FHC_INTEGER).' + AND studiensemester_kurzbz='.$this->db_add_param($studiensemester_kurzbz).' + AND anwesend=' . $this->db_add_param($anwesend, FHC_BOOLEAN).' + ORDER BY datum'; + + if($result = $this->db_query($qry)) + { + while($row = $this->db_fetch_object($result)) + { + $obj = new anwesenheit(); + + $obj->anwesenheit_id = $row->anwesenheit_id; + $obj->uid = $row->uid; + $obj->einheiten = $row->einheiten; + $obj->datum = $row->datum; + $obj->anwesend = $this->db_parse_bool($row->anwesend); + $obj->lehreinheit_id = $row->lehreinheit_id; + $obj->anmerkung = $row->anmerkung; + + $this->result[] = $obj; + } + return true; + } + else + { + $this->errormsg = 'Fehler beim Laden der Daten'; + return false; + } + } + + /** + * Liefert die Termine an denen eine Abwesenheit eingetragen ist. + * + * @param string $uid + * @param int $lehreinheit_id + * @return array + */ + public function getAbwesendTermine($uid, $lehreinheit_id) + { + + $qry = 'SELECT datum, einheiten ' + . 'FROM campus.tbl_anwesenheit ' + . 'WHERE uid = ' . $this->db_add_param($uid) + . ' AND lehreinheit_id = ' . $this->db_add_param($lehreinheit_id) + . ' AND anwesend = FALSE ' + . 'ORDER BY datum'; + + $result = $this->db_query($qry); + $ret_obj = array(); + + while($row = $this->db_fetch_object($result)) + { + $ret_obj[] = $row; + } + + return $ret_obj; + } + + public function getAmpel($anwesenheit_relativ) + { + + if($anwesenheit_relativ < FAS_ANWESENHEIT_ROT) + { + return 'red'; + } + elseif($anwesenheit_relativ < FAS_ANWESENHEIT_GELB) + { + return 'yellow'; + } + else + { + return 'green'; + } + } + + /** + * Prueft ob Anwesenheiten erfasst wurden + * @param $lehreinheit_id ID der Lehreinheit + * @param $datum Datum + * @param $uid UID des Studierenden + * @return boolean true wenn vorhanden, sonst false + */ + public function AnwesenheitExists($lehreinheit_id, $datum, $uid=null) + { + $qry = "SELECT + 1 + FROM + campus.tbl_anwesenheit + WHERE + anwesend=true + AND lehreinheit_id=".$this->db_add_param($lehreinheit_id)." + AND datum=".$this->db_add_param($datum); + + if($uid!='') + $qry.=" AND uid=".$this->db_add_param($uid); + + if($result = $this->db_query($qry)) + { + if($this->db_num_rows($result)>0) + return true; + else + return false; + } + else + { + $this->errormsg = 'Fehler beim Laden der Daten'; + return false; + } + } + + /** + * Prueft ob Anwesenheiten erfasst wurden + * @param $lehreinheit_id ID der Lehreinheit + * @param $datum Datum + * @param $uid UID des Studierenden + * @return boolean true wenn vorhanden, sonst false + */ + public function AnwesenheitEntryExists($lehreinheit_id, $datum, $uid=null) + { + $qry = "SELECT + 1 + FROM + campus.tbl_anwesenheit + WHERE + lehreinheit_id=".$this->db_add_param($lehreinheit_id)." + AND datum=".$this->db_add_param($datum)." + AND uid=".$this->db_add_param($uid); + + if($result = $this->db_query($qry)) + { + if($this->db_num_rows($result)>0) + return true; + else + return false; + } + else + { + $this->errormsg = 'Fehler beim Laden der Daten'; + return false; + } + } + + /** + * Laedt die Anwesenheiten in Prozent von Studierenden bei Lehrveranstaltungen + * Wenn die StudentUID uebergeben wird, werden alle Lehrveranstaltungen zu denen der Studierenden zugeteilt ist inkl Prozent der Anwesenheit + * Wenn die LehrveranstaltungID uebergeben wird, werden alle Studierenden geholt die zugeteilt sind inkl Prozent der Anwesenheit + * Es werden pro Student die Anwesenheiten berechnet aufgrund der Lehreinheit zu der sie zugeordnet sind + * @param $studiensemester_kurzbz + * @param $student_uid + * @param $lehrveranstaltung_id + * @return boolean true wenn ok, false im fehlerfall + */ + public function loadAnwesenheitStudiensemester($studiensemester_kurzbz, $student_uid=null, $lehrveranstaltung_id=null) + { + $qry = "SELECT + lehrveranstaltung_id, vorname, nachname, wahlname, student_uid as uid, bezeichnung, + gesamt as gesamtstunden, anwesend, nichtanwesend, trunc(100-(nichtanwesend/gesamt)*100,2) as prozent + FROM + ( + SELECT + vorname, nachname, wahlname, lehrveranstaltung_id, bezeichnung, gruppe, student_uid, + count(stundenplan_id) as gesamt, + case when anwesend.summe is null then 0 else anwesend.summe end as anwesend, + case when nichtanwesend.summe is null then 0 else nichtanwesend.summe end as nichtanwesend + FROM + ( + SELECT + sum(stundenplan_id) as stundenplan_id, datum, stunde, lehrveranstaltung_id, + bezeichnung, studiensemester_kurzbz, studiengang_kz, + TRIM( + CASE WHEN stp.gruppe_kurzbz is not null then stp.gruppe_kurzbz + else stp.semester||(case when verband is null then '' else stp.verband end)||(case when stp.gruppe is null then '' else stp.gruppe end) end) as gruppe + FROM + lehre.tbl_lehrveranstaltung lv + JOIN lehre.tbl_lehreinheit le using (lehrveranstaltung_id) + JOIN lehre.tbl_stundenplan stp using (lehreinheit_id,studiengang_kz) + WHERE + studiensemester_kurzbz = ".$this->db_add_param($studiensemester_kurzbz)." + AND (titel not like '%Nebenprüfung%' OR titel is null) + + group by datum, stunde, lehrveranstaltung_id, bezeichnung, studiensemester_kurzbz, studiengang_kz, stp.gruppe_kurzbz, stp.semester, stp.verband, stp.gruppe + )x + JOIN ( + SELECT semester::text as gruppe, public.tbl_studentlehrverband.studiensemester_kurzbz, student_uid, studiengang_kz + FROM + public.tbl_studentlehrverband + WHERE studiensemester_kurzbz = ".$this->db_add_param($studiensemester_kurzbz)." + + UNION + + SELECT semester||verband as gruppe, public.tbl_studentlehrverband.studiensemester_kurzbz, student_uid, studiengang_kz + FROM + public.tbl_studentlehrverband + WHERE + studiensemester_kurzbz = ".$this->db_add_param($studiensemester_kurzbz)." + + UNION + + SELECT semester||verband||gruppe as gruppe, public.tbl_studentlehrverband.studiensemester_kurzbz, student_uid, studiengang_kz + FROM + public.tbl_studentlehrverband + WHERE + studiensemester_kurzbz = ".$this->db_add_param($studiensemester_kurzbz)." + + UNION + + SELECT gruppe_kurzbz as gruppe, public.tbl_benutzergruppe.studiensemester_kurzbz, uid as student_uid, studiengang_kz + FROM + public.tbl_benutzergruppe + JOIN + public.tbl_gruppe using (gruppe_kurzbz) + WHERE studiensemester_kurzbz = ".$this->db_add_param($studiensemester_kurzbz)." + + )a using (gruppe, studiensemester_kurzbz, studiengang_kz) + JOIN public.tbl_benutzer b on b.uid = student_uid + JOIN public.tbl_person p using(person_id) + LEFT JOIN( + SELECT + lehrveranstaltung_id, studiensemester_kurzbz, uid as student_uid, sum(einheiten) as summe + FROM + campus.tbl_anwesenheit a + JOIN lehre.tbl_lehreinheit le using (lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung lv using (lehrveranstaltung_id) + WHERE + anwesend = true AND studiensemester_kurzbz = ".$this->db_add_param($studiensemester_kurzbz)." + GROUP BY + lehrveranstaltung_id, bezeichnung, uid, studiensemester_kurzbz + )anwesend using(lehrveranstaltung_id, student_uid, studiensemester_kurzbz) + LEFT JOIN( + SELECT lehrveranstaltung_id, studiensemester_kurzbz, uid as student_uid, sum(einheiten) as summe + FROM + campus.tbl_anwesenheit a + JOIN lehre.tbl_lehreinheit le using (lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung lv using (lehrveranstaltung_id) + WHERE + anwesend = false AND studiensemester_kurzbz = ".$this->db_add_param($studiensemester_kurzbz)." + GROUP BY + lehrveranstaltung_id, bezeichnung, uid, studiensemester_kurzbz + )nichtanwesend using(lehrveranstaltung_id, student_uid, studiensemester_kurzbz) + WHERE + lehrveranstaltung_id > 0 + "; + + if(!is_null($student_uid)) + $qry.=" AND student_uid=".$this->db_add_param($student_uid); + if(!is_null($lehrveranstaltung_id)) + $qry.=" AND lehrveranstaltung_id=".$this->db_add_param($lehrveranstaltung_id); + + $qry.="group by + vorname, nachname, wahlname, lehrveranstaltung_id, bezeichnung, gruppe, student_uid, anwesend.summe, nichtanwesend.summe + )m"; + + if($lehrveranstaltung_id != '') + $qry.=" order by nachname, vorname "; + elseif($student_uid != '') + $qry.=" order by bezeichnung"; + + if($result = $this->db_query($qry)) + { + while($row = $this->db_fetch_object($result)) + { + $obj = new stdClass(); + $obj->bezeichnung = $row->bezeichnung; + $obj->anwesend = $row->anwesend; + $obj->nichtanwesend = $row->nichtanwesend; + $obj->gesamtstunden = $row->gesamtstunden; + + $obj->erfassteanwesenheit = $row->anwesend+$row->nichtanwesend; + if($row->gesamtstunden=='' || $obj->erfassteanwesenheit=='') + $obj->prozent=100; + else + $obj->prozent = number_format(100-(100/$obj->gesamtstunden*$row->nichtanwesend),2); + $obj->vorname = $row->vorname; + $obj->wahlname = $row->wahlname; + $obj->nachname = $row->nachname; + $obj->uid = $row->uid; + $obj->lehrveranstaltung_id = $row->lehrveranstaltung_id; + $this->result[] = $obj; + } + return true; + } + else + { + $this->errormsg='Fehler beim Laden der Daten'; + return false; + } + } + + /** + * Aendert die bestehende Anwesenheit + * @param $lehreinheit_id ID der Lehreinheit + * @param $datum Datum + * @param $uid UID des Studierenden + * @return boolean true ok, sonst false + */ + public function AnwesenheitToggle($lehreinheit_id, $datum, $uid) + { + if($this->AnwesenheitEntryExists($lehreinheit_id, $datum, $uid)) + { + $qry = "UPDATE + campus.tbl_anwesenheit + SET anwesend= NOT anwesend + WHERE + lehreinheit_id=".$this->db_add_param($lehreinheit_id)." + AND datum=".$this->db_add_param($datum)." + AND uid=".$this->db_add_param($uid); + + if($result = $this->db_query($qry)) + { + if($this->db_affected_rows($result)>0) + return true; + else + { + $this->errormsg='Anwesenheitsliste wurde noch nicht erfasst'; + return false; + } + } + else + { + $this->errormsg = 'Fehler beim Laden der Daten'; + return false; + } + } + else + { + // Anwesenheitsliste wurde noch nicht erfasst. Eintrag neu anlegen + + // Einheiten ermitteln + $qry = "SELECT + distinct stunde + FROM + lehre.tbl_stundenplan + WHERE + lehreinheit_id=".$this->db_add_param($lehreinheit_id)." + AND datum=".$this->db_add_param($datum); + + if($result = $this->db_query($qry)) + { + if($anzahl = $this->db_num_rows($result)) + { + $einheiten = $anzahl; + } + } + if($einheiten>0) + { + $this->lehreinheit_id=$lehreinheit_id; + $this->datum = $datum; + $this->uid = $uid; + $this->anwesend=true; + $this->new=true; + $this->einheiten=$einheiten; + if($this->save()) + return true; + else + { + $this->errormsg = 'Fehler beim Speichern der Daten'; + return true; + } + } + else + { + $this->errormsg = 'Anzahl der Einheiten fuer diesen Tag konnte nicht ermittelt werden'; + return false; + } + } + } + + /** + * Loescht eine Anwesenheit + * @param anwesenheit_id integer ID der Anwesenheit. + * @return boolean true wenn ok , false im fehlerfall + */ + public function delete($anwesenheit_id) + { + $qry = "DELETE FROM campus.tbl_anwesenheit WHERE anwesenheit_id=".$this->db_add_param($anwesenheit_id, FHC_INTEGER).";"; + + if($this->db_query($qry)) + { + return true; + } + else + { + $this->errormsg = 'Fehler beim Löschen der Anwesenheit'; + return false; + } + } +} From 19d369c3c708a9eaaabe16d54d54f121ca008366 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Thu, 6 Apr 2023 10:17:15 +0200 Subject: [PATCH 138/439] - im kalender mitarbeiter kurzbz statt uid anzeigen --- include/lehrstunde.class.php | 4 + include/wochenplan.class.php | 29 ++-- system/dbupdate_3.4.php | 1 + ...ter_kurzbz_bei_reservierungen_anzeigen.php | 130 ++++++++++++++++++ 4 files changed, 155 insertions(+), 9 deletions(-) create mode 100644 system/dbupdate_3.4/10001_tempus_mitarbeiter_kurzbz_bei_reservierungen_anzeigen.php diff --git a/include/lehrstunde.class.php b/include/lehrstunde.class.php index 280e626a8..a0f52d799 100644 --- a/include/lehrstunde.class.php +++ b/include/lehrstunde.class.php @@ -41,6 +41,7 @@ class lehrstunde extends basis_db public $unr; // @brief Unterrichtsnummer public $lektor_uid; // @brief UID des Lektors public $lektor_kurzbz; // @brief Kurzbezeichnung des Lektors + public $mitarbeiter_kurzbz; // @brief Kurzbezeichnung public $datum; // @brief Datum public $stunde; // @brief Unterrichts-Stunde des Tages public $ort_kurzbz; // @brief Ort in dem der Unterricht stattfindet @@ -116,6 +117,7 @@ class lehrstunde extends basis_db $this->unr=$row->unr; $this->lektor_uid=$row->uid; $this->lektor_kurzbz=$row->lektor; + $this->mitarbeiter_kurzbz=$row->mitarbeiter_kurzbz; $this->datum=$row->datum; $this->stunde=$row->stunde; $this->ort_kurzbz=$row->ort_kurzbz; @@ -590,6 +592,7 @@ class lehrstunde extends basis_db $stunde->unr=$row->unr; $stunde->lektor_uid=$row->uid; $stunde->lektor_kurzbz=$row->lektor; + $stunde->mitarbeiter_kurzbz=$row->mitarbeiter_kurzbz; $stunde->datum=$row->datum; $stunde->stunde=$row->stunde; $stunde->ort_kurzbz=$row->ort_kurzbz; @@ -663,6 +666,7 @@ class lehrstunde extends basis_db $stunde->updateamum=$row->insertamum; $stunde->updatevon=$row->insertvon; $stunde->farbe=''; + $stunde->mitarbeiter_kurzbz = $row->mitarbeiter_kurzbz; $this->lehrstunden[]=$stunde; } } diff --git a/include/wochenplan.class.php b/include/wochenplan.class.php index f6cc94c3c..34fbadc63 100644 --- a/include/wochenplan.class.php +++ b/include/wochenplan.class.php @@ -445,6 +445,7 @@ class wochenplan extends basis_db $this->std_plan[$tag][$stunde][$idx]->stundenplan_id=$this->wochenplan->lehrstunden[$i]->stundenplan_id; $this->std_plan[$tag][$stunde][$idx]->lektor_uid=$this->wochenplan->lehrstunden[$i]->lektor_uid; $this->std_plan[$tag][$stunde][$idx]->lektor=$this->wochenplan->lehrstunden[$i]->lektor_kurzbz; + $this->std_plan[$tag][$stunde][$idx]->mitarbeiter_kurzbz=$this->wochenplan->lehrstunden[$i]->mitarbeiter_kurzbz; $this->std_plan[$tag][$stunde][$idx]->ort=$this->wochenplan->lehrstunden[$i]->ort_kurzbz; $this->std_plan[$tag][$stunde][$idx]->stg=$this->wochenplan->lehrstunden[$i]->studiengang; $this->std_plan[$tag][$stunde][$idx]->stg_kz=$this->wochenplan->lehrstunden[$i]->studiengang_kz; @@ -736,7 +737,10 @@ class wochenplan extends basis_db { $unr[]=$lehrstunde->unr; // Lektoren - $lektor[]=$lehrstunde->lektor; + if ($lehrstunde->mitarbeiter_kurzbz === null) + $lektor[] = $lehrstunde->lektor; + else + $lektor[]=$lehrstunde->mitarbeiter_kurzbz; // Lehrverband $typ=''; if ($lehrstunde->reservierung) @@ -1450,7 +1454,10 @@ class wochenplan extends basis_db if ($lehrstunde->unr==$unr) { // Lektoren - $lektor[]=$lehrstunde->lektor; + if ($lehrstunde->mitarbeiter_kurzbz === null) + $lektor[] = $lehrstunde->lektor; + else + $lektor[]=$lehrstunde->mitarbeiter_kurzbz; // Lehrverband $lvb=$lehrstunde->stg.'-'.$lehrstunde->sem; if ($lehrstunde->ver!=null && $lehrstunde->ver!='0' && $lehrstunde->ver!='') @@ -2364,7 +2371,10 @@ class wochenplan extends basis_db $unr[]=$lehrstunde->unr; // Lektoren - $lektor[]=$lehrstunde->lektor; + if ($lehrstunde->mitarbeiter_kurzbz === null) + $lektor[] = $lehrstunde->lektor; + else + $lektor[]=$lehrstunde->mitarbeiter_kurzbz; $lektor_uids[]=$lehrstunde->lektor_uid; // Lehrverband $lvb=$lehrstunde->stg.'-'.$lehrstunde->sem; @@ -2516,6 +2526,7 @@ class wochenplan extends basis_db if (!mb_strstr($this->std_plan[$i][$j][$idx1]->lektor,$this->std_plan[$i][$j][$idx]->lektor)) { $this->std_plan[$i][$j][$idx]->lektor.=' / '.$this->std_plan[$i][$j][$idx1]->lektor; + $this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz.=' / '.$this->std_plan[$i][$j][$idx1]->mitarbeiter_kurzbz; } //Ort @@ -2549,7 +2560,7 @@ class wochenplan extends basis_db //"Betreff","Beginnt am","Beginnt um","Endet am","Endet um","Ganztaegiges Ereignis","Erinnerung Ein/Aus","Erinnerung am","Erinnerung um","Besprechungsplanung","Erforderliche Teilnehmer","Optionale Teilnehmer","Besprechungsressourcen","Abrechnungsinformationen","Beschreibung", //"Kategorien","Ort","Prioritaet","Privat","Reisekilometer","Vertraulichkeit","Zeitspanne zeigen als" echo $this->crlf.'"'.$this->std_plan[$i][$j][$idx]->lehrfach.(isset($this->std_plan[$i][$j][$idx]->lehrform) && $this->std_plan[$i][$j][$idx]->lehrform!=''?'-'.$this->std_plan[$i][$j][$idx]->lehrform:'').($lvb!=''?' - '.$lvb:'').'","'.$start_date.'","'.$start_time.'","'.$end_date.'","'.$end_time.'","Aus","Aus",,,,,,,,"Stundenplan'; - echo $this->crlf.$this->std_plan[$i][$j][$idx]->lehrfach.$this->crlf.$this->std_plan[$i][$j][$idx]->lektor.$this->crlf.$lvb.$this->crlf.$this->std_plan[$i][$j][$idx]->ort.(LVPLAN_ANMERKUNG_ANZEIGEN?$this->crlf.$this->std_plan[$i][$j][$idx]->anmerkung:'').'","StundenplanFH","'.$this->std_plan[$i][$j][$idx]->ort.'","Normal","Aus",,"Normal","2"'; + echo $this->crlf.$this->std_plan[$i][$j][$idx]->lehrfach.$this->crlf.(($this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz === null) ? $this->std_plan[$i][$j][$idx]->lektor : $this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz).$this->crlf.$lvb.$this->crlf.$this->std_plan[$i][$j][$idx]->ort.(LVPLAN_ANMERKUNG_ANZEIGEN?$this->crlf.$this->std_plan[$i][$j][$idx]->anmerkung:'').'","StundenplanFH","'.$this->std_plan[$i][$j][$idx]->ort.'","Normal","Aus",,"Normal","2"'; } elseif ($target=='ical') { @@ -2564,9 +2575,9 @@ class wochenplan extends basis_db $end_date_time_ical = $eda[2].$eda[1].$eda[0].'T'.sprintf('%02s',($eta[0])).$eta[1].$eta[2]; //neu gruppieren der Startzeit und des Startdatums echo $this->crlf.'BEGIN:VEVENT'.$this->crlf - .'UID:'.'FH'.str_replace(',',' ',$lvb.$this->std_plan[$i][$j][$idx]->ort.$this->std_plan[$i][$j][$idx]->lektor.$lehrfach[$idx].$start_date_time_ical.$end_date_time_ical.$this->crlf) + .'UID:'.'FH'.str_replace(',',' ',$lvb.$this->std_plan[$i][$j][$idx]->ort.(($this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz === null) ? $this->std_plan[$i][$j][$idx]->lektor : $this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz).$lehrfach[$idx].$start_date_time_ical.$end_date_time_ical.$this->crlf) .'SUMMARY:'.str_replace(',',' ',$lehrfach[$idx].' '.$this->std_plan[$i][$j][$idx]->ort.' - '.$lvb.$this->crlf) - .'DESCRIPTION:'.str_replace(',',' ',$lehrfach[$idx].'\n'.$this->std_plan[$i][$j][$idx]->lektor.'\n'.$lvb.'\n'.$this->std_plan[$i][$j][$idx]->ort.(LVPLAN_ANMERKUNG_ANZEIGEN?'\n'.$this->std_plan[$i][$j][$idx]->anmerkung:'').$this->crlf) + .'DESCRIPTION:'.str_replace(',',' ',$lehrfach[$idx].'\n'.(($this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz === null) ? $this->std_plan[$i][$j][$idx]->lektor : $this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz).'\n'.$lvb.'\n'.$this->std_plan[$i][$j][$idx]->ort.(LVPLAN_ANMERKUNG_ANZEIGEN?'\n'.$this->std_plan[$i][$j][$idx]->anmerkung:'').$this->crlf) .'LOCATION:'.$this->std_plan[$i][$j][$idx]->ort.$this->crlf .'CATEGORIES:'.$lvplan_kategorie.$this->crlf .'DTSTART;TZID=Europe/Vienna:'.$start_date_time_ical.$this->crlf @@ -2606,9 +2617,9 @@ class wochenplan extends basis_db $start_date_time_ical = $sda[2].$sda[1].$sda[0].'T'.sprintf('%02s',($sta[0])).$sta[1].$sta[2]; //neu gruppieren der Startzeit und des Startdatums $end_date_time_ical = $eda[2].$eda[1].$eda[0].'T'.sprintf('%02s',($eta[0])).$eta[1].$eta[2]; //neu gruppieren der Startzeit und des Startdatums - $UID = 'FH'.$lvb.$this->std_plan[$i][$j][$idx]->ort.$this->std_plan[$i][$j][$idx]->lektor.$lehrfach[$idx].$start_date_time_ical.$end_date_time_ical; + $UID = 'FH'.$lvb.$this->std_plan[$i][$j][$idx]->ort.(($this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz === null) ? $this->std_plan[$i][$j][$idx]->lektor : $this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz).$lehrfach[$idx].$start_date_time_ical.$end_date_time_ical; $Summary = $lehrfach[$idx].' '.$this->std_plan[$i][$j][$idx]->ort.' - '.$lvb; - $description = $lehrfach[$idx].'\n'.$this->std_plan[$i][$j][$idx]->lektor.'\n'.$lvb.'\n'.$this->std_plan[$i][$j][$idx]->ort.(LVPLAN_ANMERKUNG_ANZEIGEN?'\n'.$this->std_plan[$i][$j][$idx]->anmerkung:''); + $description = $lehrfach[$idx].'\n'.(($this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz === null) ? $this->std_plan[$i][$j][$idx]->lektor : $this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz).'\n'.$lvb.'\n'.$this->std_plan[$i][$j][$idx]->ort.(LVPLAN_ANMERKUNG_ANZEIGEN?'\n'.$this->std_plan[$i][$j][$idx]->anmerkung:''); $UID = str_replace(',',' ',$UID); $Summary = str_replace(',',' ',$Summary); @@ -2646,7 +2657,7 @@ class wochenplan extends basis_db else { echo $this->crlf.'"'.$lehrfach[$idx].'","'.$lvplan_kategorie.'","'.$this->std_plan[$i][$j][$idx]->ort.'","Stundenplan'.$this->crlf.$this->std_plan[$i][$j][$idx]->lehrfach.$this->crlf; - echo $this->std_plan[$i][$j][$idx]->lektor.$this->crlf.$lvb.$this->crlf.$this->std_plan[$i][$j][$idx]->ort.(LVPLAN_ANMERKUNG_ANZEIGEN?$this->crlf.$this->std_plan[$i][$j][$idx]->anmerkung:'').'","Stundenplan",'; + echo (($this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz === null) ? $this->std_plan[$i][$j][$idx]->lektor : $this->std_plan[$i][$j][$idx]->mitarbeiter_kurzbz).$this->crlf.$lvb.$this->crlf.$this->std_plan[$i][$j][$idx]->ort.(LVPLAN_ANMERKUNG_ANZEIGEN?$this->crlf.$this->std_plan[$i][$j][$idx]->anmerkung:'').'","Stundenplan",'; echo '"'.$start_date.'","'.$start_time.'","'.$end_date.'","'.$end_time.'",,,,,'; } } diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index bc8152a90..66645fb0e 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -32,6 +32,7 @@ require_once('dbupdate_3.4/26173_index_webservicelog.php'); require_once('dbupdate_3.4/24682_reihungstest_zugangscode_fuer_login.php'); require_once('dbupdate_3.4/17512_fehlercode_constraints.php'); require_once('dbupdate_3.4/19154_beurteilungsformulare_pruefungssenat.php'); +require_once('dbupdate_3.4/10001_tempus_mitarbeiter_kurzbz_bei_reservierungen_anzeigen.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; diff --git a/system/dbupdate_3.4/10001_tempus_mitarbeiter_kurzbz_bei_reservierungen_anzeigen.php b/system/dbupdate_3.4/10001_tempus_mitarbeiter_kurzbz_bei_reservierungen_anzeigen.php new file mode 100644 index 000000000..0ccf85762 --- /dev/null +++ b/system/dbupdate_3.4/10001_tempus_mitarbeiter_kurzbz_bei_reservierungen_anzeigen.php @@ -0,0 +1,130 @@ +db_query("SELECT mitarbeiter_kurzbz FROM lehre.vw_stundenplandev")) +{ + $qry = " + CREATE OR REPLACE VIEW lehre.vw_stundenplandev + (stundenplandev_id, unr, uid, lehreinheit_id, lehrfach_id, datum, stunde, ort_kurzbz, studiengang_kz, + semester, verband, gruppe, gruppe_kurzbz, titel, anmerkung, fix, lehrveranstaltung_id, stg_kurzbz, + stg_kurzbzlang, stg_bezeichnung, stg_typ, fachbereich_kurzbz, lehrfach, lehrfach_bez, farbe, lehrform, + lektor, updateamum, updatevon, insertamum, insertvon, anmerkung_lehreinheit, mitarbeiter_kurzbz) + AS + SELECT tbl_stundenplandev.stundenplandev_id, + tbl_stundenplandev.unr, + tbl_stundenplandev.mitarbeiter_uid AS uid, + tbl_stundenplandev.lehreinheit_id, + tbl_lehreinheit.lehrfach_id, + tbl_stundenplandev.datum, + tbl_stundenplandev.stunde, + tbl_stundenplandev.ort_kurzbz, + tbl_stundenplandev.studiengang_kz, + tbl_stundenplandev.semester, + tbl_stundenplandev.verband, + tbl_stundenplandev.gruppe, + tbl_stundenplandev.gruppe_kurzbz, + tbl_stundenplandev.titel, + tbl_stundenplandev.anmerkung, + tbl_stundenplandev.fix, + tbl_lehreinheit.lehrveranstaltung_id, + tbl_studiengang.kurzbz AS stg_kurzbz, + tbl_studiengang.kurzbzlang AS stg_kurzbzlang, + tbl_studiengang.bezeichnung AS stg_bezeichnung, + tbl_studiengang.typ AS stg_typ, + (SELECT tbl_fachbereich.fachbereich_kurzbz + FROM tbl_fachbereich + WHERE tbl_fachbereich.oe_kurzbz::text = lehrfach.oe_kurzbz::text) AS fachbereich_kurzbz, + lehrfach.kurzbz AS lehrfach, + lehrfach.bezeichnung AS lehrfach_bez, + lehrfach.farbe, + tbl_lehreinheit.lehrform_kurzbz AS lehrform, + tbl_mitarbeiter.kurzbz AS lektor, + tbl_stundenplandev.updateamum, + tbl_stundenplandev.updatevon, + tbl_stundenplandev.insertamum, + tbl_stundenplandev.insertvon, + tbl_lehreinheit.anmerkung AS anmerkung_lehreinheit, + tbl_mitarbeiter.kurzbz AS mitarbeiter_kurzbz + FROM lehre.tbl_stundenplandev + JOIN tbl_studiengang USING (studiengang_kz) + JOIN lehre.tbl_lehreinheit USING (lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung lehrfach ON tbl_lehreinheit.lehrfach_id = lehrfach.lehrveranstaltung_id + JOIN tbl_mitarbeiter USING (mitarbeiter_uid) + JOIN tbl_benutzer ON mitarbeiter_uid = uid + JOIN tbl_person USING(person_id); + "; + + if (!$db->db_query($qry)) + echo 'lehre.vw_stundenplandev: ' . $db->db_last_error() . '
'; + else + echo 'lehre.vw_stundenplandev: Neue Spalte mitarbeiter_kurzbz hinzugefuegt
'; +} + +// lehre.vw_stundenplan erweitern +if (!$result = @$db->db_query("SELECT mitarbeiter_kurzbz FROM lehre.vw_stundenplan")) +{ + $qry = "CREATE OR REPLACE VIEW lehre.vw_stundenplan AS + SELECT + tbl_stundenplan.stundenplan_id, tbl_stundenplan.unr, tbl_stundenplan.mitarbeiter_uid AS uid, + tbl_stundenplan.lehreinheit_id, tbl_lehreinheit.lehrfach_id AS lehrfach_id, tbl_stundenplan.datum, + tbl_stundenplan.stunde, tbl_stundenplan.ort_kurzbz, tbl_stundenplan.studiengang_kz, + tbl_stundenplan.semester, tbl_stundenplan.verband, tbl_stundenplan.gruppe, tbl_stundenplan.gruppe_kurzbz, + tbl_stundenplan.titel, tbl_stundenplan.anmerkung, tbl_stundenplan.fix, tbl_lehreinheit.lehrveranstaltung_id, + tbl_studiengang.kurzbz AS stg_kurzbz, tbl_studiengang.kurzbzlang AS stg_kurzbzlang, + tbl_studiengang.bezeichnung AS stg_bezeichnung, tbl_studiengang.typ AS stg_typ, + (SELECT fachbereich_kurzbz FROM public.tbl_fachbereich WHERE oe_kurzbz=lehrfach.oe_kurzbz) as fachbereich_kurzbz, + lehrfach.kurzbz AS lehrfach, lehrfach.bezeichnung AS lehrfach_bez, lehrfach.farbe, + tbl_lehreinheit.lehrform_kurzbz AS lehrform, tbl_mitarbeiter.kurzbz AS lektor, + tbl_stundenplan.updateamum, tbl_stundenplan.updatevon, tbl_stundenplan.insertamum, + tbl_stundenplan.insertvon, tbl_lehreinheit.anmerkung AS anmerkung_lehreinheit, + tbl_mitarbeiter.kurzbz as mitarbeiter_kurzbz + FROM lehre.tbl_stundenplan + JOIN public.tbl_studiengang USING (studiengang_kz) + JOIN lehre.tbl_lehreinheit USING (lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung as lehrfach ON (tbl_lehreinheit.lehrfach_id=lehrfach.lehrveranstaltung_id) + JOIN public.tbl_mitarbeiter USING (mitarbeiter_uid) + JOIN tbl_benutzer ON mitarbeiter_uid = uid + JOIN tbl_person USING(person_id);"; + + if (!$db->db_query($qry)) + echo 'lehre.vw_stundenplan: ' . $db->db_last_error() . '
'; + else + echo 'lehre.vw_stundenplan: Neue Spalte mitarbeiter_kurzbz hinzugefuegt
'; +} + +// campus.vw_reservierung erweitern +if (!$result = @$db->db_query("SELECT mitarbeiter_kurzbz FROM campus.vw_reservierung")) +{ + $qry = "CREATE OR REPLACE view campus.vw_reservierung + (reservierung_id, ort_kurzbz, studiengang_kz, uid, stunde, datum, titel, beschreibung, semester, verband, + gruppe, gruppe_kurzbz, stg_kurzbz, insertamum, insertvon, mitarbeiter_kurzbz) + AS + SELECT tbl_reservierung.reservierung_id, + tbl_reservierung.ort_kurzbz, + tbl_reservierung.studiengang_kz, + tbl_reservierung.uid, + tbl_reservierung.stunde, + tbl_reservierung.datum, + tbl_reservierung.titel, + tbl_reservierung.beschreibung, + tbl_reservierung.semester, + tbl_reservierung.verband, + tbl_reservierung.gruppe, + tbl_reservierung.gruppe_kurzbz, + tbl_studiengang.kurzbz AS stg_kurzbz, + tbl_reservierung.insertamum, + tbl_reservierung.insertvon, + tbl_mitarbeiter.kurzbz as mitarbeiter_kurzbz + FROM campus.tbl_reservierung + JOIN tbl_studiengang USING (studiengang_kz) + LEFT JOIN tbl_benutzer ON tbl_reservierung.uid = tbl_benutzer.uid + LEFT JOIN tbl_mitarbeiter ON tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid + LEFT JOIN tbl_person USING (person_id);"; + + if (!$db->db_query($qry)) + echo 'campus.vw_reservierung: ' . $db->db_last_error() . '
'; + else + echo 'campus.vw_reservierung: Neue Spalte mitarbeiter_kurzbz hinzugefuegt
'; +} + From a63a79ab91a2a2233e974328ad0e7ff0efc327ae Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Fri, 7 Apr 2023 14:10:30 +0200 Subject: [PATCH 139/439] add param tableOnly & save for multiple components on one page --- public/js/components/filter/Filter.js | 247 +++++++++++++++----------- 1 file changed, 142 insertions(+), 105 deletions(-) diff --git a/public/js/components/filter/Filter.js b/public/js/components/filter/Filter.js index e153042ad..7a46fd629 100644 --- a/public/js/components/filter/Filter.js +++ b/public/js/components/filter/Filter.js @@ -23,6 +23,8 @@ import {CoreFetchCmpt} from '../../components/Fetch.js'; const FILTER_COMPONENT_NEW_FILTER = 'Filter Component New Filter'; const FILTER_COMPONENT_NEW_FILTER_TYPE = 'Filter Component New Filter Type'; +var _uuid = 0; + /** * */ @@ -42,10 +44,12 @@ export const CoreFilterCmpt = { required: true }, tabulatorOptions: Object, - tabulatorEvents: Array + tabulatorEvents: Array, + tableOnly: Boolean }, data: function() { return { + uuid: 0, // FilterCmpt properties filterName: null, fields: null, @@ -54,7 +58,6 @@ export const CoreFilterCmpt = { selectedFields: null, notSelectedFields: null, filterFields: null, - columnsAlias: null, availableFilters: null, @@ -64,104 +67,136 @@ export const CoreFilterCmpt = { fetchCmptApiFunctionParams: null, fetchCmptDataFetched: null, - tabulator: null + tabulator: null, + tableBuilt: false }; }, - created: function() { - this.getFilter(); // get the filter data - }, - updated: function() { - // - let dataset = JSON.parse(JSON.stringify(this.dataset)); - let fields = JSON.parse(JSON.stringify(this.fields)); - let selectedFields = JSON.parse(JSON.stringify(this.selectedFields)); + computed: { + filteredData() { + if (!this.dataset) + return []; + return JSON.parse(JSON.stringify(this.dataset)); + }, + filteredColumns() { + let fields = JSON.parse(JSON.stringify(this.fields)) || []; + let selectedFields = JSON.parse(JSON.stringify(this.selectedFields)) || []; - // - let columns = null; + let columns = null; - // If the tabulator options has been provided and it contains the property columns - if (this.tabulatorOptions != null && this.tabulatorOptions.hasOwnProperty('columns')) - { - columns = this.tabulatorOptions.columns; - } + // If the tabulator options has been provided and it contains the property columns + if (this.tabulatorOptions && this.tabulatorOptions.hasOwnProperty('columns')) + columns = this.tabulatorOptions.columns; - // If columns is not an array or it is an array with less elements then the array fields - if (!Array.isArray(columns) || (Array.isArray(columns) && columns.length < fields.length)) - { - columns = []; // set it as an empty array - - // Loop throught all the retrieved columns from database - for (let i = 0; i < fields.length; i++) + // If columns is not an array or it is an array with less elements then the array fields + if (!Array.isArray(columns) || (Array.isArray(columns) && columns.length < fields.length)) { - // Create a new column having the title equal to the field name - let column = { - title: fields[i], - field: fields[i] - }; + columns = []; // set it as an empty array - // If the column has to be displayed or not - selectedFields.indexOf(fields[i]) >= 0 ? column.visible = true : column.visible = false; - - // Add the new column to the list of columns - columns.push(column); - } - } - else // the property columns has been provided in the tabulator options - { - // Loop throught the property columns of the tabulator options - for (let i = 0; i < columns.length; i++) - { - // If the column has to be displayed or not - selectedFields.indexOf(columns[i].field) >= 0 ? columns[i].visible = true : columns[i].visible = false; - - if (columns[i].hasOwnProperty('resizable')) + // Loop throught all the retrieved columns from database + for (let field of fields) { - columns[i].visible ? columns[i].resizable = true : columns[i].resizable = false; - } + // Create a new column having the title equal to the field name + let column = { + title: field, + field: field + }; + + // If the column has to be displayed or not + column.visible = selectedFields.indexOf(field) >= 0; + + // Add the new column to the list of columns + columns.push(column); + } } - } - - this.columnsAlias = columns; - - // Define a default tabulator options in case it was not provided - let tabulatorOptions = { - height: 500, - layout: "fitColumns", - movableColumns: true, - reactiveData: true, - columns: columns, - data: JSON.parse(JSON.stringify(this.dataset)) - }; - - // If it was provided - if (this.tabulatorOptions != null) - { - // Then copy it... - tabulatorOptions = this.tabulatorOptions; - // ...and overwrite the properties data, reactiveData, movableColumns and columns - tabulatorOptions.data = JSON.parse(JSON.stringify(this.dataset)); - tabulatorOptions.columns = columns; - tabulatorOptions.reactiveData = true; - tabulatorOptions.movableColumns = true; - } - - // Start the tabulator with the buid options - this.tabulator = new Tabulator( - "#filterTableDataset", - tabulatorOptions - ); - - // If event handlers have been provided - if (Array.isArray(this.tabulatorEvents) && this.tabulatorEvents.length > 0) - { - // Attach all the provided event handlers to the started tabulator - for (let i = 0; i < this.tabulatorEvents.length; i++) + else // the property columns has been provided in the tabulator options { - this.tabulator.on(this.tabulatorEvents[i].event, this.tabulatorEvents[i].handler); + // Loop throught the property columns of the tabulator options + for (let col of columns) + { + // If the column has to be displayed or not + col.visible = selectedFields.indexOf(col.field) >= 0; + + if (col.hasOwnProperty('resizable')) + col.resizable = col.visible; + } } + + return columns; + }, + fieldNames() { + if (!this.tableBuilt) + return {}; + return this.tabulator.getColumns().reduce((res, col) => { + res[col.getField()] = col.getDefinition().title; + return res; + }, {}); + }, + idExtra() { + if (!this.uuid) + return ''; + return '-' + this.uuid; } }, + beforeCreate() { + if (!this.tableOnly == !this.filterType) + console.warn('You can not have a filter-type in table-only mode!'); + }, + created() { + this.uuid = _uuid++; + if (!this.tableOnly) + this.getFilter(); // get the filter data + }, + mounted() { + this.initTabulator(); + }, methods: { + initTabulator() { + // Define a default tabulator options in case it was not provided + let tabulatorOptions = {...{ + height: 500, + layout: "fitColumns", + movableColumns: true, + reactiveData: true + }, ...(this.tabulatorOptions || {})}; + + if (!this.tableOnly) { + tabulatorOptions.data = this.filteredData; + tabulatorOptions.columns = this.filteredColumns; + } + + // Start the tabulator with the build options + this.tabulator = new Tabulator( + this.$refs.table, + tabulatorOptions + ); + // If event handlers have been provided + if (Array.isArray(this.tabulatorEvents) && this.tabulatorEvents.length > 0) + { + // Attach all the provided event handlers to the started tabulator + for (let evt of this.tabulatorEvents) + this.tabulator.on(evt.event, evt.handler); + } + this.tabulator.on('tableBuilt', () => this.tableBuilt = true); + if (this.tableOnly) { + this.tabulator.on('tableBuilt', () => { + const cols = this.tabulator.getColumns(); + this.fields = cols.map(col => col.getField()); + this.selectedFields = cols.filter(col => col.isVisible()).map(col => col.getField()); + }); + } + }, + updateTabulator() { + if (this.tabulator) { + if (this.tableBuilt) + this._updateTabulator(); + else + this.tabulator.on('tableBuilt', this._updateTabulator); + } + }, + _updateTabulator() { + this.tabulator.setData(this.filteredData); + this.tabulator.setColumns(this.filteredColumns); + }, /** * */ @@ -209,6 +244,7 @@ export const CoreFilterCmpt = { { this.setDropDownMenu(data); } + this.updateTabulator(); } else { @@ -335,7 +371,7 @@ export const CoreFilterCmpt = { this.startFetchCmpt( CoreFilterAPIs.saveCustomFilter, { - customFilterName: document.getElementById('customFilterName').value + customFilterName: this.$refscustomFilterName.value }, this.getFilter ); @@ -463,22 +499,22 @@ export const CoreFilterCmpt = { /* * */ - handlerToggleSelectedField: function(event) { + handlerToggleSelectedField(field) { // If it is a selected field - if (this.selectedFields.indexOf(event.target.innerText) != -1) + if (this.selectedFields.indexOf(field) != -1) { // then hide it - this.tabulator.hideColumn(event.target.innerText); + this.tabulator.hideColumn(field); // and remove it from the this.selectedFields property - this.selectedFields.splice(this.selectedFields.indexOf(event.target.innerText), 1); + this.selectedFields.splice(this.selectedFields.indexOf(field), 1); } else // otherwise { // show it - this.tabulator.showColumn(event.target.innerText); + this.tabulator.showColumn(field); // and add it to the this.selectedFields property - this.selectedFields.push(event.target.innerText); + this.selectedFields.push(field); } }, /** @@ -527,6 +563,7 @@ export const CoreFilterCmpt = { template: `
-
+
- [ {{ filterName }} ] - - + [ {{ filterName }} ] + +
-
+
@@ -558,9 +595,9 @@ export const CoreFilterCmpt = {
- {{ fieldToDisplay }} + {{ fieldNames[fieldToDisplay] || fieldToDisplay }}
@@ -568,7 +605,7 @@ export const CoreFilterCmpt = {
-
+
@@ -591,7 +628,7 @@ export const CoreFilterCmpt = {
-
+
+
+ ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/Actions.js b/public/js/components/Studierendenantrag/Leitung/Actions.js new file mode 100644 index 000000000..71ada5c20 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Actions.js @@ -0,0 +1,87 @@ +import ActionsNew from './Actions/New.js'; +import ActionsColumns from './Actions/Columns.js'; +import Phrasen from '../../../mixins/Phrasen.js'; + +export default { + components: { + ActionsNew, + ActionsColumns + }, + mixins: [Phrasen], + props: { + selectedData: Array, + columns: Array, + stgL: Array, + stgA: Array + }, + emits: [ + 'reload', + 'download', + 'action:approve', + 'action:reject', + 'action:reopen' + ], + data() { + return { + currentStudent: '' + } + }, + computed: { + selectedCanBeApproved() { + if (!this.selectedData.length) + return false; + if (!this.selectedData.every(val => this.stgL.includes(val.studiengang_kz))) + return false; + return this.selectedData.filter(row => { + return (row.typ == 'Wiederholung' && row.status == 'Lvszugewiesen') || (row.typ != 'Wiederholung' && (row.status == 'Erstellt' || row.status == 'ErstelltStgl')); + }).length == this.selectedData.length; + }, + selectedCanBeRejected() { + if (!this.selectedData.length) + return false; + if (!this.selectedData.every(val => this.stgL.includes(val.studiengang_kz))) + return false; + return this.selectedData.filter(row => { + return (row.typ == 'Unterbrechung' && row.status == 'Erstellt'); + }).length == this.selectedData.length; + }, + selectedCanBeReopened() { + if (!this.selectedData.length) + return false; + if (!this.selectedData.every(val => this.stgA.includes(val.studiengang_kz))) + return false; + return this.selectedData.filter(row => { + return (row.typ == 'Wiederholung' && row.status == 'Verzichtet'); + }).length == this.selectedData.length; + }, + newUrl() { + return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + this.currentStudent; + } + }, + methods: { + hideModal() { + bootstrap.Modal.getInstance(this.$refs.modal).hide(); + } + }, + template: ` +
+
+ + + {{p.t('table', 'with_selected', {count: selectedData.length})}} + + + +
+
+ + +
+
+ +
+
+ ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/Actions/Columns.js b/public/js/components/Studierendenantrag/Leitung/Actions/Columns.js new file mode 100644 index 000000000..df2b2a0de --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Actions/Columns.js @@ -0,0 +1,25 @@ +export default { + props: { + columns: Array + }, + methods: { + toggleColumn(col) { + col.visible = !col.visible; + col.original.toggle() + }, + show() { + + } + }, + template: ` + + ` +} \ No newline at end of file diff --git a/public/js/components/Studierendenantrag/Leitung/Actions/New.js b/public/js/components/Studierendenantrag/Leitung/Actions/New.js new file mode 100644 index 000000000..8a98a6aa5 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Actions/New.js @@ -0,0 +1,118 @@ +import BsAlert from '../../../Bootstrap/Alert.js'; +import BsModal from '../../../Bootstrap/Modal.js'; +import Phrasen from '../../../../mixins/Phrasen.js'; + +export default { + components: { + BsModal + }, + mixins: [ + Phrasen + ], + emits: [ + 'reload' + ], + data() { + return { + data: [], + student: '', + stg: '' + } + }, + computed: { + newUrl() { + return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/lehre/Studierendenantrag/abmeldung/' + this.student; + }, + students() { + if (!this.stg) + return []; + if (!this.data[this.stg]) + return []; + return this.data[this.stg].studenten.sort( + (a, b) => a.nachname == b.nachname ? + a.vorname > b.vorname : + a.nachname > b.nachname + ); + }, + hasNoData() { + return !Object.values(this.data).length; + } + }, + methods: { + openForm() { + bootstrap.Modal.getInstance(this.$refs.modal).hide(); + BsModal.popup(Vue.h('iframe', { + src: this.newUrl, + class: 'position-absolute top-0 start-0 w-100 h-100' + }), { + dialogClass: 'modal-fullscreen' + }, this.p.t('studierendenantrag', 'antrag_header')).then(() => { + this.loadSelects(); + this.$emit('reload'); + }); + }, + loadSelects() { + return axios.get( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Abmeldung/getStudiengaengeAssistenz/' + ).then( + result => { + if (result.data.error) { + BsAlert.popup(result.data.retval, {dialogClass: 'alert alert-danger'}); + } else { + this.data = result.data.retval; + } + return result; + } + ); + } + }, + created() { + return this.loadSelects(); + }, + template: ` +
+ + +
+ ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/GrundPopup.js b/public/js/components/Studierendenantrag/Leitung/GrundPopup.js new file mode 100644 index 000000000..d560dfb00 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/GrundPopup.js @@ -0,0 +1,62 @@ + +import BsAlert from '../../Bootstrap/Alert.js'; +import Phrasen from '../../../mixins/Phrasen.js'; + +export default { + mixins: [ + BsAlert, + Phrasen + ], + props: { + placeholder: String, + default: String + }, + data: () => ({ + value: '', + result: false, + check: false, + isInvalid: false + }), + methods: { + submit(){ + if(!this.value) { + this.isInvalid = true; + } + else { + this.result = [this.value, this.check]; + this.hide(); + } + return + } + }, + created() { + if (this.default) + this.value = this.default; + }, + popup(msg, options) { + if (typeof options === 'string') + options = { default: options }; + return BsAlert.popup.bind(this)(msg, options); + }, + template: ` + + + + ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/Header.js b/public/js/components/Studierendenantrag/Leitung/Header.js new file mode 100644 index 000000000..388a93b7d --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Header.js @@ -0,0 +1,24 @@ +import Phrasen from '../../../mixins/Phrasen.js'; + +export default { + mixins: [Phrasen], + props: { + stgs: Array + }, + emits: [ + 'input' + ], + template: ` +
+

{{p.t('studierendenantrag', 'studierendenantraege')}}

+
+ +
+
+ ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/LvPopup.js b/public/js/components/Studierendenantrag/Leitung/LvPopup.js new file mode 100644 index 000000000..045e98729 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/LvPopup.js @@ -0,0 +1,142 @@ +import BsAlert from '../../Bootstrap/Alert.js'; +import {CoreFetchCmpt} from "../../Fetch.js"; +import Phrasen from '../../../mixins/Phrasen.js'; + +export default { + components: { + CoreFetchCmpt + }, + mixins: [ + BsAlert, + Phrasen + ], + props: { + footer: Boolean, + antragId: Number, + countRemaining: Number + }, + data: () => ({ + lvs: null, + refresh: true, + result: false, + check: false + }), + computed: { + lvzugelassen() { + let zwischen = {}; + for (let k in this.lvs){ + zwischen[k] = this.lvs[k].filter(lv=>lv.antrag_zugelassen); + } + return zwischen; + }, + lvzugelassenLength() { + return Object.values(this.lvzugelassen).reduce((result, current) => result + current.length, 0); + } + }, + methods: { + setlvs(param) { + if(param.error) + { + this.$refs.fetchCompt.error = true; + this.$refs.fetchCompt.errorMessage = param.retval; + } + else + this.lvs = param.retval; + }, + loadlvs() { + if (!this.antragId) + return new Promise(() => {}); + return axios.get(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Antrag/Wiederholung/getLvs/' + this.antragId); + }, + submit(result) { + this.result = [result, this.check]; + this.hide(); + } + }, + watch: { + antragId() { + Vue.nextTick(() => { + this.refresh = !this.refresh; + }); + } + }, + popup(msg, options) { + if (typeof options === 'string') + options = { default: options }; + return BsAlert.popup.bind(this)(msg, options); + }, + template: ` + + + + ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/Table.js b/public/js/components/Studierendenantrag/Leitung/Table.js new file mode 100644 index 000000000..309678ae1 --- /dev/null +++ b/public/js/components/Studierendenantrag/Leitung/Table.js @@ -0,0 +1,388 @@ +import BsModal from '../../Bootstrap/Modal.js'; +import {CoreFetchCmpt} from '../../Fetch.js'; +import LvPopup from './LvPopup.js'; +import Phrasen from '../../../mixins/Phrasen.js'; +import { dateFilter } from '../../../tabulator/filters/Dates.js'; + +export default { + components: { + BsModal, + CoreFetchCmpt, + LvPopup + }, + mixins: [Phrasen], + props: { + selectedData: Array, + columnData: Array, + stgL: Array, + stgA: Array + }, + emits: [ + 'update:columnData', + 'update:selectedData', + 'action:approve', + 'action:reject', + 'action:reopen', + 'action:object', + 'action:objectionDeny', + 'action:objectionApprove' + ], + data() { + return { + ajaxUrl: FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/getAntraege/', + table: null, + lastHistoryClickedId: null, + historyData: [], + lvsData: null + } + }, + methods: { + reload(stg) { + this.table.replaceData(this.ajaxUrl + (stg || '')); + }, + download() { + this.table.download("csv", "data.csv"); + }, + getHistory() { + if (this.lastHistoryClickedId === null) + return null; + return axios.get( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/getHistory/' + + this.lastHistoryClickedId + ).then(res => { + this.historyData = res.data.retval.sort((a, b) => a.insertamum > b.insertamum); + }); + }, + showHistoryGrund(grund) { + this.$refs.modalGrund.$el.addEventListener( + 'hidden.bs.modal', + this.$refs.history.show, + { + once: true + } + ); + this.$refs.modalGrundPre.innerHTML = grund; + }, + showLVs(data) { + this.lvsData = data; + this.$refs.lvList.show(); + } + }, + mounted() { + function dateFormatter (cell) { + let val = cell.getValue(); + if (!val) + return ''; + let date = new Date(val); + return date.toLocaleDateString(); + } + + this.table = new Tabulator(this.$refs.table, { + placeholder:"Keine zu bearbeitenden Datensätze", + movableColumns: true, + maxHeight: '50vh', + layout: "fitDataStretch", // TODO(chris): wont work when changed + ajaxURL: this.ajaxUrl, + persistence: { // NOTE(chris): do not store column titles + sort: true, //persist column sorting + filter: true, //persist filters + headerFilter: true, //persist header filters + group: true, //persist row grouping + page: true, //persist page + columns: ["width", "visible"], //persist columns + }, + persistenceID: 'studierendenantrag_leitung', + columns: [ + { + formatter: 'rowSelection', + titleFormatter: 'rowSelection', + titleFormatterParams: { + rowRange: 'active' + }, + hozAlign: 'center', + headerSort: false + }, + { + field: 'studierendenantrag_id', + title: '#' + }, + { + field: 'bezeichnung', + title: this.p.t('lehre', 'studiengang'), + headerFilter: 'list', + headerFilterParams: { + valuesLookup: true, + clearable: true, + autocomplete: true, + } + }, + { + field: 'orgform', + title: this.p.t('lehre', 'organisationsform'), + headerFilter: 'list', + headerFilterParams: { + valuesLookup: true, + clearable: true, + autocomplete: true, + } + }, + { + field: 'typ', + title: this.p.t('studierendenantrag', 'antrag_typ'), + headerFilter: 'list', + headerFilterParams: { + valuesLookup: true, + clearable: true, + autocomplete: true, + }, + formatter: (cell, formatterParams, onRendered) => { + return this.p.t('studierendenantrag','antrag_typ_' + cell.getValue()); + } + }, + { + field: 'statustyp', + title: this.p.t('studierendenantrag', 'antrag_status'), + headerFilter: 'list', + headerFilterParams: { + valuesLookup: true, + clearable: true, + autocomplete: true, + } + }, + { + field: 'matrikelnr', + title: this.p.t('person', 'personenkennzeichen'), + headerFilter: 'input' + }, + { + field: 'prestudent_id', + title: this.p.t('lehre', 'prestudent'), + headerFilter: 'input' + }, + { + field: 'name', + title: this.p.t('global', 'name'), + mutator: (value, data) => (data.vorname + ' ' + data.nachname).replace(/^\s*(.*)\s*$/, '$1'), + headerFilter: 'input' + }, + { + field: 'datum', + title: this.p.t('global', 'datum'), + formatter: dateFormatter, + headerFilterFunc: 'dates', + headerFilter: dateFilter + }, + { + field: 'datum_wiedereinstieg', + title: this.p.t('studierendenantrag', 'antrag_datum_wiedereinstieg'), + formatter: dateFormatter, + headerFilterFunc: 'dates', + headerFilter: dateFilter + }, + { + field: 'grund', + title: this.p.t('studierendenantrag', 'antrag_grund'), + formatter: (cell, formatterParams, onRendered) => { + let link = document.createElement('a'), + val = cell.getValue(); + link.href = "#modal-grund"; + link.setAttribute('data-bs-toggle', 'modal'); + link.innerHTML = this.p.t('studierendenantrag', 'antrag_grund'); + link.addEventListener('click', () => { + this.$refs.modalGrundPre.innerHTML = val; + }); + + return val ? link : ''; + } + }, + { + field: 'dms_id', + title: this.p.t('studierendenantrag', 'antrag_dateianhaenge'), + formatter: (cell, formatterParams, onRendered) => { + let val = cell.getValue(); + if (!val) + return ''; + return ' ' + this.p.t('studierendenantrag', 'antrag_anhang') + ''; + } + }, + { + field: 'actions', + formatter: (cell, formatterParams, onRendered) => { + let container = document.createElement('div'), + data = cell.getData(); + + container.className = "d-flex gap-2"; + + if((data.typ == 'Abmeldung' || data.typ == 'Unterbrechung') && (data.status == 'Genehmigt')) + { + // NOTE(chris): Download PDF + let button = document.createElement('a'); + button.innerHTML = ''; + button.className = "btn btn-outline-secondary"; + button.target = "_blank"; + button.href = FHC_JS_DATA_STORAGE_OBJECT.app_root + + 'content/pdfExport.php?xml=Antrag' + data.typ + '.xml.php&xsl=Antrag' + data.typ + '&id='+ data.studierendenantrag_id +'&output=pdf'; + container.append(button); + } + if(data.typ == 'Abmeldung' && data.status == 'GenehmigtStgl') + { + // NOTE(chris): Object + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_object'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click',() => this.$emit('action:object', [cell.getData()])); + container.append(button); + } + + if(data.typ == 'Abmeldung' && data.status == 'Beeinsprucht') + { + // NOTE(chris): Deny Objection + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_objection_deny'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click',() => this.$emit('action:objectionDeny', [cell.getData()])); + container.append(button); + + // NOTE(chris): Approve Objection + button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_objection_approve'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click',() => this.$emit('action:objectionApprove', [cell.getData()])); + container.append(button); + } + + if (this.stgA.includes(data.studiengang_kz)) + { + // NOTE(chris): Reopen + if (data.typ == 'Wiederholung' && data.status == 'Verzichtet') { + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_reopen'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click',() => this.$emit('action:reopen', [cell.getData()])); + container.append(button); + } + // NOTE(chris): Lv Zuweisen + if (data.typ == 'Wiederholung' && (data.status == 'Erstellt' || data.status == 'Lvszugewiesen')) { + let button = document.createElement('a'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_lvzuweisen'); + button.className = "btn btn-outline-secondary"; + button.href = FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/lehre/Antrag/Wiederholung/assistenz/' + + cell.getData().studierendenantrag_id + '/frame'; + button.onclick = e => { + e.preventDefault(); + BsModal.popup(Vue.h('iframe', { + src: button.href, + class: 'position-absolute top-0 start-0 w-100 h-100' + }), { + dialogClass: 'modal-fullscreen' + }, this.p.t('studierendenantrag', 'title_lvzuweisen', cell.getData())).then(() => { + this.$emit('reload'); + }); + }; + container.append(button); + } + } + + if (this.stgL.includes(data.studiengang_kz)) + { + // NOTE(chris): Approve + if ((data.typ == 'Wiederholung' && data.status == 'Lvszugewiesen') || (data.typ != 'Wiederholung' && (data.status == 'Erstellt' || data.status == 'ErstelltStgl'))) { + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_approve'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click', () => this.$emit('action:approve', [cell.getData()])); + container.append(button); + } + // NOTE(chris): Reject (Unterbrechung braucht grund) + if (data.status == 'Erstellt' && data.typ == 'Unterbrechung') { + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_reject'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click', () => this.$emit('action:reject', [cell.getData()])); + container.append(button); + } + } + + // NOTE(chris): Show LVs + if (data.typ == 'Wiederholung' && (data.status == 'Lvszugewiesen' || data.status == 'Genehmigt')) { + let button = document.createElement('button'); + button.innerHTML = this.p.t('studierendenantrag', 'btn_show_lvs'); + button.className = "btn btn-outline-secondary"; + button.addEventListener('click', () => this.showLVs(cell.getData())); + container.append(button); + } + + // TODO(chris): not yet perfect + onRendered(() => { + cell.getColumn().setWidth(true); + }); + + return container; + } + } + ] + }); + this.table.on("tableBuilt", () => { + let columns = this.table.getColumns(); + let columnData = []; + for (let col of columns) { + let def = col.getDefinition(); + if (def.title) { + columnData.push({ + title: def.title, + visible: col.isVisible(), + original: col + }); + } + } + this.$emit('update:columnData', columnData); + }); + this.table.on("rowSelectionChanged", data => { + this.$emit('update:selectedData', data); + }); + this.table.on("cellClick", (e, cell) => { + if (cell.getColumn().getField() == 'statustyp') { + this.lastHistoryClickedId = cell.getData().studierendenantrag_id; + this.$refs.historyLoader.fetchData(); + this.$refs.history.show(); + } + }); + }, + template: ` +
+
+ + +

+		
+ + + + + + + + + + +
{{(new Date(status.insertamum)).toLocaleString()}}{{status.insertvon}}{{status.typ}} + + {{p.t('studierendenantrag', 'antrag_grund')}} + +
+
+
+ + {{p.t('studierendenantrag', 'title_show_lvs', lvsData ? lvsData : {name: ''}) }} + +
+ ` +} diff --git a/public/js/components/Studierendenantrag/Lvzuweisung.js b/public/js/components/Studierendenantrag/Lvzuweisung.js new file mode 100644 index 000000000..cbc97b79e --- /dev/null +++ b/public/js/components/Studierendenantrag/Lvzuweisung.js @@ -0,0 +1,242 @@ +import StudierendenantragStatus from './Status.js'; +import Phrasen from '../../mixins/Phrasen.js'; + +export default { + components: { + StudierendenantragStatus + }, + mixins: [Phrasen], + props: { + antragId: Number, + initialStatusCode: String, + initialStatusMsg: String, + disabled: Boolean + }, + data() { + return { + lvs: [], + isloading: false, + statusCode: '', + statusMsg: '' + } + }, + computed: { + lvs1() { + return this.lvs[Object.keys(this.lvs).filter(key => key.substr(0, 1) == 1)] || []; + }, + lvs2() { + return this.lvs[Object.keys(this.lvs).filter(key => key.substr(0, 1) == 2)] || []; + }, + lvs1sem(){ + return (Object.keys(this.lvs).filter(key => key.substr(0, 1) == 1).pop() || "1").substr(1); + }, + lvs2sem(){ + return (Object.keys(this.lvs).filter(key => key.substr(0, 1) == 2).pop() || "2").substr(1); + }, + statusSeverity() { + switch (this.statusCode) { + case 0: return 'danger'; + default: return 'info'; + } + } + }, + methods: { + save() { + this.isloading = true; + const forbiddenLvs = this.lvs1.filter(lv => lv.antrag_zugelassen && !lv._children).map(lv => ({ + studierendenantrag_id: this.antragId, + lehrveranstaltung_id: lv.lehrveranstaltung_id, + zugelassen: 0, + anmerkung: lv.antrag_anmerkung || "", + studiensemester_kurzbz: this.lvs1sem + })); + const mandatoryLvs = this.lvs2.filter(lv => !lv._children).map(lv => ({ + studierendenantrag_id: this.antragId, + lehrveranstaltung_id: lv.lehrveranstaltung_id, + zugelassen:lv.antrag_zugelassen ? 1 : 2, + anmerkung: lv.antrag_anmerkung || "", + studiensemester_kurzbz: this.lvs2sem + })); + axios.post(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Antrag/Wiederholung/saveLvs/', {forbiddenLvs, mandatoryLvs}) + .then(response => { + if(!response.data.error) { + this.addAlert('Speichern erfolgreich', 'alert-success'); + this.statusCode = response.data.retval[0].studierendenantrag_statustyp_kurzbz; + this.statusMsg = response.data.retval[0].typ; + } else { + this.addAlert(response.data.retval, 'alert-danger'); + this.statusCode = 0; + this.statusMsg = 'Error'; + } + this.isloading = false; + }).catch(error => { + this.addAlert(error.message, 'alert-danger'); + this.statusCode = 0; + this.statusMsg = 'Error'; + this.isloading = false; + }).finally(() => { + window.scrollTo(0, 0); + }); + }, + addAlert(text, type) { + const para = document.createElement("p"); + para.innerText = text; + para.className = "alert " + type + " alert-dismissible fade show"; + const btn = document.createElement("button"); + btn.className = "btn-close"; + btn.type = "button"; + btn.setAttribute("aria-label", "Close"); + btn.setAttribute("data-bs-dismiss", "alert"); + para.appendChild(btn); + + this.$refs.alertbox.appendChild(para); + } + }, + created() { + this.statusCode = this.initialStatusCode; + this.statusMsg = this.initialStatusMsg; + }, + mounted() { + axios.get(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Antrag/Wiederholung/getLvs/' + this.antragId).then( + result => { + if(result.data.error) + { + this.addAlert(result.data.retval, 'alert-danger'); + this.isloading = true; + } + else + { + let res = {}; + for (var k in result.data.retval) { + let lvs = result.data.retval[k].reduce((obj,lv) => { + obj[lv.studienplan_lehrveranstaltung_id] = lv; + return obj; + }, {}); + for (var lv of Object.values(lvs)) { + if (!lv.studienplan_lehrveranstaltung_id_parent) + continue; + if (!lvs[lv.studienplan_lehrveranstaltung_id_parent]) + console.error('parent not available'); + else { + if (!lvs[lv.studienplan_lehrveranstaltung_id_parent]._children) + lvs[lv.studienplan_lehrveranstaltung_id_parent]._children = []; + lvs[lv.studienplan_lehrveranstaltung_id_parent]._children.push(lv); + } + } + res[k] = Object.values(lvs).filter(lv => !lv.studienplan_lehrveranstaltung_id_parent); + let current = res[k]; + let index = k.substr(0,1); + var table = new Tabulator(this.$refs["lvtable" + k.substr(0,1)], { + data: current, + dataTree: true, + dataTreeStartExpanded:true, //start with an expanded tree + dataTreeChildIndent:15, + columns: [ + {title: this.p.t('ui','bezeichnung'), field: "bezeichnung"}, + {title: this.p.t('lehre','lehrform'), field: "lehrform_kurzbz"}, + {title: "ECTS", field: "ects"}, + {title: this.p.t('lehre','note'), field: "note", formatter:(cell, formatterParams, onRendered)=>cell.getValue() || "---"}, + {title: (index==1) ? this.p.t('studierendenantrag','lv_nicht_zulassen') : this.p.t('studierendenantrag','lv_wiederholen'), field: "antrag_zugelassen", formatter: (cell, formatterParams, onRendered) => { + let data = cell.getData(); + if(data._children || !data.zeugnis) + return ""; + let input = document.createElement('input'); + input.className = "form-check-input"; + input.type = "checkbox"; + input.role = "switch"; + input.checked = cell.getValue(); + input.addEventListener('input', () => { + lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen = input.checked; + cell.getRow().reformat(); + }); + if (this.disabled) { + input.disabled = true; + } + + let div = document.createElement('div'); + div.className = 'form-check form-switch'; + div.append(input); + + return div; + }}, + { + title: this.p.t('global','anmerkung'), + field: "antrag_anmerkung", + headerSort:false, + titleFormatter:(cell, formatterParams, onRendered)=>{ + let link = document.createElement('a'); + link.addEventListener('click', (e) => { + e.preventDefault(); + }); + + link.href ="#"; + link.title = this.p.t('studierendenantrag','anmerkung_tooltip'); + new bootstrap.Tooltip(link); + let tooltip = document.createElement('span'); + tooltip.innerHTML = this.p.t('global','anmerkung') + " "; + tooltip.append(link); + + let icon = document.createElement('i'); + link.append(icon); + icon.className = "fa fa-info-circle"; + icon.setAttribute("aria-hidden", "true"); + icon.style.minWidth = '1em'; + + return tooltip; + + }, + formatter: (cell, formatterParams, onRendered) => { + if (this.disabled) { + return cell.getValue() || ""; + } + var data = cell.getData(); + if (lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen) + { + let input = document.createElement('input'); + input.className = "form-control"; + input.type = "text"; + input.value = cell.getValue() || ""; + input.addEventListener('input', () => { + lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen = input.value; + }); + return input; + } + else + { + return ""; + } + } + } + ] + }); + } + this.lvs = result.data.retval; + } + } + ); + }, + template: ` +
+
+ + + {{p.t('studierendenantrag', 'title_lv_nicht_zugelassen')}} + {{lvs1sem}} + +
+
+ + + {{p.t('studierendenantrag', 'title_lv_wiederholen')}} + {{lvs2sem}} + +
+
+ + +
+
+ +
+ ` +} diff --git a/public/js/components/Studierendenantrag/Status.js b/public/js/components/Studierendenantrag/Status.js new file mode 100644 index 000000000..7449fd376 --- /dev/null +++ b/public/js/components/Studierendenantrag/Status.js @@ -0,0 +1,15 @@ +export default { + props: { + msg: String, + severity: String + }, + computed: { + severityClass() { + return 'alert-' + this.severity; + } + }, + template: ` + + ` +} diff --git a/public/js/components/vueDatepicker.js.php b/public/js/components/vueDatepicker.js.php new file mode 100644 index 000000000..e0814ac53 --- /dev/null +++ b/public/js/components/vueDatepicker.js.php @@ -0,0 +1,12 @@ + e.category == category).reduce((res, elem) => { + if (!res[elem.phrase]) + res[elem.phrase] = elem.text; + return res; + }, {}); +} +function reloadRefs(category) { + while (loadingModules[category].length) { + var v = loadingModules[category].pop(); + v[0].value = getValueForLoadedPhrase(category, v[1], v[2]); + Vue.triggerRef(v[0]); + /*Vue.unref(v);*/ + } +} +function loadLazy(category, val, phrase, params) { + // NOTE(chris): load module if it's not loaded yet + if (loadingModules[category]) { + loadingModules[category].push([val, phrase, params]); + if (categories[category]) // NOTE(chris): this is for safety in case the loading finished the moment before the val was pushed into the array + reloadRefs(category); + return; + } + loadingModules[category] = [[val, phrase, params]]; + + axios.get(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/components/Phrasen/loadModule/' + category).then(res => { + if (res.data.retval) + categories[category] = extractCategory(res.data.retval, category); + else + categories[category] = {}; + + reloadRefs(category); + }).catch(err => console.error(err)); +} +function getValueForLoadedPhrase(category, phrase, params) { + let result = categories[category][phrase]; + if (!result) + return '<< PHRASE ' + phrase + '>>'; + if (params) + result = result.replace(/\{([^}]*)\}/g, (match, p1) => params[p1] === undefined ? match : params[p1]); + return result; +} + +const phrasen = { + t_ref(category, phrase, params) { + if (params === undefined && ( + (Array.isArray(category) && category.length == 2) || + (category.split && category.split('/').length == 2)) + ) { + params = phrase; + [category, phrase] = category.split ? category.split('/') : category; + } + if (phrase === undefined) { + console.error('invalid input'); + return ''; + } + if (!categories[category]) { + if (window.FHC_JS_PHRASES_STORAGE_OBJECT !== undefined) + categories[category] = extractCategory(FHC_JS_PHRASES_STORAGE_OBJECT, category); + + if (!categories[category] || Object.keys(categories[category]).length === 0) { + categories[category] = undefined; + let val = Vue.ref(''); + loadLazy(category, val, phrase, params); + return val; + } + } + var result = getValueForLoadedPhrase(category, phrase, params); + return Vue.ref(result); + }, + t(category, phrase, params) { + return Vue.unref(this.t_ref(category, phrase, params)); + } +}; + +export default { + data: () => { + return { + p: phrasen + } + } +} diff --git a/public/js/tabulator/filters/Dates.js b/public/js/tabulator/filters/Dates.js new file mode 100644 index 000000000..7c9f268f0 --- /dev/null +++ b/public/js/tabulator/filters/Dates.js @@ -0,0 +1,43 @@ +if (!primevue) { + console.error('PrimeVue not loaded!'); +} + +// NOTE(chris): Click on clear button gives an error. This is a bug in primevue => fixed in current version +Tabulator.extendModule('filter', 'filters', { + "dates": (headerValue, rowValue) => { + if (!headerValue) + return true; + let v = new Date(rowValue); + if (Array.isArray(headerValue)) { + if (headerValue[1]) { + return v >= headerValue[0] && v <= headerValue[1].setHours(23, 59, 59, 999); + } + return v.toDateString() == headerValue[0].toDateString(); + } + return v.toDateString() == headerValue.toDateString(); + } +}); +function dateFilter(cell, onRendered, success) { + let div = document.createElement('div'); + + Vue.createApp({ + components: { + PrimevueCalendar: primevue.calendar + }, + data() { + return { + val: null + } + }, + watch: { + val(n) { + success(n); + } + }, + template: `` + }).use(primevue.config.default).mount(div); + + return div; +} + +export { dateFilter as 'dateFilter' }; diff --git a/rdf/AntragAbmeldung.xml.php b/rdf/AntragAbmeldung.xml.php new file mode 100644 index 000000000..b89fa51df --- /dev/null +++ b/rdf/AntragAbmeldung.xml.php @@ -0,0 +1,68 @@ +db_add_param($id) . " + AND campus.tbl_studierendenantrag.typ = 'Abmeldung' AND campus.get_status_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = 'Genehmigt';"; + $not_found_error = 'Studierendenantrag not found'. $id; + } elseif(isset($_GET['uid']) && isset($_GET['prestudent_id'])) { + $uid = $_GET['uid']; + $uid = explode(';', $uid); + $uid = (array_filter($uid, 'strlen')); + + $prestudent_id = $_GET['prestudent_id']; + $prestudent_id = explode(';', $prestudent_id); + $prestudent_id = (array_filter($prestudent_id, 'strlen')); + + $where = " WHERE campus.tbl_studierendenantrag.prestudent_id in (" . $db->db_implode4SQL($prestudent_id) . ") + AND campus.tbl_studierendenantrag.typ = 'Abmeldung' AND campus.get_status_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = 'Genehmigt';"; + $not_found_error = 'Studierendenantrag not found for: ' . implode(',', $uid); + } else + die('wrong parameters'); +} +else + die('Format not supported'); + + +// TODO(chris): mehrsprachig +$query = " + SELECT tbl_studiengang.bezeichnung, bezeichnung_mehrsprachig[1], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, vorname, nachname, studiengang_kz, semester, tbl_studierendenantrag.grund + FROM + campus.tbl_studierendenantrag + JOIN public.tbl_student USING (prestudent_id) + JOIN public.tbl_benutzer ON tbl_student.student_uid=uid + JOIN public.tbl_person USING (person_id) + JOIN public.tbl_studiengang USING (studiengang_kz) + JOIN public.tbl_studiensemester USING (studiensemester_kurzbz) + JOIN bis.tbl_orgform ON (tbl_orgform.orgform_kurzbz = tbl_studiengang.orgform_kurzbz)" . $where; + + +if (!$db->db_query($query) || !$db->db_num_rows()) + die('' . $not_found_error . ''); + +?> + + + db_fetch_object()) { ?> + + bezeichnung;?> + bezeichnung_mehrsprachig;?> + vorname. " " . $row->nachname);?> + matrikelnr;?> + studienjahr_kurzbz;?> + semester;?> + grund;?> + + + diff --git a/rdf/AntragUnterbrechung.xml.php b/rdf/AntragUnterbrechung.xml.php new file mode 100644 index 000000000..50c9f4c6a --- /dev/null +++ b/rdf/AntragUnterbrechung.xml.php @@ -0,0 +1,71 @@ +db_add_param($id) . " + AND campus.tbl_studierendenantrag.typ = 'Unterbrechung' AND campus.get_status_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = 'Genehmigt';"; + $not_found_error = 'Studierendenantrag not found'. $id; + } elseif(isset($_GET['uid']) && isset($_GET['prestudent_id'])) { + $uid = $_GET['uid']; + $uid = explode(';', $uid); + $uid = (array_filter($uid, 'strlen')); + + $prestudent_id = $_GET['prestudent_id']; + $prestudent_id = explode(';', $prestudent_id); + $prestudent_id = (array_filter($prestudent_id, 'strlen')); + + $where = " WHERE campus.tbl_studierendenantrag.prestudent_id in (" . $db->db_implode4SQL($prestudent_id) . ") + AND campus.tbl_studierendenantrag.typ = 'Unterbrechung' AND campus.get_status_studierendenantrag(campus.tbl_studierendenantrag.studierendenantrag_id) = 'Genehmigt';"; + $not_found_error = 'Studierendenantrag not found for: ' . implode(',', $uid); + } else + die('wrong parameters'); +} +else + die('Format not supported'); + + +// TODO(chris): mehrsprachig +$query = " + SELECT tbl_studiengang.bezeichnung, bezeichnung_mehrsprachig[1], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, vorname, nachname, studiengang_kz, semester, tbl_studierendenantrag.grund, datum_wiedereinstieg, datum + FROM + campus.tbl_studierendenantrag + JOIN public.tbl_student USING (prestudent_id) + JOIN public.tbl_benutzer ON tbl_student.student_uid=uid + JOIN public.tbl_person USING (person_id) + JOIN public.tbl_studiengang USING (studiengang_kz) + JOIN public.tbl_studiensemester USING (studiensemester_kurzbz) + JOIN bis.tbl_orgform ON (tbl_orgform.orgform_kurzbz = tbl_studiengang.orgform_kurzbz)" . $where; + + +if (!$db->db_query($query) || !$db->db_num_rows()) + die('' . $not_found_error . ''); + +?> + + + db_fetch_object()) { ?> + + bezeichnung;?> + bezeichnung_mehrsprachig;?> + vorname. " " . $row->nachname);?> + matrikelnr;?> + studienjahr_kurzbz;?> + semester;?> + grund;?> + datum_wiedereinstieg))->format('d.m.Y');?> + datum))->format('d.m.Y');?> + + + diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index 9fda09bba..013972154 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -39,6 +39,7 @@ require_once('dbupdate_3.4/27107_vilesci_erfassung_abwesenheiten_reinigung.php') require_once('dbupdate_3.4/24913_tabelle_raumtyp_neues_attribut_aktiv.php'); require_once('dbupdate_3.4/28089_plausichecks_in_extension_hinzufuegen.php'); require_once('dbupdate_3.4/29133_einzelne_studiengaenge_aus_issuechecks_ausnehmen.php'); +require_once('dbupdate_3.4/27351_digitalisierung_formulare.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; diff --git a/system/dbupdate_3.4/27351_digitalisierung_formulare.php b/system/dbupdate_3.4/27351_digitalisierung_formulare.php new file mode 100644 index 000000000..a40b457e2 --- /dev/null +++ b/system/dbupdate_3.4/27351_digitalisierung_formulare.php @@ -0,0 +1,289 @@ +db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statustyp LIMIT 1")) +{ + $qry = "CREATE TABLE campus.tbl_studierendenantrag_statustyp ( + studierendenantrag_statustyp_kurzbz VARCHAR(32) NOT NULL, + bezeichnung VARCHAR(128)[] NOT NULL, + CONSTRAINT tbl_studierendenantrag_statustyp_pk PRIMARY KEY(studierendenantrag_statustyp_kurzbz) + ); + + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_statustyp TO vilesci; + GRANT SELECT ON campus.tbl_studierendenantrag_statustyp TO web;"; + + if(!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag_statustyp: '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag_statustyp: table created'; +} + +if($result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statustyp WHERE studierendenantrag_statustyp_kurzbz = 'Erstellt' ")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO campus.tbl_studierendenantrag_statustyp + (studierendenantrag_statustyp_kurzbz, bezeichnung) + VALUES + ('Erstellt', '{\"Erstellt\",\"Created\"}'), + ('ErstelltStgl', '{\"Erstellt\",\"Created\"}'), + ('Genehmigt', '{\"Genehmigt\",\"Approved\"}'), + ('GenehmigtStgl', '{\"Vorläufig Genehmigt\",\"Provisionally Approved\"}'), + ('Beeinsprucht', '{\"Beeinsprucht\",\"Objected\"}'), + ('Abgelehnt', '{\"Abgelehnt\",\"Rejected\"}'), + ('Verzichtet', '{\"Verzichtet\",\"Pass\"}'), + ('Offen', '{\"Offen\",\"Reopened\"}'), + ('Zurückgezogen', '{\"Zurückgezogen\",\"Cancelled\"}'), + ('EmailVersandt', '{\"Email Versandt\",\"Reminder Sent\"}'), + ('ErsteAufforderungVersandt', '{\"1.Aufforderung Versandt\",\"1st Request Sent\"}'), + ('ZweiteAufforderungVersandt', '{\"2.Aufforderung Versandt\",\"2nd Request Sent\"}'), + ('Lvszugewiesen', '{\"Lvszugewiesen\",\"Lvsassigned\"}'); + "; + if (!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag_statustyp (insert): '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag_statustyp: table prefilled'; + } +} + +if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag LIMIT 1")) +{ + $qry = "CREATE TABLE campus.tbl_studierendenantrag ( + studierendenantrag_id INTEGER NOT NULL, + prestudent_id INTEGER NOT NULL, + studiensemester_kurzbz VARCHAR(32) NOT NULL, + datum TIMESTAMP NULL, + typ VARCHAR(32) NOT NULL, + insertamum TIMESTAMP DEFAULT NOW(), + insertvon VARCHAR(32) NOT NULL, + datum_wiedereinstieg TIMESTAMP NULL, + grund TEXT NULL, + dms_id INTEGER NULL, + CONSTRAINT tbl_studierendenantrag_pk PRIMARY KEY(studierendenantrag_id) + ); + CREATE SEQUENCE campus.tbl_studierendenantrag_studierendenantrag_id_seq + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + ALTER TABLE campus.tbl_studierendenantrag ALTER COLUMN studierendenantrag_id SET DEFAULT nextval('campus.tbl_studierendenantrag_studierendenantrag_id_seq'); + + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag TO vilesci; + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag TO web; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_studierendenantrag_id_seq TO vilesci; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_studierendenantrag_id_seq TO web;"; + + if(!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag: '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag: table created'; +} + +if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_status LIMIT 1")) +{ + $qry = "CREATE TABLE campus.tbl_studierendenantrag_status ( + studierendenantrag_status_id INTEGER NOT NULL, + studierendenantrag_id INTEGER NOT NULL, + studierendenantrag_statustyp_kurzbz VARCHAR(32) NOT NULL, + insertamum TIMESTAMP DEFAULT NOW(), + insertvon VARCHAR(32) NOT NULL, + grund TEXT NULL, + CONSTRAINT tbl_studierendenantrag_status_pk PRIMARY KEY(studierendenantrag_status_id), + CONSTRAINT tbl_studierendenantrag_fk FOREIGN KEY (studierendenantrag_id) REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id) ON UPDATE CASCADE ON DELETE RESTRICT, + CONSTRAINT tbl_studierendenantrag_statustyp_fk FOREIGN KEY (studierendenantrag_statustyp_kurzbz) REFERENCES campus.tbl_studierendenantrag_statustyp(studierendenantrag_statustyp_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT + ); + CREATE SEQUENCE campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + ALTER TABLE campus.tbl_studierendenantrag_status ALTER COLUMN studierendenantrag_status_id SET DEFAULT nextval('campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq'); + + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_status TO vilesci; + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_status TO web; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq TO vilesci; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq TO web;"; + + if(!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag_status: '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag_status: table created'; +} + +if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_lehrveranstaltung LIMIT 1")) +{ + $qry = "CREATE TABLE campus.tbl_studierendenantrag_lehrveranstaltung ( + studierendenantrag_lehrveranstaltung_id INTEGER NOT NULL, + studierendenantrag_id INTEGER NOT NULL, + lehrveranstaltung_id INTEGER NOT NULL, + studiensemester_kurzbz VARCHAR(16) NOT NULL, + note SMALLINT NOT NULL, + anmerkung TEXT NULL, + insertamum TIMESTAMP DEFAULT NOW(), + insertvon VARCHAR(32) NOT NULL, + CONSTRAINT tbl_studierendenantrag_lehrveranstaltung_pk PRIMARY KEY(studierendenantrag_lehrveranstaltung_id), + CONSTRAINT tbl_studiensemester_fk FOREIGN KEY (studiensemester_kurzbz) REFERENCES public.tbl_studiensemester(studiensemester_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT, + CONSTRAINT tbl_note_fk FOREIGN KEY (note) REFERENCES lehre.tbl_note(note) ON UPDATE CASCADE ON DELETE RESTRICT, + CONSTRAINT tbl_studierendenantrag_fk FOREIGN KEY (studierendenantrag_id) REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id) ON UPDATE CASCADE ON DELETE RESTRICT + ); + CREATE SEQUENCE campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq + INCREMENT BY 1 + NO MAXVALUE + NO MINVALUE + CACHE 1; + ALTER TABLE campus.tbl_studierendenantrag_lehrveranstaltung ALTER COLUMN studierendenantrag_lehrveranstaltung_id SET DEFAULT nextval('campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq'); + + GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_lehrveranstaltung TO vilesci; + GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_lehrveranstaltung TO web; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq TO vilesci; + GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq TO web;"; + + if(!$db->db_query($qry)) + echo 'campus.tbl_studierendenantrag_lehrveranstaltung: '.$db->db_last_error().'
'; + else + echo '
campus.tbl_studierendenantrag_lehrveranstaltung: table created'; +} + +if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berechtigung_kurzbz = 'student/studierendenantrag';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('student/studierendenantrag', 'Berechtigung für Bearbeiten Studierendenanträge');"; + + if(!$db->db_query($qry)) + echo 'system.tbl_berechtigung '.$db->db_last_error().'
'; + else + echo ' system.tbl_berechtigung: Added permission for student/studierendenantrag
'; + } +} + +if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berechtigung_kurzbz = 'student/antragfreigabe';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('student/antragfreigabe', 'Berechtigung für Freigabe der Studierendenanträge');"; + + if(!$db->db_query($qry)) + echo 'system.tbl_berechtigung '.$db->db_last_error().'
'; + else + echo ' system.tbl_berechtigung: Added permission for student/antragfreigabe
'; + } +} + +if (!$result = @$db->db_query("SELECT campus.get_status_studierendenantrag(0)")) { + $qry = 'CREATE FUNCTION campus.get_status_studierendenantrag(integer) RETURNS character varying + LANGUAGE plpgsql + AS $_$ + DECLARE i_studierendenantrag_id ALIAS FOR $1; + DECLARE rec RECORD; + BEGIN + SELECT INTO rec studierendenantrag_statustyp_kurzbz + FROM campus.tbl_studierendenantrag_status + WHERE studierendenantrag_id=i_studierendenantrag_id + ORDER BY insertamum desc + LIMIT 1; + + RETURN rec.studierendenantrag_statustyp_kurzbz; + END; + $_$; + + ALTER FUNCTION campus.get_status_studierendenantrag(integer) OWNER TO fhcomplete;'; + + if(!$db->db_query($qry)) + echo 'campus.get_status_studierendenantrag(integer): '.$db->db_last_error().'
'; + else + echo '
campus.get_status_studierendenantrag(integer): function created'; +} + +if (!$result = @$db->db_query("SELECT campus.get_status_id_studierendenantrag(0)")) { + $qry = 'CREATE FUNCTION campus.get_status_id_studierendenantrag(integer) RETURNS integer + LANGUAGE plpgsql + AS $_$ + DECLARE i_studierendenantrag_id ALIAS FOR $1; + DECLARE rec RECORD; + BEGIN + SELECT INTO rec studierendenantrag_status_id + FROM campus.tbl_studierendenantrag_status + WHERE studierendenantrag_id=i_studierendenantrag_id + ORDER BY insertamum desc + LIMIT 1; + + RETURN rec.studierendenantrag_status_id; + END; + $_$; + + ALTER FUNCTION campus.get_status_id_studierendenantrag(integer) OWNER TO fhcomplete;'; + + if(!$db->db_query($qry)) + echo 'campus.get_status_id_studierendenantrag(integer): '.$db->db_last_error().'
'; + else + echo '
campus.get_status_id_studierendenantrag(integer): function created'; +} + +if (!$result = @$db->db_query("SELECT public.get_absem_prestudent(0, null)")) { + $qry = 'CREATE FUNCTION public.get_absem_prestudent(integer, character varying) RETURNS integer + LANGUAGE plpgsql + AS $_$ + DECLARE i_prestudent_id ALIAS FOR $1; + DECLARE cv_studiensemester_kurzbz ALIAS FOR $2; + DECLARE rec RECORD; + BEGIN + IF (cv_studiensemester_kurzbz IS NULL) THEN + SELECT INTO rec ausbildungssemester + FROM public.tbl_prestudentstatus + WHERE prestudent_id=i_prestudent_id + ORDER BY datum desc,insertamum desc, ext_id desc + LIMIT 1; + ELSE + SELECT INTO rec ausbildungssemester + FROM tbl_prestudentstatus + WHERE prestudent_id=i_prestudent_id AND studiensemester_kurzbz=cv_studiensemester_kurzbz + ORDER BY datum desc,insertamum desc, ext_id desc + LIMIT 1; + END IF; + + RETURN rec.ausbildungssemester; + END; + $_$; + + ALTER FUNCTION public.get_absem_prestudent(integer, character varying) OWNER TO fhcomplete;'; + + if(!$db->db_query($qry)) + echo 'public.get_absem_prestudent(integer, character varying): '.$db->db_last_error().'
'; + else + echo '
public.get_absem_prestudent(integer, character varying): function created'; +} +if (!$result = @$db->db_query("SELECT public.get_stdsem_prestudent(0, null)")) { + $qry = 'CREATE FUNCTION public.get_stdsem_prestudent(integer, character varying) RETURNS character varying + LANGUAGE plpgsql + AS $_$ + DECLARE i_prestudent_id ALIAS FOR $1; + DECLARE cv_studiensemester_kurzbz ALIAS FOR $2; + DECLARE rec RECORD; + BEGIN + IF (cv_studiensemester_kurzbz IS NULL) THEN + SELECT INTO rec studiensemester_kurzbz + FROM public.tbl_prestudentstatus + WHERE prestudent_id=i_prestudent_id + ORDER BY datum desc,insertamum desc, ext_id desc + LIMIT 1; + ELSE + SELECT INTO rec studiensemester_kurzbz + FROM tbl_prestudentstatus + WHERE prestudent_id=i_prestudent_id AND studiensemester_kurzbz=cv_studiensemester_kurzbz + ORDER BY datum desc,insertamum desc, ext_id desc + LIMIT 1; + END IF; + + RETURN rec.studiensemester_kurzbz; + END; + $_$; + + ALTER FUNCTION public.get_stdsem_prestudent(integer, character varying) OWNER TO fhcomplete;'; + + if(!$db->db_query($qry)) + echo 'public.get_stdsem_prestudent(integer, character varying): '.$db->db_last_error().'
'; + else + echo '
public.get_stdsem_prestudent(integer, character varying): function created'; +} diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 0bc748c80..f6df3afad 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -5774,6 +5774,26 @@ When on hold, the date is only a reminder.', ) ) ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'error_invalid_date', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Das Datumsformat ist ungültig oder liegt außerhalb des gültigen Bereichs.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The date format is invalid or out of range.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'ui', @@ -14446,6 +14466,26 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'schliessen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => "Schließen", + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => "Close", + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'global', @@ -18123,6 +18163,1750 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_0', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Gemäß § 16 Abs. 1 FHG steht Studierenden einmalig das Recht auf Wiederholung eines Studienjahres in Folge einer negativ beurteilten kommissionellen Prüfung zu.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'According to § 16 paragraph 1 FHG, students have the right to repeat an academic year as a result of a negative examination before a committee.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_1', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Die Wiederholung ist bei der Studiengangsleitung binnen eines Monats ab Mitteilung des negativen Prüfungsergebnisses bekannt zu geben.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The head of the degree program must be notified of the repetition within one month of notification of the negative examination result.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_2', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Infolge der Weiterentwicklung der Qualität des Studienganges kann es zu Änderungen der Studienbedingungen im Zuge der Wiederholung eines Studienjahres kommen (z.B. Studienplan, Prüfungsordnung etc.).', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'As a result of the further development of the quality of the course, there may be changes to the study conditions in the course of repeating an academic year (e.g. study plan, examination regulations, etc.).', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_3', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Die Studiengangsleitung legt Prüfungen und Lehrveranstaltungen für die Wiederholung des Studienjahres fest.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The head of the degree program determines examinations and courses for the repetition of the academic year.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'infotext_Wiederholung_4', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nicht bestandene Prüfungen und Lehrveranstaltungen sind jedenfalls, bestandene Prüfungen und Lehrveranstaltungen nur, sofern es der Zweck des Studiums erforderlich macht, zu wiederholen oder erneut zu besuchen. Wird eine Lehrveranstaltung nach der letzten Wiederholungsmöglichkeit negativ beurteilt, darf dieder Studierende an keiner kommissionellen Wiederholungsprüfung im Semester der negativ beurteilen Lehrveranstaltung und im Folgesemester mehr teilnehmen (nicht-kommissionelle Wiederholungsprüfungen können wahrgenommen werden)', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'In any case, failed examinations and courses are to be repeated or attended again only if the purpose of the course makes it necessary. If a course is assessed negatively after the last opportunity to repeat it, the student may no longer take part in a board re-examination in the semester in which the course was assessed as negative and in the following semester (non-board re-examinations can be taken).', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'info_Wiederholung_Erstellt', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Info für Wiederholung Erstellt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Info for Wiederholung Erstellt', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_Wiederholung_pruefung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Negativ beurteilte kommissionelle Prüfung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Negative assessment by a committee', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_Wiederholung_pruefung_date', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Datum der Beurteilung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'date of assessment', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_Wiederholung_button_yes', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ich gebe hiermit die Wiederholung des Studienjahres bekannt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'I hereby announce the repetition of the academic year', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_Wiederholung_button_no', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ich werde das Studienjahr nicht wiederholen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'I will not repeat the academic year', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antraege_header', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Anträge auf Änderung des Studierendenstatus', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Requests for changing the Studierendenstatus', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_header', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Antrag auf Änderung des Studierendenstatus', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Request for changing the Studierendenstatus', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_new', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Neu Anlegen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Create new', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'cancel', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abbrechen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Cancel', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'ok', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ok', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Ok', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_create', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Anlegen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Create', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_create_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Vom Studium abmelden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Deregister from your studies', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_create_Unterbrechung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Das Studium unterbrechen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Interrupt your studies', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_cancel', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Antrag zurückziehen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Cancel Application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'warning_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ihr CIS-Account ist noch 21 Tage aktiv. Wir bitten Sie, alle benötigten Dateien (Zeugnisse, Studienerfolgsbestätigungen, Studienbestätigungen, etc.) innerhalb dieses Zeitraums herunterzuladen. Für die Ausstellung von Duplikaten fallen nach Inaktivsetzung des CIS-Accounts Kosten an.' . "
\n" . + 'Bitte retournieren Sie baldmöglichst entlehnte Bücher an die Bibliothek.', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Your CIS account is still active for 21 days. We ask you to download all required files (certificates, confirmations of academic success, confirmation of studies, etc.) within this period. There is a charge for issuing duplicates after the CIS account has been deactivated.' . "
\n" . + 'Please return borrowed books to the library as soon as possible.', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abmeldung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'De-registration', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_Unterbrechung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Unterbrechung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Interruption', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_Wiederholung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Wiederholung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Repetition', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_new_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Neue Abmeldung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'New de-registration', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_typ', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Typ', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Type', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_status', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Status', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Status', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_studiensemester', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studiensemester', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Semester', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_erstelldatum', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Erstelldatum', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Createdate', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'studierendenantraege', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studierendenanträge', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Applications', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_datum_wiedereinstieg', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Datum Wiedereinstieg', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Date of return', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_grund', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Grund', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reason', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_dateianhaenge', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Dateianhänge', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Attachments', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_anhang', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Anhang', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Attachment', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_typ_Abmeldung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abmeldung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Deregistration', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_typ_Unterbrechung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Unterbrechung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Break', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'antrag_typ_Wiederholung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Wiederholung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Repetition', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_show_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'LVs anzeigen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Show LVs', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_edit', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Bearbeiten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Edit', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_reopen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Erneut Freischalten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reopen', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_object', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Beeinspruchen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Object', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_objection_deny', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Einspruch abgelehnt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Objection rejected', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_objection_approve', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Einspruch stattgegeben', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Objection granted', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_lvzuweisen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'LVs zuweisen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Assign Lvs', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_approve', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Genehmigen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Approve', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_reject', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ablehnen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reject', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'skip', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Überspringen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Skip', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'ui', + 'phrase' => 'select_studiensemester', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studiensemester auswählen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Select a semester', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_save_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zuweisungen speichern', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Save assignments', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'btn_download_antrag', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'PDF herunterladen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Download PDF', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'table', + 'phrase' => 'download', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Download', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Download', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'table', + 'phrase' => 'reload', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Tabelle neu laden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reload table', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_student', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Sie sind derzeit in keinem Studium', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'You are currently not enrolled', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_student_no_failed_exam', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Sie sind derzeit in keinem Studium oder haben keine negativ beurteilte kommissionelle Prüfung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'You are not currently studying or have not passed a board examination with negative reasons', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'no_attachments', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Dateianhänge', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No Attachments', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'prestudent', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Prestudent', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Prestudent', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'studienjahr', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Studienjahr', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Academic year', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_lvzuweisen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehrveranstaltungen zuweisen für {name}', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Assign Courses for {name}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_lv_nicht_zugelassen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Angabe aller Lehrveranstaltungen, zu denen die Person nicht zugelassen ist', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Details of all courses to which the person is not admitted', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_lv_wiederholen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Angabe aller zu wiederholenden bzw. erneut zu besuchenden Lehrveranstaltungen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Specification of all courses to be repeated or attended again', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_show_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehrveranstaltungen für {name}', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Courses for {name}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'my_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Meine Lehrveranstaltungen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'My Courses', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'table', + 'phrase' => 'with_selected', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Mit {count} ausgewählten: ', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'With {count} selected: ', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'lv_nicht_zulassen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Nicht zulassen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Don\'t allow ', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'lv_wiederholen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Wiederholen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Repeat', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_history', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Statusverlauf für Antrag #{id} ', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'History for Application #{id}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'anmerkung_tooltip', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Die Spalte Anmerkung kann verwendet werden, um Besonderheiten z.B. bei einem Studienplanwechsel zu dokumentieren (Änderung von LV-Titel, ECTS…) ', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The Comment column can be used to document special features, e.g. when changing the curriculum (change of course title, ECTS...)', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'fuer_alle_uebernehmen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'für alle übernehmen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'apply for all', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'fuer_x_uebernehmen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Auswahl für {count} weitere(n) Wiederholungsanträge übernehmen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Adopt selection for {count} further repeat applications', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'title_grund', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Grund für Ablehnung von Antrag #{id}', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Reason for rejection of Application #{id}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_lvs', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Lehrveranstaltungen zugewiesen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No courses assigned', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_x', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Status: {status}', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Status: {status}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_saving', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Daten werden gespeichert...', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Saving...', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_error', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Fehler', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Error', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_open', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Offen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Open', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_created', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Erstellt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Created', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_cancelling', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zurückziehen...', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Cancelling...', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'status_cancelled', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Zurückgezogen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Cancelled', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_stg_blacklist', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Für diesen Studiengang sind keine Anträge möglich', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No applications are accepted for this course', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_antrag_exists', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Es gibt bereits einen bestehenden Antrag', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'There is already an existing application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_antrag_pending', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Es gibt bereits einen bestehenden Antrag vom Typ {typ}' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'There is already an existing application of type {typ}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_antrag_found', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Kein Antrag mit AntragsId {id} gefunden' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No application found with ApplicationId {id}', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_antrag_locked', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Dieser Antrag ist gesperrt' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'This request is locked', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_lv', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Lehrveranstaltung ausgewählt' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No course selected', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_lv_in_application', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Lehrveranstaltung im Antrag gefunden' , + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No course found in application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_right', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Berechtigung, den Antrag zu bearbeiten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No authorization to edit the application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_no_objection', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Keine Berechtigung, den Antrag zu beeinspruchen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'No authorization to object the application', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_not_objected', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Antrag ist nicht beeinsprucht', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Application is not objected', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + ); diff --git a/system/vorlage_zip/AntragAbmeldung.odt b/system/vorlage_zip/AntragAbmeldung.odt new file mode 100644 index 0000000000000000000000000000000000000000..2e11ca60ae49eb67a843672bf6e2c87e5d31517c GIT binary patch literal 37277 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 literal 0 HcmV?d00001 diff --git a/system/vorlage_zip/AntragUnterbrechung.odt b/system/vorlage_zip/AntragUnterbrechung.odt new file mode 100644 index 0000000000000000000000000000000000000000..aeaa82105e7a130979d9a86f82ee5d622b610b7c GIT binary patch literal 34155 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

VY%NO_G+4oZkl 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Studiengang: + + + + + + Organisationsform: + + + + + + + + Abmeldung vom Studium durch Studierende + + + + + + + Name der*des Studierenden + + + + + + + + + + + Personenkennzeichen + + + + + + + + + + Studienjahr + + + + + + + + + + Semester + + + + + + + + + + Grund der Abmeldung: + + + + + + + + + + + + + + + Wir weisen Sie darauf hin, dass Ihr FHTW Account noch 21 Tage aktiv ist. Wir bitten Sie, alle benötigte Dateien (Zeugnisse, Studienerfolgsbestätigungen, Studienbestätigungen, etc.) innerhalb dieses Zeitraums herunterzuladen. Für die Ausstellung von Duplikaten fallen nach Inaktivsetzung des CIS-Accounts Kosten an. + + + Sie sind gem. Ausbildungsvertrag verpflichtet, unverzüglich alle zur Verfügung gestellten Gerätschaften, Bücher, Schlüssel und sonstige Materialien zurückzugeben. + + Bei Abmeldung vor dem 01.09. bzw. 15.02. und bereits eingezahltem Studienbeitrag für das kommende Semester: Wir informieren Sie darüber, dass der Studienbeitrag für das kommende Semester von Ihnen zurückgefordert werden kann. Bitte geben Sie uns dafür innerhalb von 14 Tagen Ihre Bankdaten an folgende E-Mail-Adresse bekannt: billing@technikum-wien.at. + + + + + + + + \ No newline at end of file diff --git a/system/xsl/AntragUnterbrechung.xsl b/system/xsl/AntragUnterbrechung.xsl new file mode 100644 index 000000000..f1ab10d91 --- /dev/null +++ b/system/xsl/AntragUnterbrechung.xsl @@ -0,0 +1,459 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Studiengang: + + + + + + + + Organisationsform: + + + + + + + + + Antrag auf Unterbrechung des Studiums + + + + + + + + Name der*des Studierenden + + + + + + + + + + + + + + Personenkennzeichen + + + + + + + + + + + + + + Studienjahr + + + + + + + + + + + + + + Aktuelles Semester + + + + + + + + + + + + Grund der Unterbrechung: + + + + + + + + + + + + + Wiedereinstieg am + + + + + + + + + + + + + + + + + + + + Datum: + + + + + + + + + + + + + + + + Infolge der Weiterentwicklung der Qualität des Studienganges kann es zu Änderungen der Studienbedingungen beim Wiedereinstieg kommen (z. B. Studienplan, Prüfungsordnung etc.) + + + Falls Sie das Studium im Wintersemester vor dem 15.10. bzw. im Sommersemester vor dem 15.3. beenden, wird Ihnen der Studienbeitrag für das aktuelle Semester rückerstattet. Bitte geben Sie uns innerhalb von 14 Tagen Ihre Bankdaten an folgende E-Mail-Adresse bekannt: + + + billing@technikum-wien.at + + + . + + + + + + \ No newline at end of file From 16356d8a5c4c60e5ced65ab159383023cab2fcf9 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 10:42:06 +0200 Subject: [PATCH 222/439] reverse order setColumns & setData --- public/js/components/filter/Filter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/js/components/filter/Filter.js b/public/js/components/filter/Filter.js index 776405614..453face96 100644 --- a/public/js/components/filter/Filter.js +++ b/public/js/components/filter/Filter.js @@ -226,9 +226,9 @@ export const CoreFilterCmpt = { } }, _updateTabulator() { - this.tabulator.setData(this.filteredData); this.tabulatorHasSelector = this.filteredColumns.filter(el => el.formatter == 'rowSelection').length; this.tabulator.setColumns(this.filteredColumns); + this.tabulator.setData(this.filteredData); }, /** * From b39fa7667e4f36d4db15a95007631bc0bc9c46c5 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 11:09:55 +0200 Subject: [PATCH 223/439] Remove TODO --- application/controllers/components/Antrag/Wiederholung.php | 1 - 1 file changed, 1 deletion(-) diff --git a/application/controllers/components/Antrag/Wiederholung.php b/application/controllers/components/Antrag/Wiederholung.php index 7b5d8f887..941d6e51a 100644 --- a/application/controllers/components/Antrag/Wiederholung.php +++ b/application/controllers/components/Antrag/Wiederholung.php @@ -66,7 +66,6 @@ class Wiederholung extends FHC_Controller } $result = $result->retval; if (!$result) { - // TODO(chris): ERROR Message $this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN); return $this->outputJsonError($this->p->t('studierendenantrag','error_no_student_no_failed_exam')); } From ff93cb26fe07985fcc0b29263c419c7b75b5d759 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 11:10:26 +0200 Subject: [PATCH 224/439] Bug: status --- .../Studierendenantrag/Form/Wiederholung.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/public/js/components/Studierendenantrag/Form/Wiederholung.js b/public/js/components/Studierendenantrag/Form/Wiederholung.js index 4cbc32d88..ff37540bb 100644 --- a/public/js/components/Studierendenantrag/Form/Wiederholung.js +++ b/public/js/components/Studierendenantrag/Form/Wiederholung.js @@ -65,13 +65,15 @@ export default { ).then( result => { this.data = result.data.retval; - if (!this.data.status || this.data.status == 'ErsteAufforderungVersandt' || this.data.status == 'ZweiteAufforderungVersandt') + if (!this.data.status || this.data.status == 'ErsteAufforderungVersandt' || this.data.status == 'ZweiteAufforderungVersandt') { this.data.status = 'Offen'; + this.data.statustyp = this.p.t('studierendenantrag', 'status_open'); + } this.$emit('update:status', this.data.status); this.$emit("setStatus", { - msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), - severity: this.statusSeverity - }); + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.data.statustyp}), + severity: this.statusSeverity + }); return result; } ); @@ -87,7 +89,7 @@ export default { let nextState = repeat ? 'Erstellt' : 'Verzichtet'; this.$emit('setStatus', { - msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t_ref('studierendenantrag', 'status_saving')}), + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_saving')}), severity: 'warning' }); this.saving = true; @@ -114,7 +116,7 @@ export default { this.errors.default.push(result.data.retval[k]); } this.$emit('setStatus', { - msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t_ref('studierendenantrag', 'status_error')}), + msg: this.p.t_ref('studierendenantrag', 'status_x', {status: this.p.t('studierendenantrag', 'status_error')}), severity: 'danger' }); } From 7eed07a68295d8b83db19e915983140282123ddb Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 13:37:54 +0200 Subject: [PATCH 225/439] LV zuweisung & anzeige: handle semester above max_semester & anmerkung bug --- application/libraries/AntragLib.php | 30 ++++++--- .../Studierendenantrag/Leitung/LvPopup.js | 63 ++++++++++--------- .../Studierendenantrag/Lvzuweisung.js | 15 ++++- system/phrasesupdate.php | 20 ++++++ 4 files changed, 87 insertions(+), 41 deletions(-) diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index 38504772c..f1a757bc2 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -765,14 +765,16 @@ class AntragLib ); if (isError($result)) return $result; - $lvsA = getData($result) ?: []; - foreach($lvsA as $lv) - { - if (isset($lvszugewiesen[$lv->lehrveranstaltung_id]) && - ($lvszugewiesen[$lv->lehrveranstaltung_id]->note == $this->_ci->config->item('wiederholung_note_nicht_zugelassen'))) + $lvsA = $result->retval; // NOTE(chris): don't use getData() because we want to differenciate [] and null + if ($lvsA) { + foreach($lvsA as $lv) { - $lv->antrag_zugelassen = true; - $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; + if (isset($lvszugewiesen[$lv->lehrveranstaltung_id]) && + ($lvszugewiesen[$lv->lehrveranstaltung_id]->note == $this->_ci->config->item('wiederholung_note_nicht_zugelassen'))) + { + $lv->antrag_zugelassen = true; + $lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung; + } } } @@ -798,7 +800,7 @@ class AntragLib } return success([ - '1' . $semA => $lvsA ?: [], + '1' . $semA => $lvsA, '2' . $semB => $lvsB ?: [] ]); } @@ -822,13 +824,23 @@ class AntragLib if (isError($result)) return $result; $result = getData($result); - if (!$result) + if (!$result) { + $result = $this->_ci->StudiengangModel->load($studiengang_kz); + if (isError($result)) + return $result; + if (!hasData($result)) + return error('No Studiengang found with studiengang_kz: ' . $studiengang_kz); + $stg = current(getData($result)); + + if ($ausbildungssemester > $stg->max_semester) + return success(); return error('No studienplan found for stg: ' . $studiengang_kz . ', studiensemester: ' . $studiensemester_kurzbz . ', ausbildungssemester: ' . ($ausbildungssemester)); + } if (count($result) > 1) return error('Multiple studienplaene found for stg: ' . $studiengang_kz . diff --git a/public/js/components/Studierendenantrag/Leitung/LvPopup.js b/public/js/components/Studierendenantrag/Leitung/LvPopup.js index 045e98729..c3f2aa118 100644 --- a/public/js/components/Studierendenantrag/Leitung/LvPopup.js +++ b/public/js/components/Studierendenantrag/Leitung/LvPopup.js @@ -25,12 +25,12 @@ export default { lvzugelassen() { let zwischen = {}; for (let k in this.lvs){ - zwischen[k] = this.lvs[k].filter(lv=>lv.antrag_zugelassen); + zwischen[k] = this.lvs[k] ? this.lvs[k].filter(lv=>lv.antrag_zugelassen) : null; } return zwischen; }, lvzugelassenLength() { - return Object.values(this.lvzugelassen).reduce((result, current) => result + current.length, 0); + return Object.values(this.lvzugelassen).reduce((result, current) => result + (current ? current.length : 0), 0); } }, methods: { @@ -86,7 +86,7 @@ export default { {{sem.substr(1)}} - + {{p.t('ui','bezeichnung')}} {{p.t('lehre','lehrform')}} @@ -98,33 +98,38 @@ export default { - - - - - -

- {{lv.lehrform_kurzbz}} -
- - -
- {{lv.ects}} -
- - -
- {{lv.note || '---'}} -
- - -
- {{lv.antrag_anmerkung}} -
- + + {{p.t('studierendenantrag/error_stg_last_semester')}} + diff --git a/public/js/components/Studierendenantrag/Lvzuweisung.js b/public/js/components/Studierendenantrag/Lvzuweisung.js index cbc97b79e..d987f55be 100644 --- a/public/js/components/Studierendenantrag/Lvzuweisung.js +++ b/public/js/components/Studierendenantrag/Lvzuweisung.js @@ -108,6 +108,14 @@ export default { { let res = {}; for (var k in result.data.retval) { + if (result.data.retval[k] === null) { + const alert = document.createElement('div'); + alert.innerHTML = this.p.t('studierendenantrag', 'error_stg_last_semester'); + alert.className = 'alert alert-warning'; + alert.role = 'alert'; + this.$refs["lvtable" + k.substr(0,1)].append(alert); + continue; + } let lvs = result.data.retval[k].reduce((obj,lv) => { obj[lv.studienplan_lehrveranstaltung_id] = lv; return obj; @@ -129,8 +137,9 @@ export default { var table = new Tabulator(this.$refs["lvtable" + k.substr(0,1)], { data: current, dataTree: true, - dataTreeStartExpanded:true, //start with an expanded tree - dataTreeChildIndent:15, + dataTreeStartExpanded: true, //start with an expanded tree + dataTreeChildIndent: 15, + layout: "fitDataStretch", columns: [ {title: this.p.t('ui','bezeichnung'), field: "bezeichnung"}, {title: this.p.t('lehre','lehrform'), field: "lehrform_kurzbz"}, @@ -197,7 +206,7 @@ export default { input.type = "text"; input.value = cell.getValue() || ""; input.addEventListener('input', () => { - lvs[data.studienplan_lehrveranstaltung_id].antrag_zugelassen = input.value; + lvs[data.studienplan_lehrveranstaltung_id].antrag_anmerkung = input.value; }); return input; } diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index f6df3afad..562e4e5c2 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -19906,6 +19906,26 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_stg_last_semester', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Der Studiengang hat nicht genügend Semester', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'The course does not have enough semesters', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), ); From 3798720ee0ed5fe1a42e0240ac7fd7ffbfa6ecc9 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 14:38:20 +0200 Subject: [PATCH 226/439] +emit: click:new --- public/js/components/filter/Filter.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/js/components/filter/Filter.js b/public/js/components/filter/Filter.js index 453face96..2b6a4fe6d 100644 --- a/public/js/components/filter/Filter.js +++ b/public/js/components/filter/Filter.js @@ -39,7 +39,8 @@ export const CoreFilterCmpt = { TableDownload }, emits: [ - 'nwNewEntry' + 'nwNewEntry', + 'click:new' ], props: { onNwNewEntry: Function, // NOTE(chris): Hack to get the nwNewEntry listener into $props From 3ca80904eafa3080bb9615426514db987dd1ced4 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Tue, 4 Jul 2023 15:59:43 +0200 Subject: [PATCH 227/439] =?UTF-8?q?Verbesserungen=20Unterbrecher=20best?= =?UTF-8?q?=C3=A4tigen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/libraries/AntragLib.php | 6 ++++++ application/libraries/PrestudentLib.php | 19 +++++++++++++++++-- .../27351_digitalisierung_formulare.php | 4 ++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index f1a757bc2..e3119d65b 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -288,6 +288,7 @@ class AntragLib } else { + $studierendenantrag_status_id = getData($result); $resultAntrag = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); if (isError($resultAntrag)) return $resultAntrag; @@ -299,6 +300,11 @@ class AntragLib // Prestudentstatus und Unterbrechungsfolgeaktionen setzen $result = $this->_ci->prestudentlib->setUnterbrecher($resultAntrag->prestudent_id, $resultAntrag->studiensemester_kurzbz, $studierendenantrag_id); + if (isError($result)) { + $this->_ci->StudierendenantragstatusModel->delete($studierendenantrag_status_id); + return $result; + } + //Mail $subject = 'Unterbrechung freigegeben'; $mail = []; diff --git a/application/libraries/PrestudentLib.php b/application/libraries/PrestudentLib.php index 6dff4e812..2597b40d0 100644 --- a/application/libraries/PrestudentLib.php +++ b/application/libraries/PrestudentLib.php @@ -203,8 +203,23 @@ class PrestudentLib if (isError($result)) return $result; $result = getData($result); - if (!$result) - return error('Kein Prestudent in diesem Studiensemester gefunden'); + if (!$result) { + /** TODO(chris): Zukünftige Unterbrecher so nicht möglich + * - Verband und Gruppe dürfen noch nicht gesetzt werden + * - Keine Garantie das Ausbildungssemester gleich bleibt (weiter Unterbrechungen oder eine Wiederholung in der Zwischenzeit) + * - LVs eventuell nicht zugewießen + * Mögliche Lösung: JOB! + + $result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id); + if (isError($result)) + return $result; + $result = getData($result); + if (!$result) { + return error('Kein Prestudent status gefunden'); + } + $result->studiensemester_kurzbz*/ + return error('Kein Prestudent status gefunden'); + } $prestudent_status = current($result); diff --git a/system/dbupdate_3.4/27351_digitalisierung_formulare.php b/system/dbupdate_3.4/27351_digitalisierung_formulare.php index a40b457e2..e94bd2b61 100644 --- a/system/dbupdate_3.4/27351_digitalisierung_formulare.php +++ b/system/dbupdate_3.4/27351_digitalisierung_formulare.php @@ -100,8 +100,8 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_status CACHE 1; ALTER TABLE campus.tbl_studierendenantrag_status ALTER COLUMN studierendenantrag_status_id SET DEFAULT nextval('campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq'); - GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_status TO vilesci; - GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_status TO web; + GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_status TO vilesci; + GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_status TO web; GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq TO vilesci; GRANT SELECT, UPDATE ON campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq TO web;"; From 61856473eaf40242128fd170c23d156bc0b3c0ba Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Wed, 5 Jul 2023 08:30:33 +0200 Subject: [PATCH 228/439] Leitungsansicht Autocomplete 1st draft --- .../components/Antrag/Abmeldung.php | 7 +- application/libraries/AntragLib.php | 10 ++- .../models/organisation/Studiengang_model.php | 17 +++- application/views/templates/FHC-Footer.php | 1 + public/js/apps/lehre/Antrag/Leitung.js | 2 +- .../Studierendenantrag/Leitung/Actions/New.js | 84 ++++++++++++------- 6 files changed, 86 insertions(+), 35 deletions(-) diff --git a/application/controllers/components/Antrag/Abmeldung.php b/application/controllers/components/Antrag/Abmeldung.php index 9130c1d7d..44d1b5c4a 100644 --- a/application/controllers/components/Antrag/Abmeldung.php +++ b/application/controllers/components/Antrag/Abmeldung.php @@ -167,9 +167,12 @@ class Abmeldung extends FHC_Controller { $this->load->library('PermissionLib'); + $_POST = json_decode($this->input->raw_input_stream, true); + $query = $this->input->post('query'); + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); - $result = $this->antraglib->getAbmeldeBerechtigtForStg($studiengaenge); + $result = $this->antraglib->getAktivePrestudentenInStgs($studiengaenge, $query); if (isError($result)) { return $this->outputJsonError(getError($result)); } @@ -178,6 +181,8 @@ class Abmeldung extends FHC_Controller return $this->outputJsonSuccess([]); } + return $this->outputJsonSuccess($result); + $sortedStudents = []; foreach ($result as $item) { if (!isset($sortedStudents[$item->studiengang_kz])) diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index e3119d65b..e06c57544 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -1188,13 +1188,15 @@ class AntragLib return $stsems; } - public function getAbmeldeBerechtigtForStg($studiengaenge) + public function getAktivePrestudentenInStgs($studiengaenge, $query) { $blacklist = $this->_ci->config->item('stgkz_blacklist_abmeldung'); $studiengaenge = array_diff($studiengaenge, $blacklist); - return $this->_ci->StudiengangModel->getAktivePrestudenten($studiengaenge, [ - Studierendenantrag_model::TYP_ABMELDUNG - ]); + return $this->_ci->StudiengangModel->getAktivePrestudenten( + $studiengaenge, + [ Studierendenantrag_model::TYP_ABMELDUNG ], + $query + ); } public function getFailedExamForPrestudent($prestudent_id) diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index ea9e5857e..1e5c16cc5 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -532,7 +532,7 @@ class Studiengang_model extends DB_Model * * @return stdClass */ - public function getAktivePrestudenten($studiengang_kzs, $not_antrag_typ = null) + public function getAktivePrestudenten($studiengang_kzs, $not_antrag_typ = null, $query = null) { $this->load->config('studierendenantrag'); @@ -571,6 +571,21 @@ class Studiengang_model extends DB_Model $this->db->group_end(); } + if ($query) { + $query = explode(' ', $query); + $this->db->group_start(); + foreach ($query as $q) { + $this->db->group_start(); + $this->db->where('pers.vorname ILIKE', "%" . $q . "%"); + $this->db->or_where('pers.nachname ILIKE', "%" . $q . "%"); + $this->db->or_where($this->dbTable . '.bezeichnung ILIKE', "%" . $q . "%"); + if (is_numeric($q)) + $this->db->or_where('p.prestudent_id', $q); + $this->db->group_end(); + } + $this->db->group_end(); + } + return $this->load(); } } diff --git a/application/views/templates/FHC-Footer.php b/application/views/templates/FHC-Footer.php index c461dd8b0..f4d66a9b9 100644 --- a/application/views/templates/FHC-Footer.php +++ b/application/views/templates/FHC-Footer.php @@ -122,6 +122,7 @@ generateJSsInclude('vendor/npm-asset/primevue/column/column.min.js'); generateJSsInclude('vendor/npm-asset/primevue/calendar/calendar.min.js'); generateJSsInclude('vendor/npm-asset/primevue/skeleton/skeleton.min.js'); + generateJSsInclude('vendor/npm-asset/primevue/autocomplete/autocomplete.min.js'); } // -------------------------------------------------------------------------------------------------------- diff --git a/public/js/apps/lehre/Antrag/Leitung.js b/public/js/apps/lehre/Antrag/Leitung.js index 0e68cccba..e243aad93 100644 --- a/public/js/apps/lehre/Antrag/Leitung.js +++ b/public/js/apps/lehre/Antrag/Leitung.js @@ -5,4 +5,4 @@ const app = Vue.createApp({ StudierendenantragLeitung } }); -app.mount('#wrapper'); +app.use(primevue.config.default).mount('#wrapper'); diff --git a/public/js/components/Studierendenantrag/Leitung/Actions/New.js b/public/js/components/Studierendenantrag/Leitung/Actions/New.js index 8a98a6aa5..b9c21b05f 100644 --- a/public/js/components/Studierendenantrag/Leitung/Actions/New.js +++ b/public/js/components/Studierendenantrag/Leitung/Actions/New.js @@ -4,7 +4,8 @@ import Phrasen from '../../../../mixins/Phrasen.js'; export default { components: { - BsModal + BsModal, + AutoComplete: primevue.autocomplete }, mixins: [ Phrasen @@ -15,8 +16,7 @@ export default { data() { return { data: [], - student: '', - stg: '' + student: '' } }, computed: { @@ -24,13 +24,13 @@ export default { return FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + '/lehre/Studierendenantrag/abmeldung/' + this.student; }, students() { - if (!this.stg) - return []; - if (!this.data[this.stg]) - return []; - return this.data[this.stg].studenten.sort( + return this.data.sort( (a, b) => a.nachname == b.nachname ? - a.vorname > b.vorname : + ( + a.vorname == b.vorname ? + a.bezeichnung > b.bezeichnung : + a.vorname > b.vorname + ) : a.nachname > b.nachname ); }, @@ -47,15 +47,17 @@ export default { }), { dialogClass: 'modal-fullscreen' }, this.p.t('studierendenantrag', 'antrag_header')).then(() => { + this.data = []; this.loadSelects(); this.$emit('reload'); }); }, - loadSelects() { - return axios.get( + loadData(evt) { + axios.post( FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + - '/components/Antrag/Abmeldung/getStudiengaengeAssistenz/' + '/components/Antrag/Abmeldung/getStudiengaengeAssistenz/', + evt ).then( result => { if (result.data.error) { @@ -66,14 +68,30 @@ export default { return result; } ); + }, + loadSelects() { + if (this.hasNoData) { + return axios.post( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Abmeldung/getStudiengaengeAssistenz/', + {query: 'felix'} + ).then( + result => { + if (result.data.error) { + BsAlert.popup(result.data.retval, {dialogClass: 'alert alert-danger'}); + } else { + this.data = result.data.retval; + } + return result; + } + ); + } } }, - created() { - return this.loadSelects(); - }, template: `
- @@ -85,22 +103,32 @@ export default {
From d4450e1ae16da849079fbcc2b946c8aaecb1ed14 Mon Sep 17 00:00:00 2001 From: Paolo Date: Wed, 5 Jul 2023 15:07:05 +0200 Subject: [PATCH 230/439] Removed check of the tbl_benutzer.aktiv field in the AuthLib --- application/libraries/AuthLib.php | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/application/libraries/AuthLib.php b/application/libraries/AuthLib.php index ae30d41fa..de9c15350 100644 --- a/application/libraries/AuthLib.php +++ b/application/libraries/AuthLib.php @@ -551,10 +551,7 @@ class AuthLib // Needed information $this->_ci->PersonModel->addSelect('person_id, vorname, nachname, uid'); // Retrieves the uid if it is possible for active users - $this->_ci->PersonModel->addJoin( - '(SELECT uid, person_id FROM public.tbl_benutzer WHERE aktiv = TRUE) tb', 'person_id', - 'LEFT' - ); + $this->_ci->PersonModel->addJoin('public.tbl_benutzer', 'person_id', 'LEFT'); // Execute query with where clause $personResult = $this->_ci->PersonModel->loadWhere($queryParamsArray); From cb4ce6dab6616712e425b8ecf00de896d426bea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Thu, 6 Jul 2023 13:30:43 +0200 Subject: [PATCH 231/439] Anzeige Lehre Saldo in der Zeitaufzeichnung deaktiviert --- cis/private/tools/zeitaufzeichnung.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cis/private/tools/zeitaufzeichnung.php b/cis/private/tools/zeitaufzeichnung.php index 773582177..0eb86bdb1 100644 --- a/cis/private/tools/zeitaufzeichnung.php +++ b/cis/private/tools/zeitaufzeichnung.php @@ -1433,7 +1433,8 @@ if ($projekt->getProjekteMitarbeiter($user, true)) $sem_akt = $stsem->getakt(); $lehre = new zeitaufzeichnung(); $l_arr = $lehre->getLehreForUser($user, $sem_akt); - if ($l_arr["LehreAuftraege"]>0 || $l_arr["Lehre"] > 0 || $l_arr["LehreExtern"] > 0) + $displayLehresaldo = false; + if ($displayLehresaldo && ($l_arr["LehreAuftraege"]>0 || $l_arr["Lehre"] > 0 || $l_arr["LehreExtern"] > 0)) { if ($lehre_inkludiert == -1) { From af9418d456495d2a985f19bd1fa6f88ce00d6fae Mon Sep 17 00:00:00 2001 From: Manfred Date: Thu, 6 Jul 2023 18:05:24 +0200 Subject: [PATCH 232/439] Anmerkung und Insertdaten bei Rolleberechtigung MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit + Vergleichsskript für Rechte in einzelnen Rollen --- include/berechtigung.class.php | 23 +- system/dbupdate_3.4.php | 3 +- ...537_anmerkung_in_tbl_rolleberechtigung.php | 15 + vilesci/stammdaten/berechtigungrolle.php | 587 +++++++++--------- 4 files changed, 343 insertions(+), 285 deletions(-) create mode 100644 system/dbupdate_3.4/30537_anmerkung_in_tbl_rolleberechtigung.php diff --git a/include/berechtigung.class.php b/include/berechtigung.class.php index e7be01283..9d9a8e79b 100644 --- a/include/berechtigung.class.php +++ b/include/berechtigung.class.php @@ -29,6 +29,10 @@ class berechtigung extends basis_db public $rolle_kurzbz; public $beschreibung; public $berechtigung_kurzbz; + public $art; + public $anmerkung; + public $insertamum; + public $insertvon; /** * Konstruktor @@ -78,8 +82,7 @@ class berechtigung extends basis_db public function save($new=null) { if(is_null($new)) - $new = $this->new; - + if($new) { $qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES(". @@ -176,6 +179,9 @@ class berechtigung extends basis_db $obj->rolle_kurzbz = $row->rolle_kurzbz; $obj->art = $row->art; $obj->beschreibung = $row->beschreibung; + $obj->anmerkung = $row->anmerkung; + $obj->insertamum = $row->insertamum; + $obj->insertvon = $row->insertvon; $this->result[] = $obj; } @@ -276,15 +282,22 @@ class berechtigung extends basis_db if($this->db_num_rows()>0) { //Update - $qry = "UPDATE system.tbl_rolleberechtigung SET art=".$this->db_add_param($this->art)." WHERE rolle_kurzbz=".$this->db_add_param($this->rolle_kurzbz)." AND berechtigung_kurzbz=".$this->db_add_param($this->berechtigung_kurzbz).";"; + $qry = "UPDATE system.tbl_rolleberechtigung SET art=".$this->db_add_param($this->art).", + anmerkung=".$this->db_add_param($this->anmerkung).", + insertamum=".$this->db_add_param($this->insertamum).", + insertvon=".$this->db_add_param($this->insertvon)." + WHERE rolle_kurzbz=".$this->db_add_param($this->rolle_kurzbz)." AND berechtigung_kurzbz=".$this->db_add_param($this->berechtigung_kurzbz).";"; } else { //Insert - $qry = "INSERT INTO system.tbl_rolleberechtigung (rolle_kurzbz, berechtigung_kurzbz, art) VALUES(". + $qry = "INSERT INTO system.tbl_rolleberechtigung (rolle_kurzbz, berechtigung_kurzbz, art, anmerkung, insertamum, insertvon) VALUES(". $this->db_add_param($this->rolle_kurzbz).",". $this->db_add_param($this->berechtigung_kurzbz).",". - $this->db_add_param($this->art).");"; + $this->db_add_param($this->art).",". + $this->db_add_param($this->anmerkung).",". + $this->db_add_param($this->insertamum).",". + $this->db_add_param($this->insertvon).");"; } if($this->db_query($qry)) diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index 9fda09bba..ed60aeddf 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -39,6 +39,7 @@ require_once('dbupdate_3.4/27107_vilesci_erfassung_abwesenheiten_reinigung.php') require_once('dbupdate_3.4/24913_tabelle_raumtyp_neues_attribut_aktiv.php'); require_once('dbupdate_3.4/28089_plausichecks_in_extension_hinzufuegen.php'); require_once('dbupdate_3.4/29133_einzelne_studiengaenge_aus_issuechecks_ausnehmen.php'); +require_once('dbupdate_3.4/30537_anmerkung_in_tbl_rolleberechtigung.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; @@ -326,7 +327,7 @@ $tabellen=array( "system.tbl_phrase" => array("phrase_id","app","phrase","insertamum","insertvon","category"), "system.tbl_phrasentext" => array("phrasentext_id","phrase_id","sprache","orgeinheit_kurzbz","orgform_kurzbz","text","description","insertamum","insertvon"), "system.tbl_rolle" => array("rolle_kurzbz","beschreibung"), - "system.tbl_rolleberechtigung" => array("berechtigung_kurzbz","rolle_kurzbz","art"), + "system.tbl_rolleberechtigung" => array("berechtigung_kurzbz","rolle_kurzbz","art","anmerkung","insertamum","insertvon"), "system.tbl_verarbeitungstaetigkeit" => array("taetigkeit_kurzbz", "bezeichnung", "bezeichnung_mehrsprachig","aktiv"), "system.tbl_webservicelog" => array("webservicelog_id","webservicetyp_kurzbz","request_id","beschreibung","request_data","execute_time","execute_user"), "system.tbl_webservicerecht" => array("webservicerecht_id","berechtigung_kurzbz","methode","attribut","insertamum","insertvon","updateamum","updatevon","klasse"), diff --git a/system/dbupdate_3.4/30537_anmerkung_in_tbl_rolleberechtigung.php b/system/dbupdate_3.4/30537_anmerkung_in_tbl_rolleberechtigung.php new file mode 100644 index 000000000..0d7b43b8f --- /dev/null +++ b/system/dbupdate_3.4/30537_anmerkung_in_tbl_rolleberechtigung.php @@ -0,0 +1,15 @@ +db_query("SELECT anmerkung FROM system.tbl_rolleberechtigung LIMIT 1")) +{ + $qry = "ALTER TABLE system.tbl_rolleberechtigung ADD COLUMN anmerkung varchar(256); + ALTER TABLE system.tbl_rolleberechtigung ADD COLUMN insertamum timestamp DEFAULT now(); + ALTER TABLE system.tbl_rolleberechtigung ADD COLUMN insertvon varchar(32);"; + + if(!$db->db_query($qry)) + echo 'system.tbl_rolleberechtigung '.$db->db_last_error().'
'; + else + echo '
Spalten anmerkung, insertamum, insertvon in system.tbl_rolleberechtigung hinzugefügt'; +} diff --git a/vilesci/stammdaten/berechtigungrolle.php b/vilesci/stammdaten/berechtigungrolle.php index 82430d64e..7e87a4901 100644 --- a/vilesci/stammdaten/berechtigungrolle.php +++ b/vilesci/stammdaten/berechtigungrolle.php @@ -1,239 +1,3 @@ - - * Andreas Oesterreicher < andreas.oesterreicher@technikum-wien.at > - * Rudolf Hangl < rudolf.hangl@technikum-wien.at > - * Gerald Simane-Sequens < gerald.simane-sequens@technikum-wien.at > - */ -require_once('../../config/vilesci.config.inc.php'); -require_once('../../include/functions.inc.php'); -require_once('../../include/berechtigung.class.php'); -require_once('../../include/benutzerberechtigung.class.php'); - -$user = get_uid(); - -$rechte = new benutzerberechtigung(); -$rechte->getBerechtigungen($user); - -if(!$rechte->isBerechtigt('basis/berechtigung')) - die($rechte->errormsg); - -$berechtigung_kurzbz = filter_input(INPUT_POST, 'berechtigung_kurzbz'); -$beschreibung = filter_input(INPUT_POST, 'beschreibung'); -$kurzbz = filter_input(INPUT_GET, 'kurzbz'); -$kurzbzPost = filter_input(INPUT_POST, 'kurzbz_post'); -$edit = filter_input(INPUT_GET, 'edit'); -$save = filter_input(INPUT_POST, 'save'); -$delete = filter_input(INPUT_GET, 'delete'); -$saveNew = filter_input(INPUT_POST, 'saveNew'); - -//$delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); -?> - - - Rechte - - - - - - - - - - -

Rollenübersicht

- - berechtigung_kurzbz = $kurzbzPost; - $berechtigung->beschreibung = $beschreibung; - $berechtigung->new = true; - - if($berechtigung->save()) - { - echo 'Recht '.$kurzbzPost.' wurde angelegt

'; - } - else - { - echo 'Fehler beim Speichern:'.$berechtigung->errormsg.'

'; - } - } - else - { - echo 'Zum Speichern der Daten muss die Kurzbz und die Beschreibung angegeben werden

'; - } - } - - if(isset($delete) && isset($kurzbz)) - { - $berechtigung = new berechtigung(); - if($berechtigung->delete($kurzbz)) - echo 'Das Recht "'.$kurzbz.'" wurde erfolgreich gelöscht

'; - else - echo 'Fehler beim Löschen des Rechts:'.$berechtigung->errormsg.'

'; - } - - if(isset($save)) - { - $berechtigung = new berechtigung(); - $berechtigung->load($berechtigung_kurzbz); - $berechtigung->beschreibung = $beschreibung; - if (!$berechtigung->save(false)) - echo 'Fehler beim Speichern:'.$berechtigung->errormsg.'

'; - } - - //Tabelle mit Rollen anzeigen - $berechtigung = new berechtigung(); - $berechtigung->getBerechtigungen(); - - echo ''; - echo ' - - - - - - - - - '; - - foreach($berechtigung->result as $recht) - { - if($edit && $recht->berechtigung_kurzbz == $kurzbz) - { - echo ' - - - - '; - } - else - { - echo ' - - - - - - '; - } - } - echo ' - -
KurzbzBeschreibungAktion
- '.$recht->berechtigung_kurzbz.' -
- - '.(256 - strlen($recht->beschreibung)).' - - -
-
'.$recht->berechtigung_kurzbz.''.$recht->beschreibung.' - - Bearbeiten - - - - Recht löschen - -
- -
'; - - echo '
-

Neues Recht einfügen

- Kurzbz: - Beschreibung: - 256 -   -
-
- -'; - ?> - - - - - - - - - - - - - - - - - - isBerechtigt('basis/berechtigung')) $rolle_kurzbz = filter_input(INPUT_GET, 'rolle_kurzbz'); $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); +$copy = filter_input(INPUT_POST, 'copy'); +$vergleich = filter_input(INPUT_GET, 'vergleich'); ?> - Berechtigungen Uebersicht + Rollen Uebersicht @@ -290,15 +56,37 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); $("#t1").tablesorter( { sortList: [[0,0]], - widgets: ["zebra"], - headers: {3:{sorter:false}} + widgets: ["zebra", "filter", "stickyHeaders"], + headers: {3:{filter:false, sorter:false}}, + widgetOptions : {filter_saveFilters : true} }); $("#t2").tablesorter( { sortList: [[0,0]], - widgets: ["zebra"], - headers: {2:{sorter:false}} + widgets: ["zebra", "filter", "stickyHeaders"], + headers: {2:{filter:false, sorter:false}}, + widgetOptions : {filter_saveFilters : true} + }); + $("#t3").tablesorter( + { + sortList: [], + widgets: ["zebra"] + }); + $("#t4").tablesorter( + { + sortList: [], + widgets: ["zebra"] + }); + $('.resetsaved').click(function() + { + $(".tablesorter").trigger("filterReset"); + window.location(""); + return false; + }); + $("textarea").keyup(function() + { + $(this).siblings("span").text((256 - $(this).val().length)); }); // Breite des Autocompletes korrigieren um das Springen zu verhindern @@ -329,16 +117,15 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); $(this).val(ui.item.berechtigung_kurzbz); } }); - }); - function confdel() - { - var value=prompt('Achtung! Sie sind dabei eine Rolle zu löschen. Die Zuordnungen gehen dadurch verloren! Um diese Rolle wirklich zu Löschen tippen Sie "LÖSCHEN" in das untenstehende Feld.'); - if(value=='LÖSCHEN') - return true; - else - return false; - } + $(".copyButton").click(function(event) + { + event.preventDefault(); + $(this).siblings().show(); + $(this).hide(); + }); + }); + function validateNewData() { if($('#berechtigung_neu_autocomplete').val() == '') @@ -374,14 +161,16 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); -

Berechtigung - Rolle -

+ Berechtigungen der Rolle "'.$rolle_kurzbz.'"'; $berechtigung_kurzbz = filter_input(INPUT_GET, 'berechtigung_kurzbz'); $art = filter_input(INPUT_GET, 'art'); $save = filter_input(INPUT_GET, 'save'); + $anmerkung = filter_input(INPUT_GET, 'anmerkung'); if(isset($save)) { @@ -391,10 +180,17 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); $berechtigung->rolle_kurzbz = $rolle_kurzbz; $berechtigung->berechtigung_kurzbz = $berechtigung_kurzbz; $berechtigung->art = $art; + $berechtigung->anmerkung = $anmerkung; + $berechtigung->insertamum = date('Y-m-d H:i:s'); + $berechtigung->insertvon = $user; if($berechtigung->saveRolleBerechtigung()): ?> Zuteilung gespeichert - + Fehler beim Speichern der Zuteilung: errormsg ?> - Zurück zur Rollenübersicht + Zurück zur Rollen Übersicht

getBerechtigungen(); ?>
- +
+ - - getRolleBerechtigung($rolle_kurzbz); - $berechtigungen_arr = array(); - foreach ($berechtigungen->result as $row) - { - $berechtigungen_arr[] = $row->berechtigung_kurzbz; - } - foreach ($berechtigung->result as $row): ?> - - - - + + +
- + - + + @@ -460,9 +262,15 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); + + @@ -471,8 +279,166 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN);
Kurzbz Art BeschreibungAnmerkung
berechtigung_kurzbz ?> art ?> beschreibung ?>anmerkung ?> - - entfernen + + Bearbeiten + + + + Recht entfernen
Rollen vergleichen'; + $rolle1 = filter_input(INPUT_GET, 'rolle_kurzbz1'); + $rolle2 = filter_input(INPUT_GET, 'rolle_kurzbz2'); + ?> + + + Zurück zur Rollen Übersicht + +

+ + getRolleBerechtigung($rolle1); + foreach ($rollen->result AS $recht) + { + $rollen1Arr[$recht->berechtigung_kurzbz] = $recht->art; + } + $rollen = new berechtigung(); + $rollen->getRolleBerechtigung($rolle2); + foreach ($rollen->result AS $recht) + { + $rollen2Arr[$recht->berechtigung_kurzbz] = $recht->art; + } + $rollenGesamt = array_merge($rollen1Arr,$rollen2Arr); + ksort($rollenGesamt); + + echo '
+
+
+ Rolle 1: + '; + if (isset($rolle1)) + { + echo ' + + + + + + + '; + + foreach ($rollenGesamt AS $recht => $art) + { + if (array_key_exists($recht, $rollen1Arr)) + { + if ($art != $rollen1Arr[$recht]) + { + echo ' + + + '; + } + else + { + echo ' + + + '; + } + + } + else + { + echo ' + + + '; + } + } + echo ' + +
KurzbzArt
'.$recht.''.$rollen1Arr[$recht].'
'.$recht.''.$art.'
  
'; + } + echo ' +
+
+ Rolle 2: + '; + echo ''; + if (isset($rolle2)) + { + echo ' + + + + + + + '; + foreach ($rollenGesamt AS $recht => $art) + { + if (array_key_exists($recht, $rollen2Arr)) + { + if ($art != $rollen2Arr[$recht]) + { + echo ' + + + '; + } + else + { + echo ' + + + '; + } + } + else + { + echo ' + + + '; + } + } + echo ' + +
KurzbzArt
'.$recht.''.$rollen2Arr[$recht].'
'.$recht.''.$art.'
  
'; + } + echo ' +
+
+
'; + } else { + echo '

Rollen Übersicht

'; $save = filter_input(INPUT_POST, 'save'); $edit = filter_input(INPUT_POST, 'edit'); @@ -509,11 +475,56 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); { $berechtigung = new berechtigung(); if($berechtigung->deleteRolle($kurzbz)) - echo 'Rolle wurde entfernt'; + echo 'Die Rolle '.$kurzbz.' wurde erfolgreich gelöscht'; else echo 'Fehler beim Löschen:'.$berechtigung->errormsg; } + if(isset($copy)) + { + $kurzbz = filter_input(INPUT_POST, 'kurzbz'); + $copyName = filter_input(INPUT_POST, 'copy_name'); + $beschreibung = filter_input(INPUT_POST, 'beschreibung'); + + if(isset($kurzbz)) + { + $berechtigung = new berechtigung(); + $berechtigung->rolle_kurzbz = $copyName; + $berechtigung->beschreibung = $beschreibung; + $berechtigung->new = true; + + if($berechtigung->saveRolle()) + { + $rollenrechte = new berechtigung(); + $rollenrechte->getRolleBerechtigung($kurzbz); + foreach($rollenrechte->result as $rollenrecht) + { + $newRolleRecht = new berechtigung(); + $newRolleRecht->rolle_kurzbz = $copyName; + $newRolleRecht->berechtigung_kurzbz = $rollenrecht->berechtigung_kurzbz; + $newRolleRecht->art = $rollenrecht->art; + $newRolleRecht->anmerkung = $rollenrecht->anmerkung; + $newRolleRecht->insertamum = date('Y-m-d H:i:s'); + $newRolleRecht->insertvon = $user; + if(!$newRolleRecht->saveRolleBerechtigung()) + { + echo 'Fehler beim Speichern des Rechts '.$rollenrecht->berechtigung_kurzbz.' zur Rolle '.$rollenrecht->rolle_kurzbz; + break; + } + } + echo 'Rolle erfolgreich kopiert'; + } + else + { + echo 'Fehler beim kopieren der Rolle '.$kurzbz.':'.$berechtigung->errormsg; + } + } + else + { + echo 'Zum Speichern der Daten muss die kurzbz und die Beschreibung angegeben werden'; + } + } + if(isset($edit)) { $beschreibung = filter_input(INPUT_POST, 'beschreibung'); @@ -528,13 +539,18 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); $berechtigung = new berechtigung(); $berechtigung->getRollen(); ?> -

Rollen:

+

+ + Rollen vergleichen + +

+ - + @@ -561,7 +577,18 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); + @@ -577,6 +604,7 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); Kurzbz: Beschreibung: + beschreibung)) ?>  Neue Rolle anlegen @@ -584,6 +612,7 @@ $delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN); Kurzbz: Beschreibung: + 256   From 9651903200ff2556dc55c4f57af0e4a25c0384ca Mon Sep 17 00:00:00 2001 From: Manfred Date: Thu, 6 Jul 2023 18:08:06 +0200 Subject: [PATCH 233/439] Diverse Titel und Textkorrekturen bei Rechte-Skripten --- include/tw/vilesci_menu_main.inc.php | 15 ++++++------- .../benutzerberechtigung_autocomplete.php | 22 ++++++++++++++----- .../benutzerberechtigung_details.php | 2 +- .../benutzerberechtigung_uebersicht.php | 4 ++-- vilesci/stammdaten/berechtigungen.php | 4 ++-- 5 files changed, 29 insertions(+), 18 deletions(-) diff --git a/include/tw/vilesci_menu_main.inc.php b/include/tw/vilesci_menu_main.inc.php index c28319957..7d24f16f3 100644 --- a/include/tw/vilesci_menu_main.inc.php +++ b/include/tw/vilesci_menu_main.inc.php @@ -33,7 +33,7 @@ $menu=array 'Lehrveranstaltung'=>array('name'=>'Lehrveranstaltung', 'link'=>'lehre/lehrveranstaltung_frameset.html', 'target'=>'main'), /* Leerzeile */'emptyrow1'=>array('name'=>'', 'link'=>'#empty', 'target'=>'main'), 'Verplanungsuebersicht'=>array('name'=>'Verplanungsübersicht', 'link'=>'lehre/check/verplanungsuebersicht.php', 'target'=>'main'), - 'Reihungstest'=>array('name'=>'Reihungstest', 'link'=>'stammdaten/reihungstestverwaltung.php', 'target'=>'main','permissions'=>array('reihungstest')), + 'Reihungstest'=>array('name'=>'Reihungstest', 'link'=>'stammdaten/reihungstestverwaltung.php', 'target'=>'main','permissions'=>array('lehre/reihungstest')), 'LV-Planung'=>array ( 'name'=>'LV-Planung', 'permissions'=>array('admin','lv-plan','support'), @@ -109,7 +109,7 @@ $menu=array ), 'Benutzer'=>array ( - 'name'=>'Benutzer','permissions'=>array('admin','lv-plan','support'), + 'name'=>'Benutzer','permissions'=>array('admin','lv-plan','support','mitarbeiter'), 'Funktionen'=>array('name'=>'Funktionen', 'link'=>'personen/funktion.php', 'target'=>'main', 'permissions'=>array('mitarbeiter')), 'Berechtigungen'=>array('name'=>'Berechtigungen', 'link'=>'stammdaten/benutzerberechtigung_frameset.html', 'target'=>'main','permissions'=>array('basis/berechtigung')), 'Rollen'=>array('name'=>'Rollen', 'link'=>'stammdaten/berechtigungrolle.php', 'target'=>'main','permissions'=>array('basis/berechtigung')), @@ -132,16 +132,15 @@ $menu=array 'name'=>'Stammdaten', 'opener'=>'true', 'hide'=>'true', 'permissions'=>array('admin','lv-plan','support','basis/berechtigung','basis/variable','basis/studiengang','basis/ort','basis/firma','basis/fhausweis','basis/infoscreen','basis/organisationseinheit'), 'image'=>'vilesci_stammdaten.png', 'link'=>'left.php?categorie=Stammdaten', 'target'=>'nav', 'Betriebsmittel'=>array('name'=>'Betriebsmittel', 'link'=>'stammdaten/betriebsmittel_frameset.php', 'target'=>'main','permissions'=>array('basis/betriebsmittel')), - 'Reihungstest'=>array('name'=>'Reihungstest', 'link'=>'stammdaten/reihungstestverwaltung.php', 'target'=>'main','permissions'=>array('admin','assistenz')), + 'Reihungstest'=>array('name'=>'Reihungstest', 'link'=>'stammdaten/reihungstestverwaltung.php', 'target'=>'main','permissions'=>array('lehre/reihungstest')), - 'User'=>array + 'Rechtemanagement'=>array ( - 'name'=>'User', 'permissions'=>array('basis/variable','basis/berechtigung'), - 'Rechte'=>array('name'=>'Rechte', 'link'=>'stammdaten/berechtigungen.php', 'target'=>'main','permissions'=>array('basis/berechtigung')), + 'name'=>'Rechtemanagement', 'permissions'=>array('basis/berechtigung','mitarbeiter'), 'Berechtigungen'=>array('name'=>'Berechtigungen', 'link'=>'stammdaten/benutzerberechtigung_frameset.html', 'target'=>'main','permissions'=>array('basis/berechtigung')), + 'Rechte'=>array('name'=>'Rechte', 'link'=>'stammdaten/berechtigungen.php', 'target'=>'main','permissions'=>array('basis/berechtigung')), 'Rollen'=>array('name'=>'Rollen', 'link'=>'stammdaten/berechtigungrolle.php', 'target'=>'main','permissions'=>array('basis/berechtigung')), 'Funktionen'=>array('name'=>'Funktionen', 'link'=>'personen/funktion.php', 'target'=>'main', 'permissions'=>array('mitarbeiter')), - 'Variablen'=>array('name'=>'Variablen', 'link'=>'stammdaten/variablen_frameset.html', 'target'=>'main', 'target'=>'main','permissions'=>array('basis/variable')), ), 'Personal'=>array ( @@ -157,7 +156,7 @@ $menu=array 'Statistik'=>array('name'=>'Statistik', 'link'=>'stammdaten/statistik_frameset.html', 'target'=>'main','permissions'=>array('basis/statistik')), 'Ampel'=>array('name'=>'Ampel', 'link'=>'stammdaten/ampel_frameset.html', 'target'=>'main','permissions'=>array('basis/ampel')), 'Infoscreen'=>array('name'=>'Infoscreen', 'link'=>'stammdaten/infoscreen_frameset.html', 'target'=>'main','permissions'=>array('basis/infoscreen')), - 'Ferien'=>array('name'=>'Ferien', 'link'=>'lehre/ferienverwaltung.php', 'target'=>'main','permissions'=>array('admin')), + 'Ferien'=>array('name'=>'Ferien', 'link'=>'lehre/ferienverwaltung.php', 'target'=>'main','permissions'=>array('basis/ferien')), 'Service'=>array('name'=>'Service', 'link'=>'stammdaten/service_frameset.html', 'target'=>'main','permissions'=>array('basis/service')), 'Dokumentvorlagen'=>array('name'=>'Dokumentvorlagen', 'link'=>'stammdaten/dokumentvorlagen_verwaltung.php', 'target'=>'main','permissions'=>array('basis/dokumente')), 'GSProgramm'=>array('name'=>'GSProgramm', 'link'=>'stammdaten/gsprogramm.php', 'target'=>'main','permissions'=>array('inout/uebersicht')), diff --git a/vilesci/stammdaten/benutzerberechtigung_autocomplete.php b/vilesci/stammdaten/benutzerberechtigung_autocomplete.php index a888a5b67..774828c19 100644 --- a/vilesci/stammdaten/benutzerberechtigung_autocomplete.php +++ b/vilesci/stammdaten/benutzerberechtigung_autocomplete.php @@ -98,17 +98,29 @@ if (isset($_REQUEST['autocomplete']) && $_REQUEST['autocomplete'] == 'oe_kurzbz' if(is_array($oe->result) && count($oe->result) > 0) { - $result_obj = array(); + $resultArray = array(); foreach($oe->result as $row) { if($row->aktiv==true) { - $item['oe_kurzbz'] = html_entity_decode($row->oe_kurzbz); - $item['organisationseinheittyp_kurzbz'] = html_entity_decode($row->organisationseinheittyp_kurzbz); - $item['bezeichnung'] = html_entity_decode($row->bezeichnung); - $result_obj[] = $item; + $resultArray[html_entity_decode($row->oe_kurzbz)] = array('organisationseinheittyp_kurzbz' => html_entity_decode($row->organisationseinheittyp_kurzbz),'bezeichnung' => html_entity_decode($row->bezeichnung)); } } + + usort($resultArray, function($a, $b) + { + return $a['organisationseinheittyp_kurzbz'] <=> $b['organisationseinheittyp_kurzbz']; + }); + + $result_obj = array(); + foreach($resultArray as $key => $value) + { + $item['oe_kurzbz'] = $key; + $item['organisationseinheittyp_kurzbz'] = $value['organisationseinheittyp_kurzbz']; + $item['bezeichnung'] = $value['bezeichnung']; + $result_obj[] = $item; + } + echo json_encode($result_obj); } exit(); diff --git a/vilesci/stammdaten/benutzerberechtigung_details.php b/vilesci/stammdaten/benutzerberechtigung_details.php index 7ae0e711b..b230d702f 100644 --- a/vilesci/stammdaten/benutzerberechtigung_details.php +++ b/vilesci/stammdaten/benutzerberechtigung_details.php @@ -599,7 +599,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz'])) } if (count($bn) > 0) { - $htmlstr .= "

Rechte Details

"; + $htmlstr .= "

Rechte Detailaufschlüsselung

"; } } elseif(isset($_REQUEST['funktion_kurzbz']) && $_REQUEST['funktion_kurzbz']!='') diff --git a/vilesci/stammdaten/benutzerberechtigung_uebersicht.php b/vilesci/stammdaten/benutzerberechtigung_uebersicht.php index d986d6642..0be268b70 100644 --- a/vilesci/stammdaten/benutzerberechtigung_uebersicht.php +++ b/vilesci/stammdaten/benutzerberechtigung_uebersicht.php @@ -182,7 +182,7 @@ $(document).ready(function() -

Benutzerberechtigungen Übersicht

'; +

Berechtigungen Übersicht

'; if (!$db = new basis_db()) die('Es konnte keine Verbindung zum Server aufgebaut werden.'); @@ -229,7 +229,7 @@ $htmlstr='

- Berechtigung: + Rechte:
Kurzbz BeschreibungAktionAktion
- +
+ + + + +
+
+ Rolle kopieren + +
+ Rolle löschen
+ + + + + + + + + + + + + + + + + + + + + + + + +
{{p.t('lehre', 'studiengang')}}{{data.bezeichnung}}
{{p.t('lehre', 'organisationsform')}}{{data.orgform_bezeichnung}}
{{p.t('projektarbeitsbeurteilung', 'nameStudierende')}}{{data.name}}
{{p.t('person', 'personenkennzeichen')}}{{data.matrikelnr}}
{{p.t('lehre', 'studienjahr')}}{{data.studienjahr_kurzbz}}
{{p.t('lehre', 'semester')}}{{data.semester}}
+
+
+
{{p.t('studierendenantrag', 'antrag_grund')}}:
+
{{data.grund}}
+
+
+ + +
+ ` +} diff --git a/public/js/components/Studierendenantrag/Leitung/Actions/New.js b/public/js/components/Studierendenantrag/Leitung/Actions/New.js index 6169fef72..9fb5e7a64 100644 --- a/public/js/components/Studierendenantrag/Leitung/Actions/New.js +++ b/public/js/components/Studierendenantrag/Leitung/Actions/New.js @@ -79,6 +79,7 @@ export default { @complete="loadData" inputId="newAntragModalAutoComplete" dropdown + dropdown-mode="current" > ` } diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index a754cf277..155ef3217 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -18363,26 +18363,6 @@ array( ) ) ), - array( - 'app' => 'core', - 'category' => 'studierendenantrag', - 'phrase' => 'antraege_header', - 'insertvon' => 'system', - 'phrases' => array( - array( - 'sprache' => 'German', - 'text' => 'Anträge auf Änderung des Studierendenstatus', - 'description' => '', - 'insertvon' => 'system' - ), - array( - 'sprache' => 'English', - 'text' => 'Requests for changing the Studierendenstatus', - 'description' => '', - 'insertvon' => 'system' - ) - ) - ), array( 'app' => 'core', 'category' => 'studierendenantrag', @@ -18391,13 +18371,13 @@ array( 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Antrag auf Änderung des Studierendenstatus', + 'text' => 'Verwaltung des Studierendenstatus', 'description' => '', 'insertvon' => 'system' ), array( 'sprache' => 'English', - 'text' => 'Request for changing the Studierendenstatus', + 'text' => 'Management of student status', 'description' => '', 'insertvon' => 'system' ) @@ -19073,13 +19053,13 @@ array( 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Genehmigen', + 'text' => 'Bestätigen', 'description' => '', 'insertvon' => 'system' ), array( 'sprache' => 'English', - 'text' => 'Approve', + 'text' => 'Confirm', 'description' => '', 'insertvon' => 'system' ) From 6f1eed669643690be9c472b5f147aed3654d76b9 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Tue, 11 Jul 2023 17:01:22 +0200 Subject: [PATCH 251/439] =?UTF-8?q?Abbrecher=202dos:=20=C3=84nderungen=20W?= =?UTF-8?q?ordings,=20neue=20Statusgr=C3=BCnde=20preabbrecher,=20durchStgl?= =?UTF-8?q?,=20durchStud,=20update=20setAbbrecher?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/controllers/jobs/AntragJob.php | 11 ++-- application/libraries/AntragLib.php | 54 +++++++++++++------ application/libraries/PrestudentLib.php | 17 ++++-- .../models/crm/Prestudentstatus_model.php | 16 ++++++ .../27351_digitalisierung_formulare.php | 39 ++++++++++++++ 5 files changed, 113 insertions(+), 24 deletions(-) diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index 71068fbe9..39c2519af 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -177,9 +177,14 @@ class AntragJob extends JOB_Controller $dateDeadline = new DateTime(); $dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline)); + $this->StudierendenantragModel->addSelect('prestudent_id'); + $this->StudierendenantragModel->addSelect('studiensemester_kurzbz'); + $this->StudierendenantragModel->addSelect('s.insertamum'); + $result = $this->StudierendenantragModel->getWithLastStatusWhere( [ - 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED_STGL, + 'typ' => Studierendenantrag_model::TYP_ABMELDUNG_STGL, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, 's.insertamum <=' => $dateDeadline->format('c') ] ); @@ -195,8 +200,8 @@ class AntragJob extends JOB_Controller foreach ($antraege as $antrag) { - $result = $this->antraglib->approveAbmeldung([$antrag->studierendenantrag_id], $insertvon); + $result = $this->prestudentlib->setAbbrecher($antrag->prestudent_id, $antrag->studiensemester_kurzbz, $insertvon, 'abbrecherStgl', $antrag->insertamum); if (isError($result)) $this->logError(getError($result)); else @@ -316,7 +321,7 @@ class AntragJob extends JOB_Controller 'urlCIS' => $urlCIS, 'fristablauf' => $fristende->format('d.m.Y') ); - + // NOTE(chris): Sancho mail if(sendSanchoMail('Sancho_Mail_Antrag_W_' . $name, $dataMail, $email, $subject)) { diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index 190997c19..d02ce9012 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -137,26 +137,21 @@ class AntragLib $errors[] = $this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $studierendenantrag_id]); continue; } - $status = getData($result)[0]; + $antrag = getData($result)[0]; + + $insertam = date('c'); $result = $this->_ci->StudierendenantragstatusModel->insert([ 'studierendenantrag_id' => $studierendenantrag_id, 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, - 'insertvon' => $insertvon + 'insertvon' => $insertvon, + 'insertam' => $insertam ]); if (isError($result)) $errors[] = getError($result); else { - $resultPrestudent = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); - if (isError($resultPrestudent)) + if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG) { - $errors[] = getError($resultPrestudent); - continue; - } - if ($status->typ == Studierendenantrag_model::TYP_ABMELDUNG) - { - $antrag = getData($resultPrestudent)[0]; - $resultPrestudentStatus = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($antrag->prestudent_id); if (isError($resultPrestudentStatus)) $errors[] = getError($resultPrestudentStatus); @@ -167,7 +162,7 @@ class AntragLib $vorlage ='Sancho_Mail_Antrag_A_Approve'; $subject = $this->_ci->p->t('studierendenantrag', 'mail_subject_A_Approve'); - $result = $this->_ci->prestudentlib->setAbbrecher($antrag->prestudent_id, $antrag->studiensemester_kurzbz, $insertvon); + $result = $this->_ci->prestudentlib->setAbbrecher($antrag->prestudent_id, $antrag->studiensemester_kurzbz, $insertvon, 'abbrecherStud', $antrag->datum, $insertam) ; if (isError($result)) { $errors[] = getError($result); @@ -186,8 +181,35 @@ class AntragLib sendSanchoMail($vorlage, $data, $prestudent_status->email, $subject); } } - if ($status->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) { - $res = $this->_ci->PrestudentModel->load($status->prestudent_id); + if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) { + $result = $this->_ci->PrestudentstatusModel->getLastStatus($antrag->prestudent_id, '', 'Student'); + if (isError($result)) + { + $errors[] = getError($result); + continue; + } + if(!hasData($result)) + { + $errors[] = $this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', ['prestudent_id' => $antrag->prestudent_id]); + continue; + } + $prestudentstatus = getData($result)[0]; + + $result = $this->_ci->PrestudentstatusModel->withGrund('preabbrecher')->update([ + 'prestudent_id' => $prestudentstatus->prestudent_id, + 'status_kurzbz'=>$prestudentstatus->status_kurzbz, + 'studiensemester_kurzbz'=>$prestudentstatus->studiensemester_kurzbz, + 'ausbildungssemester'=>$prestudentstatus->ausbildungssemester + ],[]); + if (isError($result)) + { + $errors[] = getError($result); + continue; + } + + + $res = $this->_ci->PrestudentModel->load($antrag->prestudent_id); + if (hasData($res)) { $prestudent = current(getData($res)); $res = $this->_ci->PersonModel->load($prestudent->person_id); @@ -205,7 +227,7 @@ class AntragLib 'Sancho_Mail_Antrag_A_Stgl', [ 'name' => $name, - 'grund' => $status->grund + 'grund' => $antrag->grund ], $email, $this->_ci->p->t('studierendenantrag', 'mail_subject_A_Stgl') @@ -857,7 +879,7 @@ class AntragLib if (!hasData($result)) return error($this->_ci->p->t('studierendenantrag', 'error_no_stg', ['studiengang_kz' => $studiengang_kz])); $stg = current(getData($result)); - + if ($ausbildungssemester > $stg->max_semester) return success(); return error($this->_ci->p->t('studierendenantrag', 'error_no_studienplan', [ diff --git a/application/libraries/PrestudentLib.php b/application/libraries/PrestudentLib.php index 5024c6c22..bb1250a62 100644 --- a/application/libraries/PrestudentLib.php +++ b/application/libraries/PrestudentLib.php @@ -35,7 +35,7 @@ class PrestudentLib } - public function setAbbrecher($prestudent_id, $studiensemester_kurzbz, $insertvon = null) + public function setAbbrecher($prestudent_id, $studiensemester_kurzbz, $insertvon = null, $statusgrund_kurzbz = null, $datum = null, $bestaetigtam = null) { if (!$insertvon) $insertvon = getAuthUID(); @@ -62,24 +62,31 @@ class PrestudentLib $student = current($result); - //Status updaten - $result = $this->_ci->PrestudentstatusModel->insert([ + if(!$datum) + $datum = date('c'); + + if(!$bestaetigtam) + $bestaetigtam = date('c'); + + //Status und Statusgrund updaten + $result = $this->_ci->PrestudentstatusModel->withGrund($statusgrund_kurzbz)->insert([ 'prestudent_id' => $prestudent_id, 'status_kurzbz' => Prestudentstatus_model::STATUS_ABBRECHER, 'studiensemester_kurzbz' => $studiensemester_kurzbz, 'ausbildungssemester' => $prestudent_status->ausbildungssemester, - 'datum' => date('c'), + 'datum' => $datum, 'insertvon' => $insertvon, 'insertamum' => date('c'), 'orgform_kurzbz'=> $prestudent_status->orgform_kurzbz, 'studienplan_id'=> $prestudent_status->studienplan_id, 'bestaetigtvon' => $insertvon, - 'bestaetigtam' => date('c') + 'bestaetigtam' => $bestaetigtam ]); if (isError($result)) return $result; + //Verband anlegen $result = $this->_ci->LehrverbandModel->load([ 'studiengang_kz' => $student->studiengang_kz, diff --git a/application/models/crm/Prestudentstatus_model.php b/application/models/crm/Prestudentstatus_model.php index 620b897e6..ddf8d3a7a 100644 --- a/application/models/crm/Prestudentstatus_model.php +++ b/application/models/crm/Prestudentstatus_model.php @@ -316,4 +316,20 @@ class Prestudentstatus_model extends DB_Model return $this->loadWhere($whereArr); } + + /** + * call like this: + * $this->PrestudentstatusModel->withGrund('grund_kurzbz')->update($id, $otherData); + * or: + * $this->PrestudentstatusModel->withGrund('grund_kurzbz')->insert($otherData); + * @param string $statusgrund_kurzbz + * @return object $this + */ + public function withGrund($statusgrund_kurzbz) + { + if($statusgrund_kurzbz) + $this->db->set('statusgrund_id', '(SELECT statusgrund_id FROM public.tbl_status_grund WHERE statusgrund_kurzbz =' . $this->db->escape($statusgrund_kurzbz) .')', FALSE); + + return $this; + } } diff --git a/system/dbupdate_3.4/27351_digitalisierung_formulare.php b/system/dbupdate_3.4/27351_digitalisierung_formulare.php index 1fbe56945..5041b86f5 100644 --- a/system/dbupdate_3.4/27351_digitalisierung_formulare.php +++ b/system/dbupdate_3.4/27351_digitalisierung_formulare.php @@ -285,3 +285,42 @@ if (!$result = @$db->db_query("SELECT public.get_stdsem_prestudent(0, null)")) { else echo '
public.get_stdsem_prestudent(integer, character varying): function created'; } + +if($result = @$db->db_query("SELECT 1 FROM public.tbl_status_grund WHERE statusgrund_kurzbz = 'abbrecherStgl';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig) VALUES('abbrecherStgl', 'Abbrecher', TRUE, '{\"durch Stgl\", \"by Course Director\"}', '{\"durch Stgl\", \"by Course Director\"}');"; + + if(!$db->db_query($qry)) + echo 'public.tbl_status_grund '.$db->db_last_error().'
'; + else + echo ' public.tbl_status_grund: Added Statusgrund abbrecherStgl for Abbrecher
'; + } +} + +if($result = @$db->db_query("SELECT 1 FROM public.tbl_status_grund WHERE statusgrund_kurzbz = 'abbrecherStud';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig) VALUES('abbrecherStud', 'Abbrecher', TRUE, '{\"durch Stud\", \"by Student\"}', '{\"durch Stud\", \"by Student\"}');"; + + if(!$db->db_query($qry)) + echo 'public.tbl_status_grund '.$db->db_last_error().'
'; + else + echo ' public.tbl_status_grund: Added Statusgrund abbrecherStud for Abbrecher
'; + } +} + +if($result = @$db->db_query("SELECT 1 FROM public.tbl_status_grund WHERE statusgrund_kurzbz = 'preabbrecher';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig) VALUES('preabbrecher', 'Student', TRUE, '{\"Pre-Abbrecher\", \"Pre-Aborted\"}', '{\"Pre-Abbrecher\", \"Pre-Aborted\"}');"; + + if(!$db->db_query($qry)) + echo 'public.tbl_status_grund '.$db->db_last_error().'
'; + else + echo ' public.tbl_status_grund: Added Statusgrund pre-abbrecher for Student
'; + } +} From 3192a1b3f2ebd7f4717a90e16ac728a93e9a2698 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 12 Jul 2023 09:47:01 +0200 Subject: [PATCH 252/439] - job hinzugefuegt um bewerber status automatisch zu setzen - fas filter hinzugefugt --- include/prestudent.class.php | 36 +++++++++++++++++++++++ rdf/lehrverbandsgruppe.rdf.php | 52 ++++++++++++++++++++++++++++++++-- rdf/student.rdf.php | 2 +- 3 files changed, 86 insertions(+), 4 deletions(-) diff --git a/include/prestudent.class.php b/include/prestudent.class.php index 13f3e5e00..557412413 100644 --- a/include/prestudent.class.php +++ b/include/prestudent.class.php @@ -870,6 +870,42 @@ class prestudent extends person AND tbl_reihungstest.studiensemester_kurzbz=".$this->db_add_param($studiensemester_kurzbz)." )"; break; + case "bewerberrtnichtangemeldet": + $qry.=" AND a.rolle='Bewerber' + AND NOT EXISTS ( + SELECT + 1 + FROM + public.tbl_rt_person + JOIN public.tbl_reihungstest ON (rt_id = reihungstest_id) + WHERE + person_id=a.person_id + AND studienplan_id IN ( + SELECT studienplan_id FROM lehre.tbl_studienplan + JOIN lehre.tbl_studienordnung USING(studienordnung_id) + WHERE tbl_studienordnung.studiengang_kz=a.studiengang_kz + ) + AND tbl_reihungstest.studiensemester_kurzbz=".$this->db_add_param($studiensemester_kurzbz)." + )"; + break; + case "bewerberrtangemeldet": + $qry.=" AND a.rolle='Bewerber' + AND EXISTS ( + SELECT + 1 + FROM + public.tbl_rt_person + JOIN public.tbl_reihungstest ON (rt_id = reihungstest_id) + WHERE + person_id=a.person_id + AND studienplan_id IN ( + SELECT studienplan_id FROM lehre.tbl_studienplan + JOIN lehre.tbl_studienordnung USING(studienordnung_id) + WHERE tbl_studienordnung.studiengang_kz=a.studiengang_kz + ) + AND tbl_reihungstest.studiensemester_kurzbz=".$this->db_add_param($studiensemester_kurzbz)." + )"; + break; case "zgv": $stg_obj = new studiengang(); $stg_obj->load($studiengang_kz); diff --git a/rdf/lehrverbandsgruppe.rdf.php b/rdf/lehrverbandsgruppe.rdf.php index 20956d279..19affa245 100644 --- a/rdf/lehrverbandsgruppe.rdf.php +++ b/rdf/lehrverbandsgruppe.rdf.php @@ -290,6 +290,24 @@ function draw_orgformsubmenu($stg_kz, $orgform) bewerber + + + Nicht zum Reihungstest angemeldet + + + studiensemester_kurzbz.']]> + bewerberrtnichtangemeldet + + + + + Reihungstest angemeldet + + + studiensemester_kurzbz.']]> + bewerberrtangemeldet + + Aufgenommen @@ -344,8 +362,14 @@ function draw_orgformsubmenu($stg_kz, $orgform) $orgform_sequence[$stg_kz].= "\t\t\t\tstudiensemester_kurzbz/interessenten/reihungstestangemeldet\" />\n"; $orgform_sequence[$stg_kz].= "\t\t\t\t"; $orgform_sequence[$stg_kz].= "\n\t\t\t\n"; - - $orgform_sequence[$stg_kz].= "\t\t\tstudiensemester_kurzbz/bewerber\" />\n"; + + $orgform_sequence[$stg_kz].= "\t\t\t"; + $orgform_sequence[$stg_kz].= "\n\t\t\t\tstudiensemester_kurzbz/bewerber\">\n"; + $orgform_sequence[$stg_kz].= "\t\t\tstudiensemester_kurzbz/bewerber/reihungstestnichtangemeldet\" />\n"; + $orgform_sequence[$stg_kz].= "\t\t\tstudiensemester_kurzbz/bewerber/reihungstestangemeldet\" />\n"; + $orgform_sequence[$stg_kz].= "\t\t\t\t"; + $orgform_sequence[$stg_kz].= "\n\t\t\t\n"; + $orgform_sequence[$stg_kz].= "\t\t\tstudiensemester_kurzbz/aufgenommen\" />\n"; $orgform_sequence[$stg_kz].= "\t\t\tstudiensemester_kurzbz/warteliste\" />\n"; $orgform_sequence[$stg_kz].= "\t\t\tstudiensemester_kurzbz/absage\" />\n"; @@ -624,6 +648,22 @@ while ($row=$dbo->db_fetch_object()) + + + ]]> + studiengang_kz; ?>]]> + studiensemester_kurzbz; ?>]]> + + + + + + ]]> + studiengang_kz; ?>]]> + studiensemester_kurzbz; ?>]]> + + + ]]> @@ -832,8 +872,14 @@ draw_orgformpart($stg_kz); echo "\t\t\t\tstudiensemester_kurzbz/interessenten/reihungstestangemeldet\" />\n"; echo "\t\t\t\t"; echo "\n\t\t\t\n"; + + echo "\t\t\t"; + echo "\t\t\t\tstudiensemester_kurzbz/bewerber\">\n"; + echo "\t\t\t\tstudiensemester_kurzbz/bewerber/reihungstestnichtangemeldet\" />\n"; + echo "\t\t\t\tstudiensemester_kurzbz/bewerber/reihungstestangemeldet\" />\n"; + echo "\t\t\t\t"; + echo "\n\t\t\t\n"; - echo "\t\t\t\tstudiensemester_kurzbz/bewerber\" />\n"; echo "\t\t\t\tstudiensemester_kurzbz/aufgenommen\" />\n"; echo "\t\t\t\tstudiensemester_kurzbz/warteliste\" />\n"; echo "\t\t\t\tstudiensemester_kurzbz/absage\" />\n"; diff --git a/rdf/student.rdf.php b/rdf/student.rdf.php index 11e841c2b..1625f161c 100644 --- a/rdf/student.rdf.php +++ b/rdf/student.rdf.php @@ -737,7 +737,7 @@ if($xmlformat=='rdf') } elseif(in_array($typ, array('prestudent', 'interessenten', 'bewerber', 'aufgenommen', 'warteliste', 'absage', 'zgv', 'reihungstestangemeldet', 'reihungstestnichtangemeldet', 'absolvent', - 'diplomand', 'bewerbungnichtabgeschickt', 'bewerbungabgeschickt', 'statusbestaetigt', 'statusbestaetigtrtnichtangemeldet', 'statusbestaetigtrtangemeldet'))) + 'diplomand', 'bewerbungnichtabgeschickt', 'bewerbungabgeschickt', 'statusbestaetigt', 'statusbestaetigtrtnichtangemeldet', 'statusbestaetigtrtangemeldet', 'bewerberrtangemeldet', 'bewerberrtnichtangemeldet'))) { $prestd = new prestudent(); From f8da119ad78917de274dc7e11e12131592b02874 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Thu, 13 Jul 2023 11:48:25 +0200 Subject: [PATCH 253/439] Abmeldung: Einspruch Abgelehnt handling --- .../controllers/components/Antrag/Leitung.php | 2 +- application/controllers/jobs/AntragJob.php | 1 - application/libraries/AntragLib.php | 77 ++++++++++++++++++- .../Studierendenantragstatus_model.php | 1 + .../27351_digitalisierung_formulare.php | 5 +- system/phrasesupdate.php | 40 ++++++++++ 6 files changed, 121 insertions(+), 5 deletions(-) diff --git a/application/controllers/components/Antrag/Leitung.php b/application/controllers/components/Antrag/Leitung.php index 9df8fdb75..c107fbb63 100644 --- a/application/controllers/components/Antrag/Leitung.php +++ b/application/controllers/components/Antrag/Leitung.php @@ -145,7 +145,7 @@ class Leitung extends FHC_Controller $studierendenantrag_id = $this->input->post('studierendenantrag_id'); - $result = $this->antraglib->approveAbmeldung([$studierendenantrag_id], getAuthUID()); + $result = $this->antraglib->denyObjectionAbmeldung($studierendenantrag_id, getAuthUID()); if (isError($result)) return $this->outputJsonError(['studierendenantrag_id' => getError($result)]); diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index 39c2519af..ca4f06690 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -200,7 +200,6 @@ class AntragJob extends JOB_Controller foreach ($antraege as $antrag) { - $result = $this->prestudentlib->setAbbrecher($antrag->prestudent_id, $antrag->studiensemester_kurzbz, $insertvon, 'abbrecherStgl', $antrag->insertamum); if (isError($result)) $this->logError(getError($result)); diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index d02ce9012..c725c6ea9 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -145,7 +145,7 @@ class AntragLib 'studierendenantrag_id' => $studierendenantrag_id, 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED, 'insertvon' => $insertvon, - 'insertam' => $insertam + 'insertamum' => $insertam ]); if (isError($result)) $errors[] = getError($result); @@ -244,6 +244,81 @@ class AntragLib return success(); } + /** + * @param integer $studierendenantrag_id + * @param string $insertvon + * + * @return stdClass + */ + public function denyObjectionAbmeldung($studierendenantrag_id, $insertvon) + { + $result = $this->_ci->StudierendenantragModel->load($studierendenantrag_id); + if (isError($result)) + { + return $result; + } + if(!hasData($result)) + { + return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $studierendenantrag_id])); + } + $antrag = getData($result)[0]; + + $result = $this->_ci->StudierendenantragstatusModel->loadWhere([ + 'studierendenantrag_id' => $studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED + ]); + if (isError($result)) + return $result; + if (!hasData($result)) + return error($this->_ci->p->t('studierendenantrag', 'error_not_approved')); + + $status = current(getData($result)); + + $result = $this->_ci->StudierendenantragstatusModel->insert([ + 'studierendenantrag_id' => $studierendenantrag_id, + 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_OBJECTION_DENIED, + 'insertvon' => $insertvon + ]); + if (isError($result)) + return $result; + else { + $result = $this->_ci->prestudentlib->setAbbrecher($antrag->prestudent_id, $antrag->studiensemester_kurzbz, $insertvon, 'abbrecherStgl', $status->insertamum); + + if (isError($result)) + return $result; + + $res = $this->_ci->PrestudentModel->load($antrag->prestudent_id); + + if (hasData($res)) { + $prestudent = current(getData($res)); + $res = $this->_ci->PersonModel->load($prestudent->person_id); + if (hasData($res)) { + $person = current(getData($res)); + $name = trim($person->vorname . ' ' . $person->nachname); + } else { + $name = $this->_ci->p->t('person', 'studentIn'); + } + $res = $this->_ci->KontaktModel->getZustellKontakt($prestudent->person_id, ['email']); + if (hasData($res)) { + $kontakt = current(getData($res)); + $email = $kontakt->kontakt; + sendSanchoMail( + // TODO(chris): Vorlage erstellen + 'Sancho_Mail_Antrag_A_ObjectionDenied', + [ + 'name' => $name, + 'grund' => $antrag->grund + ], + $email, + $this->_ci->p->t('studierendenantrag', 'mail_subject_A_ObjectionDenied') + ); + } + } + } + + return success(); + } + /** * NOTE(chris): permissions & verification must be handled outside * diff --git a/application/models/education/Studierendenantragstatus_model.php b/application/models/education/Studierendenantragstatus_model.php index 8f737f458..5355ecdba 100644 --- a/application/models/education/Studierendenantragstatus_model.php +++ b/application/models/education/Studierendenantragstatus_model.php @@ -13,6 +13,7 @@ class Studierendenantragstatus_model extends DB_Model const STATUS_REQUESTSENT_1 = 'ErsteAufforderungVersandt'; const STATUS_REQUESTSENT_2 = 'ZweiteAufforderungVersandt'; const STATUS_OBJECTED = 'Beeinsprucht'; + const STATUS_OBJECTION_DENIED = 'EinspruchAbgelehnt'; /** * Constructor diff --git a/system/dbupdate_3.4/27351_digitalisierung_formulare.php b/system/dbupdate_3.4/27351_digitalisierung_formulare.php index 5041b86f5..341b34b67 100644 --- a/system/dbupdate_3.4/27351_digitalisierung_formulare.php +++ b/system/dbupdate_3.4/27351_digitalisierung_formulare.php @@ -28,15 +28,16 @@ if($result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statust VALUES ('Erstellt', '{\"Erstellt\",\"Created\"}'), ('Genehmigt', '{\"Genehmigt\",\"Approved\"}'), - ('Beeinsprucht', '{\"Beeinsprucht\",\"Objected\"}'), ('Abgelehnt', '{\"Abgelehnt\",\"Rejected\"}'), ('Verzichtet', '{\"Verzichtet\",\"Pass\"}'), ('Offen', '{\"Offen\",\"Reopened\"}'), ('Zurückgezogen', '{\"Zurückgezogen\",\"Cancelled\"}'), + ('Lvszugewiesen', '{\"Lvszugewiesen\",\"Lvsassigned\"}'), ('EmailVersandt', '{\"Email Versandt\",\"Reminder Sent\"}'), ('ErsteAufforderungVersandt', '{\"1.Aufforderung Versandt\",\"1st Request Sent\"}'), ('ZweiteAufforderungVersandt', '{\"2.Aufforderung Versandt\",\"2nd Request Sent\"}'), - ('Lvszugewiesen', '{\"Lvszugewiesen\",\"Lvsassigned\"}'); + ('Beeinsprucht', '{\"Beeinsprucht\",\"Objected\"}'), + ('EinspruchAbgelehnt', '{\"Einspruch abgelehnt\",\"Objection denied\"}'); "; if (!$db->db_query($qry)) echo 'campus.tbl_studierendenantrag_statustyp (insert): '.$db->db_last_error().'
'; diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 155ef3217..18a61f1d1 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -20106,6 +20106,26 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'error_not_approved', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Antrag ist nicht bestätigt worden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Application is not approved', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'studierendenantrag', @@ -20426,6 +20446,26 @@ array( ) ) ), + array( + 'app' => 'core', + 'category' => 'studierendenantrag', + 'phrase' => 'mail_subject_A_ObjectionDenied', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Ihr Einspruch wurde Abgelehnt', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Your objection was denied', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), array( 'app' => 'core', 'category' => 'studierendenantrag', From c8fc6c747ffea3803de12716469e593378c925ae Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Thu, 13 Jul 2023 13:57:17 +0200 Subject: [PATCH 254/439] Table height & Bug: Allowed/Shown Stgs in Component --- .../controllers/components/Antrag/Leitung.php | 44 +++++++++++++++++++ .../controllers/lehre/Studierendenantrag.php | 4 +- .../models/organisation/Studiengang_model.php | 14 ++++++ .../components/Studierendenantrag/Leitung.js | 39 ++++++++-------- .../Studierendenantrag/Leitung/Table.js | 2 +- 5 files changed, 80 insertions(+), 23 deletions(-) diff --git a/application/controllers/components/Antrag/Leitung.php b/application/controllers/components/Antrag/Leitung.php index c107fbb63..54e5b65e6 100644 --- a/application/controllers/components/Antrag/Leitung.php +++ b/application/controllers/components/Antrag/Leitung.php @@ -29,6 +29,50 @@ class Leitung extends FHC_Controller //------------------------------------------------------------------------------------------------------------------ // Public methods + public function getActiveStgs() + { + $studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe'); + $stgsNeuanlage = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag'); + + $stgs = []; + + if ($studiengaenge) { + $result = $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); + + if (isError($result)) + return $this->outputJson($result); + $antraege = getData($result) ?: []; + + foreach ($antraege as $antrag) { + if (!isset($stgs[$antrag->studiengang_kz])) { + $stgs[$antrag->studiengang_kz] = new stdClass(); + $stgs[$antrag->studiengang_kz]->bezeichnung = $antrag->bezeichnung; + $stgs[$antrag->studiengang_kz]->orgform = $antrag->orgform; + $stgs[$antrag->studiengang_kz]->studiengang_kz = $antrag->studiengang_kz; + } + } + } + + if ($stgsNeuanlage) { + $result = $this->StudierendenantragModel->loadForStudiengaenge($stgsNeuanlage); + + if (isError($result)) + return $this->outputJson($result); + $antraege = getData($result) ?: []; + + foreach ($antraege as $antrag) { + if (!isset($stgs[$antrag->studiengang_kz])) { + $stgs[$antrag->studiengang_kz] = new stdClass(); + $stgs[$antrag->studiengang_kz]->bezeichnung = $antrag->bezeichnung; + $stgs[$antrag->studiengang_kz]->orgform = $antrag->orgform; + $stgs[$antrag->studiengang_kz]->studiengang_kz = $antrag->studiengang_kz; + } + } + } + + $this->outputJsonSuccess($stgs); + } + public function getAntraege($studiengang = null) { diff --git a/application/controllers/lehre/Studierendenantrag.php b/application/controllers/lehre/Studierendenantrag.php index f27350e9a..c0ac284b3 100644 --- a/application/controllers/lehre/Studierendenantrag.php +++ b/application/controllers/lehre/Studierendenantrag.php @@ -82,7 +82,7 @@ class Studierendenantrag extends FHC_Controller $stgL = []; if ($studiengaenge) { - $result = $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge); + $result = $this->StudiengangModel->loadWithOrgform($studiengaenge); if (isError($result)) return show_error(getError($result)); $antraege = getData($result) ?: []; @@ -99,7 +99,7 @@ class Studierendenantrag extends FHC_Controller $stgA = []; if ($stgsNeuanlage) { - $result = $this->StudierendenantragModel->loadForStudiengaenge($stgsNeuanlage); + $result = $this->StudiengangModel->loadWithOrgform($stgsNeuanlage); if (isError($result)) return show_error(getError($result)); $antraege = getData($result) ?: []; diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index 0d2328b14..1fb733d04 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -525,6 +525,20 @@ class Studiengang_model extends DB_Model return $this->execQuery($query, $params); } + public function loadWithOrgform($studiengang_kzs) + { + $sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; + + $this->addSelect($this->dbTable . '.*'); + $this->addSelect('o.bezeichnung_mehrsprachig[(' . $sql . ')] AS orgform'); + + $this->addJoin('bis.tbl_orgform o', 'orgform_kurzbz'); + + $this->db->where_in($this->dbTable . '.studiengang_kz', $studiengang_kzs); + + return $this->load(); + } + /** * @param array $studiengang_kzs * @param array $not_antrag_typ (optional) If the prestudent has an antrag with one of the specified types it will be excluded from the result diff --git a/public/js/components/Studierendenantrag/Leitung.js b/public/js/components/Studierendenantrag/Leitung.js index f08da3879..ba7af0a2c 100644 --- a/public/js/components/Studierendenantrag/Leitung.js +++ b/public/js/components/Studierendenantrag/Leitung.js @@ -23,45 +23,41 @@ export default { return { filter: undefined, selectedData: [], - columns: [] + columns: [], + stgs: [] } }, computed: { - stgs(){ - if(!this.stgL || !this.stgA) - return[]; - let undesiredOutput = [...this.stgL, ...this.stgA]; - let desiredOutput = undesiredOutput.reduce( - (accumulator, currentValue)=> - { - accumulator[currentValue.studiengang_kz] = currentValue; - return accumulator; - }, - {} - ); - return Object.values(desiredOutput); - - }, - stgkzL() - { + stgkzL() { if (!this.stgL) return []; return this.stgL.map(stg => stg.studiengang_kz); }, - stgkzA() - { + stgkzA() { if (!this.stgA) return []; return this.stgA.map(stg => stg.studiengang_kz); } }, methods: { + loadFilter() { + axios.get( + FHC_JS_DATA_STORAGE_OBJECT.app_root + + FHC_JS_DATA_STORAGE_OBJECT.ci_router + + '/components/Antrag/Leitung/getActiveStgs' + ).then(result => { + this.stgs = Object.values(result.data.retval).sort((a,b) => a.bezeichnung == b.bezeichnung ? (a.orgform == b.orgform ? 0 : (a.orgform > b.orgform ? 1 : -1)) : (a.bezeichnung > b.bezeichnung ? 1 : -1)); + }).catch(error => { + console.error(error); + }); + }, changeFilter(evt) { this.filter = evt.target.value || undefined; this.reload(); }, reload() { this.$refs.table.reload(this.filter); + this.loadFilter(); }, download() { this.$refs.table.download(); @@ -270,6 +266,9 @@ export default { BsAlert.popup(msg, {dialogClass: 'alert alert-danger'}); } }, + created() { + this.loadFilter(); + }, template: `
Date: Thu, 13 Jul 2023 14:44:51 +0200 Subject: [PATCH 255/439] Bug: Studierenden-Ansicht: Abmeldung bearbeiten bei mehrfachen Abmeldungen --- .../controllers/components/Antrag/Abmeldung.php | 10 +++++++--- application/libraries/AntragLib.php | 8 ++++++-- .../components/Studierendenantrag/Form/Abmeldung.js | 13 ++++++++++--- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/application/controllers/components/Antrag/Abmeldung.php b/application/controllers/components/Antrag/Abmeldung.php index 8c728c804..55435c1f6 100644 --- a/application/controllers/components/Antrag/Abmeldung.php +++ b/application/controllers/components/Antrag/Abmeldung.php @@ -57,13 +57,17 @@ class Abmeldung extends FHC_Controller } elseif ($result == -1) { - $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id, Studierendenantrag_model::TYP_ABMELDUNG); + $result = $this->antraglib->getDetailsForLastAntrag($prestudent_id, [Studierendenantrag_model::TYP_ABMELDUNG, Studierendenantrag_model::TYP_ABMELDUNG_STGL]); if (isError($result)) { return $this->outputJsonError(getError($result)); } $data = getData($result); - $data->canCancel = (boolean)$this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id); + + $data->canCancel = ( + $data->status == Studierendenantragstatus_model::STATUS_CREATED && + $this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id) + ); return $this->outputJsonSuccess($data); } @@ -87,7 +91,7 @@ class Abmeldung extends FHC_Controller $data = getData($result); - if ($data->typ !== Studierendenantrag_model::TYP_ABMELDUNG_STGL) + if ($data->typ !== Studierendenantrag_model::TYP_ABMELDUNG_STGL && $data->typ !== Studierendenantrag_model::TYP_ABMELDUNG) return show_404(); $this->outputJsonSuccess($data); diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index c725c6ea9..bda165e0f 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -1204,8 +1204,12 @@ class AntragLib $where = [ 'prestudent_id' => $prestudent_id ]; - if ($typ) - $where['typ'] = $typ; + if ($typ) { + if (is_array($typ)) + $this->_ci->StudierendenantragModel->db->where_in('typ', $typ); + else + $where['typ'] = $typ; + } $result = $this->_ci->StudierendenantragModel->loadWithStatusWhere($where); if (isError($result)) return $result; diff --git a/public/js/components/Studierendenantrag/Form/Abmeldung.js b/public/js/components/Studierendenantrag/Form/Abmeldung.js index 0de6e3d16..7018237fb 100644 --- a/public/js/components/Studierendenantrag/Form/Abmeldung.js +++ b/public/js/components/Studierendenantrag/Form/Abmeldung.js @@ -15,7 +15,8 @@ export default { 'setStatus' ], props: { - prestudentId: Number + prestudentId: Number, + studierendenantragId: Number }, data() { return { @@ -35,6 +36,13 @@ export default { case 'Genehmigt': return 'success'; default: return 'info'; } + }, + loadUrl() { + if (this.studierendenantragId) + return '/components/Antrag/Abmeldung/getDetailsForAntrag/'+ + this.studierendenantragId; + return '/components/Antrag/Abmeldung/getDetailsForNewAntrag/' + + this.prestudentId; } }, methods: { @@ -42,8 +50,7 @@ export default { return axios.get( FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + - '/components/Antrag/Abmeldung/getDetailsForNewAntrag/' + - this.prestudentId + this.loadUrl ).then( result => { this.data = result.data.retval; From b04aefc105bc922c219099052f976ec0fc8a1765 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Thu, 13 Jul 2023 16:13:40 +0200 Subject: [PATCH 256/439] =?UTF-8?q?Unterbrechung=20nur=20f=C3=BCr=20das=20?= =?UTF-8?q?Aktuelle=20und=20kommende=20Semester?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/libraries/AntragLib.php | 45 ++++++++++--------- .../organisation/Studiensemester_model.php | 30 ------------- .../Studierendenantrag/Form/Unterbrechung.js | 37 ++++++++------- 3 files changed, 42 insertions(+), 70 deletions(-) diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index bda165e0f..6e05380a5 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -1279,35 +1279,38 @@ class AntragLib $this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel'); $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $semester = []; + $result = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $ausbildungssemester); if (!hasData($result)) - return []; + return $semester; - $studienplaene = getData($result); - $studienplan_ids = array_map(function ($studienplan) { - return $studienplan->studienplan_id; - }, $studienplaene); - - $result = $this->_ci->StudiensemesterModel->getFollowingSemester($studienplan_ids, $studiensemester_kurzbz, $ausbildungssemester); + $result = $this->_ci->StudiensemesterModel->getNextFrom($studiensemester_kurzbz); if (!hasData($result)) - return []; + return $semester; + $nextSem = current(getData($result)); - $stsems = getData($result); + $semester[] = [ + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'wiedereinstieg' => $nextSem->start + ]; - $result = $this->_ci->StudiensemesterModel->loadWhere(); + $result = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $nextSem->studiensemester_kurzbz, $ausbildungssemester+1); if (!hasData($result)) - return []; - $result = getData($result); - usort($result, function($a, $b) { - return $a->start > $b->start ? 1 : -1; - }); - foreach ($stsems as $stsem) { - $stsem->wiedereinstieg = array_filter($result, function ($sem) use ($stsem) { - return $sem->start > $stsem->ende; - }); - } + return $semester; - return $stsems; + $result = $this->_ci->StudiensemesterModel->getNextFrom($nextSem->studiensemester_kurzbz); + if (!hasData($result)) + return $semester; + + $semAfterNext = current(getData($result)); + + $semester[] = [ + 'studiensemester_kurzbz' => $nextSem->studiensemester_kurzbz, + 'wiedereinstieg' => $semAfterNext->start + ]; + + return $semester; } public function getAktivePrestudentenInStgs($studiengaenge, $query) diff --git a/application/models/organisation/Studiensemester_model.php b/application/models/organisation/Studiensemester_model.php index 6daa76b59..bb9b94c92 100644 --- a/application/models/organisation/Studiensemester_model.php +++ b/application/models/organisation/Studiensemester_model.php @@ -204,34 +204,4 @@ class Studiensemester_model extends DB_Model return $this->execQuery($query, array($studiensemester_kurzbz)); } - - public function getFollowingSemester($studienplan_ids, $studiensemester_kurzbz, $ausbildungssemester) - { - $query = ' - WITH RECURSIVE following(studiensemester_kurzbz, semester, start) AS ( - SELECT studiensemester_kurzbz, ?, start - FROM public.tbl_studiensemester - WHERE studiensemester_kurzbz=? - UNION ALL - SELECT * FROM ( - SELECT s.studiensemester_kurzbz, s.semester, ss.start - FROM lehre.tbl_studienplan_semester s - JOIN public.tbl_studiensemester ss USING(studiensemester_kurzbz) - INNER JOIN following a ON(s.semester=a.semester+1 AND ss.start > a.start) - WHERE studienplan_id IN ? - ORDER BY start ASC - LIMIT 1 - ) wrapper - ) - SELECT sem.*, following.semester - FROM following - LEFT JOIN ' . $this->dbTable . ' sem USING(studiensemester_kurzbz) - ORDER BY start'; - - return $this->execQuery($query, [ - $ausbildungssemester, - $studiensemester_kurzbz, - $studienplan_ids - ]); - } } diff --git a/public/js/components/Studierendenantrag/Form/Unterbrechung.js b/public/js/components/Studierendenantrag/Form/Unterbrechung.js index 2034361bc..e1322067f 100644 --- a/public/js/components/Studierendenantrag/Form/Unterbrechung.js +++ b/public/js/components/Studierendenantrag/Form/Unterbrechung.js @@ -53,9 +53,18 @@ export default { this.prestudentId; }, datumWsFormatted() { - if(!this.data.datum_wiedereinstieg) - return ''; - let datum = new Date(this.data.datum_wiedereinstieg); + let datumUnformatted = ''; + + if (this.studierendenantragId) { + if (this.data.datum_wiedereinstieg) + datumUnformatted = this.data.datum_wiedereinstieg; + } else { + if (this.stsem !== null && this.data.studiensemester[this.stsem].wiedereinstieg) + datumUnformatted = this.data.studiensemester[this.stsem].wiedereinstieg; + } + if (datumUnformatted === '') + return datumUnformatted; + let datum = new Date(datumUnformatted); return datum.toLocaleDateString(); } }, @@ -93,7 +102,7 @@ export default { formData.append("studiensemester", this.stsem !== null && this.data.studiensemester[this.stsem].studiensemester_kurzbz); formData.append("prestudent_id", this.data.prestudent_id); formData.append("grund", this.$refs.grund.value); - formData.append("datum_wiedereinstieg", this.$refs.datum_wiedereinstieg && this.$refs.datum_wiedereinstieg.value); + formData.append("datum_wiedereinstieg", this.stsem !== null && this.data.studiensemester[this.stsem].wiedereinstieg); axios.post( FHC_JS_DATA_STORAGE_OBJECT.app_root + @@ -267,21 +276,11 @@ export default {
{{datumWsFormatted}}
-
- - +
+ {{p.t('ui/select_studiensemester')}} +
+
+ {{datumWsFormatted}}
From a53ca81784deea0b6b63e5f051cccf3486d24cff Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Thu, 13 Jul 2023 16:51:14 +0200 Subject: [PATCH 257/439] =?UTF-8?q?Wording=20=C3=84nderung=20bei=20Studier?= =?UTF-8?q?endenansicht=20Wiederholung?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- system/phrasesupdate.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 18a61f1d1..e3bee6643 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -18351,13 +18351,13 @@ array( 'phrases' => array( array( 'sprache' => 'German', - 'text' => 'Ich werde das Studienjahr nicht wiederholen', + 'text' => 'Ich werde das Studienjahr nicht wiederholen und Abbrechen', 'description' => '', 'insertvon' => 'system' ), array( 'sprache' => 'English', - 'text' => 'I will not repeat the academic year', + 'text' => 'I will not repeat the academic year and will drop out', 'description' => '', 'insertvon' => 'system' ) From a96d99bcd15f8f085675dd439a64cb867ca3aba3 Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Thu, 13 Jul 2023 16:51:54 +0200 Subject: [PATCH 258/439] Sammelmails: draft --- application/controllers/jobs/AntragJob.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index ca4f06690..61c3a2eaa 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -28,6 +28,18 @@ class AntragJob extends JOB_Controller $this->load->model('crm/Student_model', 'StudentModel'); } + /** + * Send infomail to Stgl + */ + public function sendStglSammelmail() + { + // TODO(chris): get all Abmeldung:Created, Unterbrechung:Created, Wiederholung:LvZugeordnet + // TODO(chris): get stgs for all these + // TODO(chris): get stgls for all these + // TODO(chris): sort antraege in stgls + // TODO(chris): send email + } + /** * Send reminder to Assistant for Wiedereinstieg Unterbrecher * From 68fbc13a691c6f791f72faa711f128d9682e2204 Mon Sep 17 00:00:00 2001 From: KarpAlex Date: Sat, 15 Jul 2023 19:57:51 +0200 Subject: [PATCH 259/439] added first version of uhstat1 form, added unique constraint for person_id in uhstat1daten table, added permissions for uhstat1daten sequence --- application/controllers/codex/UHSTAT1.php | 301 ++++++++++++++++++ application/models/codex/Abschluss_model.php | 28 ++ .../models/codex/Uhstat1daten_model.php | 14 + application/views/codex/uhstat1.php | 217 +++++++++++++ ...uhstat1_daten_ueber_das_bewerbungstool.php | 6 +- 5 files changed, 565 insertions(+), 1 deletion(-) create mode 100644 application/controllers/codex/UHSTAT1.php create mode 100644 application/models/codex/Abschluss_model.php create mode 100644 application/models/codex/Uhstat1daten_model.php create mode 100644 application/views/codex/uhstat1.php diff --git a/application/controllers/codex/UHSTAT1.php b/application/controllers/codex/UHSTAT1.php new file mode 100644 index 000000000..071368aae --- /dev/null +++ b/application/controllers/codex/UHSTAT1.php @@ -0,0 +1,301 @@ + 'admin:r', + 'saveUHSTAT1Data' => 'admin:rw' + ) + ); + + // load ci libs + $this->load->library('form_validation'); + + // load ci helpers + $this->load->helper(array('form', 'url')); + + // load models + $this->load->model('codex/Oehbeitrag_model', 'OehbeitragModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $this->load->model('system/Sprache_model', 'SpracheModel'); + $this->load->model('codex/Abschluss_model', 'AbschlussModel'); + $this->load->model('codex/Uhstat1daten_model', 'Uhstat1datenModel'); + + $this->loadPhrases( + array( + 'ui', + 'uhstat' + ) + ); + } + + public function index() + { + $formData = $this->_getFormData(); + + if (!hasData($formData)) show_error("No form data could be loaded"); + + $this->load->view("codex/uhstat1.php", array('formData' => getData($formData))); + } + + /** + * Add or update UHSTAT1 data + */ + public function saveUHSTAT1Data() + { + $person_id = $this->input->get('person_id'); + + if (!isset($person_id) || !is_numeric($person_id)) show_error("Person Id missing"); + + $this->form_validation->set_error_delimiters('', ''); + + // check required fields + $this->form_validation->set_rules('geburtsstaat', 'Geburtsstaat', 'required', array('required' => $this->p->t('uhstat', 'feldFehlt'))); + $this->form_validation->set_rules( + 'mutter_geburtsstaat', + 'Geburtsstaat Mutter', + 'required', + array('required' => $this->p->t('uhstat', 'feldFehlt')) + ); + $this->form_validation->set_rules( + 'mutter_bildungsstaat', + 'Bildungsstaat Mutter', + 'required', + array('required' => $this->p->t('uhstat', 'feldFehlt')) + ); + $this->form_validation->set_rules( + 'mutter_geburtsjahr', + 'Geburtsjahr Mutter', + 'required', + array('required' => $this->p->t('uhstat', 'feldFehlt')) + ); + $this->form_validation->set_rules( + 'mutter_bildungmax', + 'Höchste Ausbildung Mutter', + 'required|callback_bildungsstaat_bildungmax_check[m]', + array( + 'required' => $this->p->t('uhstat', 'feldFehlt'), + 'bildungsstaat_bildungmax_check' => $this->p->t('uhstat', 'ausbildungBildungsstaatUebereinstimmung') + //'Land der höchsten Ausbildung muss mit Bildungsstaat übereinstimmen' + // Bildungsstaat should correspond to state of bildung max + ) + ); + $this->form_validation->set_rules( + 'vater_geburtsstaat', + 'Geburtsstaat Vater', + 'required', + array('required' => $this->p->t('uhstat', 'feldFehlt')) + ); + $this->form_validation->set_rules( + 'vater_bildungsstaat', + 'Bildungsstaat Vater', + 'required', + array('required' => $this->p->t('uhstat', 'feldFehlt')) + ); + $this->form_validation->set_rules( + 'vater_geburtsjahr', + 'Geburtsjahr Vater', + 'required', + array('required' => $this->p->t('uhstat', 'feldFehlt')) + ); + $this->form_validation->set_rules( + 'vater_bildungmax', + 'Höchste Ausbildung Vater', + 'required|callback_bildungsstaat_bildungmax_check[v]', + array( + 'required' => $this->p->t('uhstat', 'feldFehlt'), + 'bildungsstaat_bildungmax_check' => $this->p->t('uhstat', 'ausbildungBildungsstaatUebereinstimmung') + ) + ); + + $uhstat1datenRes = null; + if ($this->form_validation->run()) // if valid + { + // get post fields + $geburtsstaat = $this->input->post('geburtsstaat'); + $mutter_geburtsstaat = $this->input->post('mutter_geburtsstaat'); + $mutter_geburtsjahr = $this->input->post('mutter_geburtsjahr'); + $mutter_bildungsstaat = $this->input->post('mutter_bildungsstaat'); + $mutter_bildungmax = $this->input->post('mutter_bildungmax'); + $vater_geburtsstaat = $this->input->post('vater_geburtsstaat'); + $vater_geburtsjahr = $this->input->post('vater_geburtsjahr'); + $vater_bildungsstaat = $this->input->post('vater_bildungsstaat'); + $vater_bildungmax = $this->input->post('vater_bildungmax'); + + $uhstat1datenloadRes = $this->Uhstat1datenModel->loadWhere(array('person_id' => $person_id)); + + if (hasData($uhstat1datenloadRes)) + { + $uhstat1datenRes = $this->Uhstat1datenModel->update( + array('person_id' => $person_id), + array( + 'geburtsstaat' => $geburtsstaat, + 'mutter_geburtsstaat' => $mutter_geburtsstaat, + 'mutter_geburtsjahr' => $mutter_geburtsjahr, + 'mutter_bildungsstaat' => $mutter_bildungsstaat, + 'mutter_bildungmax' => $mutter_bildungmax, + 'vater_geburtsstaat' => $vater_geburtsstaat, + 'vater_geburtsjahr' => $vater_geburtsjahr, + 'vater_bildungsstaat' => $vater_bildungsstaat, + 'vater_bildungmax' => $vater_bildungmax + ) + ); + } + else + { + $uhstat1datenRes = $this->Uhstat1datenModel->insert( + array( + 'geburtsstaat' => $geburtsstaat, + 'mutter_geburtsstaat' => $mutter_geburtsstaat, + 'mutter_geburtsjahr' => $mutter_geburtsjahr, + 'mutter_bildungsstaat' => $mutter_bildungsstaat, + 'mutter_bildungmax' => $mutter_bildungmax, + 'vater_geburtsstaat' => $vater_geburtsstaat, + 'vater_geburtsjahr' => $vater_geburtsjahr, + 'vater_bildungsstaat' => $vater_bildungsstaat, + 'vater_bildungmax' => $vater_bildungmax, + 'person_id' =>$person_id + ) + ); + } + } + + $formData = $this->_getFormData(); + + if (!hasData($formData)) show_error("No data found"); + + // pass success/error messages to view + $successMessage = isset($uhstat1datenRes) && isSuccess($uhstat1datenRes) ? $this->p->t('uhstat', 'erfolgreichGespeichert') : ''; + $errorMessage = isset($uhstat1datenRes) && isError($uhstat1datenRes) ? $this->p->t('uhstat', 'fehlerBeimSpeichern') : ''; + + // load view with form data + $this->load->view("codex/uhstat1.php", array( + 'formData' => getData($formData), + 'successMessage' => $successMessage, + 'errorMessage' => $errorMessage + )); + } + + /** + * Check callback for Bildungsstaat - if Bildungsstaat is Austria, a highest education should be in Austria. + * @param $bildungmax + * @param $bildungsstaat_typ - mother (m) or father (v) + * @return bool true if valid, false otherwise + */ + public function bildungsstaat_bildungmax_check($bildungmax, $bildungsstaat_typ) + { + // valid if no type passed + if (!isset($bildungsstaat_typ)) return true; + + // get correct input + if ($bildungsstaat_typ == 'm') // mutter + $bildungsstaat = $this->input->post('mutter_bildungsstaat'); + elseif ($bildungsstaat_typ == 'v') // vater + $bildungsstaat = $this->input->post('vater_bildungsstaat'); + else + return true; + + if (!isset($bildungsstaat)) return true; + + // find out if abschluss is in Austria + $this->AbschlussModel->addSelect("in_oesterreich"); + $abschlussRes = $this->AbschlussModel->load($bildungmax); + + if (hasData($abschlussRes)) + { + $in_oesterreich = getData($abschlussRes)[0]->in_oesterreich; + // invalid if abschluss in Austria, but not Bildungsstaat, or abschluss not in Austria, but Bildungsstaat in Austria + return ($in_oesterreich && $bildungsstaat == self::CODEX_OESTERREICH) || (!$in_oesterreich && $bildungsstaat != self::CODEX_OESTERREICH); + } + + return false; + } + + /** + * Gets initial data needed to display UHSTAT1 form. + */ + private function _getFormData() + { + $person_id = $this->input->get('person_id'); + + if (!isset($person_id) || !is_numeric($person_id)) return error("Person Id missing"); + + $formData = array( + 'nation' => array(), + 'abschluss_oesterreich' => array(), + 'abschluss_nicht_oesterreich' => array(), + 'jahre' => array(), + 'languageIdx' => $this->_getLanguageIndex(), + 'person_id' => $person_id + ); + + $nationTextFieldName = $formData['languageIdx'] == 1 ? 'langtext' : 'engltext'; + + // get nation list + $this->load->model('codex/Nation_model', 'NationModel'); + + $this->NationModel->addSelect("nation_code, $nationTextFieldName AS nation_text"); + $this->NationModel->addOrder("nation_text"); + $nationRes = $this->NationModel->load(); + + if (isError($nationRes)) return $nationRes; + + if (hasData($nationRes)) $formData['nation'] = getData($nationRes); + + // get abschluss list + $abschlussRes = $this->AbschlussModel->getActiveAbschluesse(); + + if (isError($abschlussRes)) return $abschlussRes; + + $abschlussData = getData($abschlussRes); + + if (hasData($abschlussRes)) + { + foreach (getData($abschlussRes) as $abschluss) + { + if ($abschluss->in_oesterreich === true) + $formData['abschluss_oesterreich'][] = $abschluss; + elseif ($abschluss->in_oesterreich === false) + $formData['abschluss_nicht_oesterreich'][] = $abschluss; + else + { + $formData['abschluss_oesterreich'][] = $abschluss; + $formData['abschluss_nicht_oesterreich'][] = $abschluss; + } + } + } + + // get realistic birth years, dated back from current year + $currYear = date("Y"); + $formData['jahre'] = range($currYear - self::UPPER_BOUNDARY_YEARS, $currYear - self::LOWER_BOUNDARY_YEARS); + + return success($formData); + } + + /** + * Gets language index of currently logged in user. + * @return int (the index, start at 1) + */ + private function _getLanguageIndex() + { + $idx = 1; + $this->SpracheModel->addSelect('index'); + $langRes = $this->SpracheModel->loadWhere(array('sprache' => getUserLanguage())); + + if (hasData($langRes)) + { + $idx = getData($langRes)[0]->index; + } + + return $idx; + } +} diff --git a/application/models/codex/Abschluss_model.php b/application/models/codex/Abschluss_model.php new file mode 100644 index 000000000..93b940ed2 --- /dev/null +++ b/application/models/codex/Abschluss_model.php @@ -0,0 +1,28 @@ +dbTable = 'bis.tbl_abschluss'; + $this->pk = 'ausbildung_code'; + } + + public function getActiveAbschluesse() + { + return $this->execQuery( + ' + SELECT + ausbildung_code, bezeichnung, in_oesterreich + FROM + bis.tbl_abschluss + WHERE + aktiv + ORDER BY CASE WHEN in_oesterreich THEN 0 ELSE 1 END, ausbildung_code' + ); + } +} diff --git a/application/models/codex/Uhstat1daten_model.php b/application/models/codex/Uhstat1daten_model.php new file mode 100644 index 000000000..9bca44b58 --- /dev/null +++ b/application/models/codex/Uhstat1daten_model.php @@ -0,0 +1,14 @@ +dbTable = 'bis.tbl_uhstat1daten'; + $this->pk = 'uhstat1daten_id'; + } +} diff --git a/application/views/codex/uhstat1.php b/application/views/codex/uhstat1.php new file mode 100644 index 000000000..48397a387 --- /dev/null +++ b/application/views/codex/uhstat1.php @@ -0,0 +1,217 @@ +load->view( + 'templates/FHC-Header', + array( + 'title' => 'UHSTAT1Formular', + 'jquery3' => true, + 'bootstrap3' => true, + 'fontawesome4' => true, + 'dialoglib' => true, + 'phrases' => array( + 'ui' => array('speichern') + ) + ) +); +?> + +
+
+

+ p->t('uhstat', 'uhstat1AnmeldungUeberschrift') ?> +

+ +
+ p->t('uhstat', 'persoenlicheAngaben') ?> +
+ +
+ + +
+
+
+
+ p->t('uhstat', 'angabenErziehungsberechtigte') ?> +

p->t('uhstat', 'erziehungsberechtigtePersonEins') ?>

+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+

p->t('uhstat', 'erziehungsberechtigtePersonZwei') ?>

+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ + + + + + + +
+ +
+ +
+ +load->view('templates/FHC-Footer'); ?> diff --git a/system/dbupdate_3.4/29835_uhstat1_erfassung_der_uhstat1_daten_ueber_das_bewerbungstool.php b/system/dbupdate_3.4/29835_uhstat1_erfassung_der_uhstat1_daten_ueber_das_bewerbungstool.php index 7395ac0bc..bbd168073 100644 --- a/system/dbupdate_3.4/29835_uhstat1_erfassung_der_uhstat1_daten_ueber_das_bewerbungstool.php +++ b/system/dbupdate_3.4/29835_uhstat1_erfassung_der_uhstat1_daten_ueber_das_bewerbungstool.php @@ -12,7 +12,7 @@ if (!$result = @$db->db_query('SELECT 1 FROM bis.tbl_abschluss LIMIT 1')) bezeichnung character varying(128)[], aktiv boolean NOT NULL DEFAULT true, in_oesterreich boolean, - CONSTRAINT tbl_abschluss_pk PRIMARY KEY (ausbildung_code) + CONSTRAINT pk_tbl_abschluss PRIMARY KEY (ausbildung_code) ); COMMENT ON TABLE bis.tbl_abschluss IS 'Key-Table of graduation'; @@ -102,6 +102,8 @@ if (!$result = @$db->db_query('SELECT 1 FROM bis.tbl_uhstat1daten LIMIT 1')) REFERENCES public.tbl_person (person_id) MATCH SIMPLE ON DELETE RESTRICT ON UPDATE CASCADE; + ALTER TABLE bis.tbl_uhstat1daten ADD CONSTRAINT uk_uhstat1daten_person_id UNIQUE(person_id); + COMMENT ON TABLE bis.tbl_uhstat1daten IS 'UHSTAT1 data for a person (statistical data)'; COMMENT ON COLUMN bis.tbl_uhstat1daten.geburtsstaat IS 'Birthplace of person'; COMMENT ON COLUMN bis.tbl_uhstat1daten.mutter_geburtsstaat IS 'Birth country of mother of person'; @@ -115,6 +117,8 @@ if (!$result = @$db->db_query('SELECT 1 FROM bis.tbl_uhstat1daten LIMIT 1')) GRANT SELECT, UPDATE, INSERT, DELETE ON bis.tbl_uhstat1daten TO web; GRANT SELECT, UPDATE, INSERT, DELETE ON bis.tbl_uhstat1daten TO vilesci; + GRANT SELECT, UPDATE ON bis.tbl_uhstat1daten_uhstat1daten_id_seq TO vilesci; + GRANT SELECT, UPDATE ON bis.tbl_uhstat1daten_uhstat1daten_id_seq TO web; "; if(!$db->db_query($qry)) From 5f096b58b7739e43eecb2dfeff84c9ed22d9088f Mon Sep 17 00:00:00 2001 From: ma0048 Date: Mon, 17 Jul 2023 13:52:06 +0200 Subject: [PATCH 260/439] - STG beim nicht vorhanden Master RT anzeigen --- include/reihungstest.class.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/reihungstest.class.php b/include/reihungstest.class.php index 633ddf1da..8cc9495fd 100644 --- a/include/reihungstest.class.php +++ b/include/reihungstest.class.php @@ -688,8 +688,8 @@ class reihungstest extends basis_db tbl_reihungstest.aufnahmegruppe_kurzbz, tbl_studiengang.typ, UPPER(typ::varchar(1) || kurzbz) AS stg_kuerzel, - so.studiengangbezeichnung as bezeichnung, - so.studiengangbezeichnung_englisch as english + so.studiengangbezeichnung, + so.studiengangbezeichnung_englisch FROM public.tbl_rt_person JOIN public.tbl_reihungstest ON (rt_id=reihungstest_id) @@ -736,8 +736,8 @@ class reihungstest extends basis_db $obj->aufnahmegruppe_kurzbz = $row->aufnahmegruppe_kurzbz; $obj->typ = $row->typ; $obj->stg_kuerzel = $row->stg_kuerzel; - $obj->bezeichnung = $row->bezeichnung; - $obj->english = $row->english; + $obj->studiengangbezeichnung = $row->studiengangbezeichnung; + $obj->studiengangbezeichnung_englisch = $row->studiengangbezeichnung_englisch; $this->result[] = $obj; } From 5e6262da56208a7d300078ea051d026e1a05aca6 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Mon, 17 Jul 2023 16:29:03 +0200 Subject: [PATCH 261/439] =?UTF-8?q?Config=20f=C3=BCr=20Datum=20Start=20Dig?= =?UTF-8?q?italisierung,=20finish=20handleWiederholerDeadline,=20start=20S?= =?UTF-8?q?ammelmail=20an=20Stgl?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/config/studierendenantrag.php | 11 ++ application/controllers/jobs/AntragJob.php | 156 ++++++++++++---- .../models/education/Pruefung_model.php | 172 ++++++++---------- 3 files changed, 210 insertions(+), 129 deletions(-) diff --git a/application/config/studierendenantrag.php b/application/config/studierendenantrag.php index 85a3e1658..89b066d33 100644 --- a/application/config/studierendenantrag.php +++ b/application/config/studierendenantrag.php @@ -88,6 +88,17 @@ $config['wiederholung_job_request_2_date_modifier'] = '+3 weeks'; */ $config['wiederholung_job_deadline_date_modifier'] = '+1 month'; +/** + * before this exam dates for Wiederholer will be ignored + * + * @var string A string formated as Date + * + */ +$config['digitalization_start'] = '2022-07-01'; + + + + /** * Objection period - the student will be abgemeldet if he hasn't objected in this period * diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index 61c3a2eaa..e0c88ac3a 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -3,11 +3,12 @@ if (!defined("BASEPATH")) exit("No direct script access allowed"); use \DateTime as DateTime; -// TODO(chris): Achtung not working class AntragJob extends JOB_Controller { - /** + private $allPrestudentsWhereCommitteeExamFailed; + + /** * API constructor */ public function __construct() @@ -33,11 +34,102 @@ class AntragJob extends JOB_Controller */ public function sendStglSammelmail() { - // TODO(chris): get all Abmeldung:Created, Unterbrechung:Created, Wiederholung:LvZugeordnet - // TODO(chris): get stgs for all these - // TODO(chris): get stgls for all these - // TODO(chris): sort antraege in stgls - // TODO(chris): send email + $this->logInfo('Start Job sendStglSammelmail'); + + // TODO(chris): get all Abmeldung:Created, Unterbrechung:Created, Wiederholung:LvZugeordnet + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + + $this->StudierendenantragModel->addJoin('public.tbl_prestudent','prestudent_id'); + $this->db->group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_ABMELDUNG); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); + $this->db->group_end(); + + $this->db->or_group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_ABMELDUNG_STGL); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); + $this->db->group_end(); + + $this->db->or_group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_UNTERBRECHUNG); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); + $this->db->group_end(); + + $this->db->or_group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_WIEDERHOLUNG); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_LVSASSIGNED); + $this->db->group_end(); + + $result = $this->StudierendenantragModel->load(); + if(isError($result)) + return $this->logError(getError($result)); + + if(!hasData($result)) + return $this->logInfo('End Job sendStglSammelmail: 0 Mails sent'); + + $antraege = getData($result); + + $stgs = array(); + $stgLeitungen = array(); + + foreach($antraege as $antrag) + { + if(!isset($stgs[$antrag->studiengang_kz])) + { + $result = $this->StudiengangModel->getLeitung($antrag->studiengang_kz); + if(isError($result)) + { + $this->logError(getError($result)); + continue; + } + if(!hasData($result)) + { + $this->logError('Keine Leitung für Studiengang ' . $antrag->studiengang_kz . ' gefunden!'); + continue; + } + + $leitung = current(getData($result)); + if(!isset($stgLeitungen[$leitung->uid])) + { + $stgLeitungen[$leitung->uid] = [ 'Details' => $leitung, 'stgs' => [] ]; + } + $stgLeitungen[$leitung->uid] ['stgs'][] = $antrag->studiengang_kz; + + $result = $this->StudiengangModel->load($antrag->studiengang_kz); + if(isError($result)) + { + $this->logError(getError($result)); + continue; + } + if(!hasData($result)) + { + $this->logError('Keine Details für Studiengang ' . $antrag->studiengang_kz . ' gefunden!'); + continue; + } + $details = current(getData($result)); + + $stgs[$antrag->studiengang_kz] = [ 'Abmeldung' => [], 'Unterbrechung' => [], 'Wiederholung' => [], 'Details' => $details ]; + } + $stgs[$antrag->studiengang_kz] [$antrag->typ] = $antrag; + } + +/* var_dump($stgs); + var_dump($stgLeitungen);*/ + + $count = 0; + foreach($stgLeitungen as $leitung) + { + $data = array(); + if(sendSanchoMail("Sancho_Mail_Antrag_Stgl",$data,$leitung['Details']->email, 'Anträge - Aktion(en) erforderlich')) + $count++; + } + + $this->logInfo($count . " Emails erfolgreich versandt"); + + // TODO(chris): Emailadresse stg + // TODO(chris): data Fertig + + $this->logInfo('End Job sendStglSammelmail'); } /** @@ -118,19 +210,22 @@ class AntragJob extends JOB_Controller return; } + $digi_start= $this->config->item('digitalization_start'); + if($digi_start) + $digi_start = new DateTime($digi_start); + $dateDeadline = new DateTime(); $dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline)); - $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed( - [ - null, - Studierendenantragstatus_model::STATUS_REQUESTSENT_1, - Studierendenantragstatus_model::STATUS_REQUESTSENT_2 - ], - $dateDeadline, - null - ); - + $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed( + [ + null, + Studierendenantragstatus_model::STATUS_REQUESTSENT_1, + Studierendenantragstatus_model::STATUS_REQUESTSENT_2 + ], + $dateDeadline, + $digi_start + ); if(isError($result)) { $this->logError(getError($result)); @@ -142,24 +237,19 @@ class AntragJob extends JOB_Controller $prestudents = $this->prestudentsGetUnique($prestudents); - foreach ($prestudents as $prestudent) - { - // TODO(chris): DEBUG REMOVE! - if ($prestudent->studiensemester_kurzbz == 'WS2021') - var_dump([$prestudent->prestudent_id, $prestudent->studiensemester_kurzbz, $prestudent->lvbezeichnung]); - $result = success(); - // TODO(chris): find out how to filter old/wrong datasets!!! - #$result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz, $insertvon); - if (isError($result)) - $this->logError(getError($result)); - else - $count++; - } - $this->logInfo($count . " Students set to Abbrecher"); - } - $this->logInfo('Ende Job handleWiederholerDeadline'); + foreach ($prestudents as $prestudent) + { + $result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz, $insertvon); + if (isError($result)) + $this->logError(getError($result)); + else + $count++; + } + $this->logInfo($count . " Students set to Abbrecher"); + } + $this->logInfo('Ende Job handleWiederholerDeadline'); } /** diff --git a/application/models/education/Pruefung_model.php b/application/models/education/Pruefung_model.php index 4236a5c6a..047cac02f 100644 --- a/application/models/education/Pruefung_model.php +++ b/application/models/education/Pruefung_model.php @@ -37,106 +37,52 @@ class Pruefung_model extends DB_Model return $this->execQuery($qry, array($person_id, $studiensemester_kurzbz)); } - /** - * @param integer $prestudent_id student_uid - * - * @return stdClass - */ - public function loadWhereCommitteeExamFailedForPrestudent($prestudent_id) - { - $this->load->config('studierendenantrag'); - $this->dbTable = 'lehre.tbl_pruefung p'; + /** + * @return string + */ + protected function loadWhereThreeExamsFailed() + { + $this->load->config('studierendenantrag'); - $this->addSelect('p.datum'); - $this->addSelect('pers.vorname'); - $this->addSelect('pers.nachname'); - $this->addSelect('s.matrikelnr'); - $this->addSelect('g.bezeichnung'); - $this->addSelect('g.studiengang_kz'); - $this->addSelect('o.bezeichnung_mehrsprachig'); - $this->addSelect('ps.prestudent_id'); - $this->addSelect('lv.bezeichnung as lvbezeichnung'); - $this->addSelect('le.studiensemester_kurzbz'); - $this->addSelect('a.typ'); - $this->addSelect('campus.get_status_studierendenantrag(a.studierendenantrag_id) status'); + $this->dbTable = 'lehre.tbl_pruefung p'; - $this->addJoin('lehre.tbl_note n', 'note'); - $this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id'); - $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); - $this->addJoin('public.tbl_student s', 'student_uid'); - $this->addJoin('public.tbl_prestudent ps', 'prestudent_id'); - $this->addJoin('public.tbl_person pers', 'person_id'); - $this->addJoin('public.tbl_studiengang g', 'ps.studiengang_kz=g.studiengang_kz'); - $this->addJoin('bis.tbl_orgform o', 'g.orgform_kurzbz=o.orgform_kurzbz'); - $this->addJoin('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id', 'LEFT'); + $sprache_index = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; - $this->db->where("n.positiv", false); - $this->db->where("p.pruefungstyp_kurzbz", 'kommPruef'); - $this->db->where("ps.prestudent_id", $prestudent_id); - $this->db->where_in("get_rolle_prestudent(ps.prestudent_id, NULL)", $this->config->item('antrag_prestudentstatus_whitelist')); - $this->db->where("g.aktiv", true); + $this->addSelect('max(p.datum) as datum'); + $this->addSelect('pers.vorname'); + $this->addSelect('pers.nachname'); + $this->addSelect('pers.person_id'); + $this->addSelect('s.matrikelnr'); + $this->addSelect('g.bezeichnung'); + $this->addSelect('g.studiengang_kz'); + $this->addSelect('o.bezeichnung_mehrsprachig[(' . $sprache_index . ')] AS orgform', false); + $this->addSelect('ps.prestudent_id'); + $this->addSelect('lv.bezeichnung as lvbezeichnung'); + $this->addSelect('le.studiensemester_kurzbz'); + $this->addSelect('a.typ'); + $this->addSelect('campus.get_status_studierendenantrag(a.studierendenantrag_id) status'); + $this->addSelect('count(1) as count'); - $this->db->where('lv.studiengang_kz not in( - SELECT ps.studiengang_kz - FROM - public.tbl_student s - JOIN public.tbl_prestudent ps USING (prestudent_id) - JOIN public.tbl_prestudentstatus pss USING (prestudent_id) - WHERE pss.statusgrund_id in ? - and ps.prestudent_id = ?)', null, false); + $this->addGroupBy(['pers.vorname','pers.nachname','pers.person_id', 's.matrikelnr','g.bezeichnung', 'g.studiengang_kz','o.bezeichnung_mehrsprachig','ps.prestudent_id', 'lv.bezeichnung', 'le.studiensemester_kurzbz', 'a.typ', 'a.studierendenantrag_id']); + $this->addJoin('lehre.tbl_note n', 'note'); + $this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id'); + $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); + $this->addJoin('public.tbl_student s', 'student_uid'); + $this->addJoin('public.tbl_prestudent ps', 'prestudent_id'); + $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('bis.tbl_orgform o', 'g.orgform_kurzbz=o.orgform_kurzbz'); + $this->db->join('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ = ?', 'LEFT', false); - $sql = $this->db->get_compiled_select($this->dbTable); + $this->db->where("n.positiv", false); + /* $this->db->where_in("p.pruefungstyp_kurzbz1", ['kommPruef','zusKommPruef']);*/ + $this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist')); - return $this->execQuery($sql, [$this->config->item('status_gruende_wiederholer'), $prestudent_id]); - } + $this->db->where("g.aktiv", true); - public function getAllPrestudentsWhereCommitteeExamFailed($status, $maxDate, $minDate) - { - $this->load->config('studierendenantrag'); - $this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); - - $this->dbTable = 'lehre.tbl_pruefung p'; - - $sprache_index = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1"; - - $this->addSelect('p.datum'); - $this->addSelect('pers.vorname'); - $this->addSelect('pers.nachname'); - $this->addSelect('pers.person_id'); - $this->addSelect('s.matrikelnr'); - $this->addSelect('g.bezeichnung'); - $this->addSelect('g.studiengang_kz'); - $this->addSelect('o.bezeichnung_mehrsprachig[(' . $sprache_index . ')] AS orgform', false); - $this->addSelect('ps.prestudent_id'); - $this->addSelect('lv.bezeichnung as lvbezeichnung'); - $this->addSelect('le.studiensemester_kurzbz'); - $this->addSelect('a.typ'); - $this->addSelect('campus.get_status_studierendenantrag(a.studierendenantrag_id) status'); - - $this->addJoin('lehre.tbl_note n', 'note'); - $this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id'); - $this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id'); - $this->addJoin('public.tbl_student s', 'student_uid'); - $this->addJoin('public.tbl_prestudent ps', 'prestudent_id'); - $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('bis.tbl_orgform o', 'g.orgform_kurzbz=o.orgform_kurzbz'); - $this->db->join('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ = ?', 'LEFT', false); - - $this->db->where("n.positiv", false); - $this->db->where("p.pruefungstyp_kurzbz", 'kommPruef'); - $this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist')); - - if ($maxDate) - $this->db->where("p.datum < ", $maxDate->format('c')); - if ($minDate) - $this->db->where("p.datum > ", $minDate->format('c')); - $this->db->where("g.aktiv", true); - $this->db->where("b.aktiv", true); - - $this->db->where('lv.studiengang_kz not in( + $this->db->where('lv.studiengang_kz not in( SELECT ps.studiengang_kz FROM public.tbl_prestudent ps1 @@ -144,8 +90,42 @@ class Pruefung_model extends DB_Model WHERE pss.statusgrund_id in ? AND ps.prestudent_id = ps1.prestudent_id)', null, false); - // NOTE(chris): is Wiederholer without set statusgrund (legacy?) - $this->db->where('(SELECT COUNT(*) FROM (SELECT DISTINCT studiensemester_kurzbz FROM tbl_prestudentstatus _s WHERE ausbildungssemester=get_absem_prestudent(ps.prestudent_id, le.studiensemester_kurzbz) AND prestudent_id=ps.prestudent_id) a) = 1', null, false); + // NOTE(chris): is Wiederholer without set statusgrund (legacy?) + $this->db->where('(SELECT COUNT(*) FROM (SELECT DISTINCT studiensemester_kurzbz FROM tbl_prestudentstatus _s WHERE ausbildungssemester=get_absem_prestudent(ps.prestudent_id, le.studiensemester_kurzbz) AND prestudent_id=ps.prestudent_id) a) = 1', null, false); + + return $this->db->get_compiled_select($this->dbTable); + } + + + + + /** + * @param integer $prestudent_id student_uid + * + * @return stdClass + */ + public function loadWhereCommitteeExamFailedForPrestudent($prestudent_id) + { + + $sql = $this->loadWhereThreeExamsFailed(); + + $statusgruende = $this->config->item('status_gruende_wiederholer'); + if (!is_array($statusgruende)) + $statusgruende = []; + + return $this->execQuery('select * from ( ' . $sql . ') temp where count >= 3 AND prestudent_id = ?' , [Studierendenantrag_model::TYP_WIEDERHOLUNG, $statusgruende, $prestudent_id]); + } + + public function getAllPrestudentsWhereCommitteeExamFailed($status, $maxDate, $minDate) + { + $this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); + + if ($maxDate) + $this->db->where("p.datum < ", $maxDate->format('c')); + if ($minDate) + $this->db->where("p.datum > ", $minDate->format('c')); + + $this->db->where("b.aktiv", true); if (is_array($status)) { if (in_array(null, $status)) { @@ -165,12 +145,12 @@ class Pruefung_model extends DB_Model $this->db->where('campus.get_status_studierendenantrag(a.studierendenantrag_id)', $status); } - $sql = $this->db->get_compiled_select($this->dbTable); + $sql = $this->loadWhereThreeExamsFailed(); $statusgruende = $this->config->item('status_gruende_wiederholer'); if (!is_array($statusgruende)) $statusgruende = []; - return $this->execQuery($sql, [Studierendenantrag_model::TYP_WIEDERHOLUNG, $statusgruende]); + return $this->execQuery('select * from ( ' . $sql . ') temp where count >= 3', [Studierendenantrag_model::TYP_WIEDERHOLUNG, $statusgruende]); } } From 8bb3b6d53c4b0ff03759acab4d30d94236895a60 Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 20 Jul 2023 10:48:03 +0200 Subject: [PATCH 262/439] DB Update: added 2 attributes to tbl_anrechnung - begruendung_ects (text) - begruendung_lvinhalt (text) --- system/dbupdate_3.4.php | 3 +- ...chnung_neue_attribute_fuer_begruendung.php | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 system/dbupdate_3.4/30181_tabelle_anrechnung_neue_attribute_fuer_begruendung.php diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index ed60aeddf..5c6a3d5d1 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -40,6 +40,7 @@ require_once('dbupdate_3.4/24913_tabelle_raumtyp_neues_attribut_aktiv.php'); require_once('dbupdate_3.4/28089_plausichecks_in_extension_hinzufuegen.php'); require_once('dbupdate_3.4/29133_einzelne_studiengaenge_aus_issuechecks_ausnehmen.php'); require_once('dbupdate_3.4/30537_anmerkung_in_tbl_rolleberechtigung.php'); +require_once('dbupdate_3.4/30181_tabelle_anrechnung_neue_attribute_fuer_begruendung.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; @@ -150,7 +151,7 @@ $tabellen=array( "lehre.tbl_abschlusspruefung" => array("abschlusspruefung_id","student_uid","vorsitz","pruefer1","pruefer2","pruefer3","abschlussbeurteilung_kurzbz","akadgrad_id","pruefungstyp_kurzbz","datum","uhrzeit","sponsion","anmerkung","updateamum","updatevon","insertamum","insertvon","ext_id","note","protokoll","endezeit","pruefungsantritt_kurzbz","freigabedatum"), "lehre.tbl_abschlusspruefung_antritt" => array("pruefungsantritt_kurzbz","bezeichnung","bezeichnung_english","sort"), "lehre.tbl_akadgrad" => array("akadgrad_id","akadgrad_kurzbz","studiengang_kz","titel","geschlecht"), - "lehre.tbl_anrechnung" => array("anrechnung_id","prestudent_id","lehrveranstaltung_id","begruendung_id","lehrveranstaltung_id_kompatibel","genehmigt_von","insertamum","insertvon","updateamum","updatevon","ext_id", "dms_id", "studiensemester_kurzbz", "anmerkung_student", "empfehlung_anrechnung"), + "lehre.tbl_anrechnung" => array("anrechnung_id","prestudent_id","lehrveranstaltung_id","begruendung_id","lehrveranstaltung_id_kompatibel","genehmigt_von","insertamum","insertvon","updateamum","updatevon","ext_id", "dms_id", "studiensemester_kurzbz", "anmerkung_student", "empfehlung_anrechnung", "begruendung_ects", "begruendung_lvinhalt"), "lehre.tbl_anrechnungstatus" => array("status_kurzbz", "bezeichnung_mehrsprachig"), "lehre.tbl_anrechnung_anrechnungstatus" => array("anrechnungstatus_id", "anrechnung_id", "status_kurzbz", "datum", "insertamum", "insertvon"), "lehre.tbl_anrechnung_begruendung" => array("begruendung_id","bezeichnung"), diff --git a/system/dbupdate_3.4/30181_tabelle_anrechnung_neue_attribute_fuer_begruendung.php b/system/dbupdate_3.4/30181_tabelle_anrechnung_neue_attribute_fuer_begruendung.php new file mode 100644 index 000000000..922920071 --- /dev/null +++ b/system/dbupdate_3.4/30181_tabelle_anrechnung_neue_attribute_fuer_begruendung.php @@ -0,0 +1,28 @@ +db_query("SELECT begruendung_ects FROM lehre.tbl_anrechnung LIMIT 1")) +{ + $qry = "ALTER TABLE lehre.tbl_anrechnung ADD COLUMN begruendung_ects text; + COMMENT ON COLUMN lehre.tbl_anrechnung.begruendung_ects IS 'Begruendung gleichwertiger ECTS'; + "; + + if(!$db->db_query($qry)) + echo 'lehre.tbl_anrechnung '.$db->db_last_error().'
'; + else + echo '
Spalte begruendung_ects zu Tabelle lehre.tbl_anrechnung hinzugefügt'; +} + +//Add column begruendung_lvinhalt to lehre.tbl_anrechnung +if(!@$db->db_query("SELECT begruendung_lvinhalt FROM lehre.tbl_anrechnung LIMIT 1")) +{ + $qry = "ALTER TABLE lehre.tbl_anrechnung ADD COLUMN begruendung_lvinhalt text; + COMMENT ON COLUMN lehre.tbl_anrechnung.begruendung_lvinhalt IS 'Begruendung gleichwertiger LV-Inhalte'; + "; + + if(!$db->db_query($qry)) + echo 'lehre.tbl_anrechnung '.$db->db_last_error().'
'; + else + echo '
Spalte begruendung_lvinhalt zu Tabelle lehre.tbl_anrechnung hinzugefügt'; +} \ No newline at end of file From 54d819e1eaf1dc8d96b5f2ccfb22307d36b7c67b Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 20 Jul 2023 13:38:52 +0200 Subject: [PATCH 263/439] Adapted GUI to display and save begruendung_ects and begruendung_lvinhalt --- .../lehre/anrechnung/requestAnrechnung.php | 49 +++++++++++++++++-- .../js/lehre/anrechnung/requestAnrechnung.js | 25 ++++++++-- 2 files changed, 66 insertions(+), 8 deletions(-) diff --git a/application/views/lehre/anrechnung/requestAnrechnung.php b/application/views/lehre/anrechnung/requestAnrechnung.php index cfd9058f5..839e659a8 100644 --- a/application/views/lehre/anrechnung/requestAnrechnung.php +++ b/application/views/lehre/anrechnung/requestAnrechnung.php @@ -1,5 +1,7 @@ load->view( 'templates/FHC-Header', @@ -197,6 +199,47 @@ $this->load->view(
+ +
+
+
+
+ p->t('anrechnung', 'begruendungEcts'); ?>  + + + + ECTS Berechnung Referenzbeispiele +
+
+ + p->t('ui', 'maxZeichen'); ?> : +
+
+
+
+ +
+
+
+
+ p->t('anrechnung', 'begruendungLvinhalt'); ?>  + + + +
+
+ +  / p->t('ui', 'maxZeichen'); ?> : + p->t('ui', 'fehlendeMinZeichen'); ?> : +
+
+
+
@@ -242,8 +285,8 @@ $this->load->view(
- p->t('ui', 'maxZeichen'); ?> : + maxlength="" required>anmerkung; ?> + p->t('ui', 'maxZeichen'); ?> :
diff --git a/public/js/lehre/anrechnung/requestAnrechnung.js b/public/js/lehre/anrechnung/requestAnrechnung.js index 5edb4e162..01453f52d 100644 --- a/public/js/lehre/anrechnung/requestAnrechnung.js +++ b/public/js/lehre/anrechnung/requestAnrechnung.js @@ -1,6 +1,8 @@ const ANRECHNUNGSTATUS_APPROVED = 'approved'; const ANRECHNUNGSTATUS_REJECTED = 'rejected'; -const HERKUNFT_DER_KENNTNISSE_MAX_LENGTH = 125; +const CHAR_LENGTH125 = 125; +const CHAR_LENGTH500 = 500; +const CHAR_LENGTH1500 = 1500; const COLOR_DANGER = '#f2dede'; @@ -25,7 +27,7 @@ $(function(){ // Alert message inside Begruendungsbox, if maximum ECTS exceeded requestAnrechnung.alertIfMaxEctsExceededInsideBegruendungsbox(); - // Set chars counter for textarea 'Herkunft der Kenntnisse' + // Set chars counter for textareas requestAnrechnung.setCharsCounter(); // If Sperregrund exists: display Sperre panel, hide Status panel and disable all form elements @@ -98,6 +100,8 @@ $(function(){ begruendung: this.begruendung.value, lv_id: this.lv_id.value, studiensemester: this.studiensemester.value, + begruendung_ects: this.begruendung_ects.value, + begruendung_lvinhalt: this.begruendung_lvinhalt.value, bestaetigung: this.bestaetigung.value, uploadfile: this.uploadfile.files }, @@ -207,11 +211,22 @@ var requestAnrechnung = { }, setCharsCounter: function(){ $('#requestAnrechnung-herkunftDerKenntnisse').keyup(function() { - - let length = HERKUNFT_DER_KENNTNISSE_MAX_LENGTH - $(this).val().length; - + let length = CHAR_LENGTH125 - $(this).val().length; $('#requestAnrechnung-herkunftDerKenntnisse-charCounter').text(length); }); + + $('#requestAnrechnung-begruendungEcts').keyup(function() { + let length = CHAR_LENGTH125 - $(this).val().length; + $('#requestAnrechnung-begruendungEcts-charCounter').text(length); + }); + + $('#requestAnrechnung-begruendungLvinhalt').keyup(function() { + let maxlength = CHAR_LENGTH1500 - $(this).val().length; + $('#requestAnrechnung-begruendungLvinhalt-charCounterMax').text(maxlength); + + let minlength = CHAR_LENGTH500 - $(this).val().length; + $('#requestAnrechnung-begruendungLvinhalt-charCounterMin').text(minlength); + }); }, formatAnrechnungIsApplied: function (antragdatum, dms_id, filename){ $('#requestAnrechnung-antragdatum').text(antragdatum); From 110d6bace3637d2783f83be301ac86991b3d83b2 Mon Sep 17 00:00:00 2001 From: Cris Date: Thu, 20 Jul 2023 13:42:53 +0200 Subject: [PATCH 264/439] Adapted backend logic to save/retrieve begruendung_ects and begruendung_lvinhalt --- .../controllers/lehre/anrechnung/RequestAnrechnung.php | 10 ++++++++-- application/libraries/AnrechnungLib.php | 4 ++++ application/models/education/Anrechnung_model.php | 4 +++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/application/controllers/lehre/anrechnung/RequestAnrechnung.php b/application/controllers/lehre/anrechnung/RequestAnrechnung.php index e9059720b..1922bacda 100644 --- a/application/controllers/lehre/anrechnung/RequestAnrechnung.php +++ b/application/controllers/lehre/anrechnung/RequestAnrechnung.php @@ -111,6 +111,8 @@ class requestAnrechnung extends Auth_Controller $lehrveranstaltung_id = $this->input->post('lv_id'); $studiensemester_kurzbz = $this->input->post('studiensemester'); $bestaetigung = $this->input->post('bestaetigung'); + $begruendung_ects = $this->input->post('begruendung_ects'); + $begruendung_lvinhalt = $this->input->post('begruendung_lvinhalt'); // Validate data if (empty($_FILES['uploadfile']['name'])) @@ -121,7 +123,9 @@ class requestAnrechnung extends Auth_Controller if (isEmptyString($begruendung_id) || isEmptyString($anmerkung) || isEmptyString($lehrveranstaltung_id) || - isEmptyString($studiensemester_kurzbz)) + isEmptyString($studiensemester_kurzbz) || + isEmptyString($begruendung_ects) || + isEmptyString($begruendung_lvinhalt)) { return $this->outputJsonError($this->p->t('ui', 'errorFelderFehlen')); } @@ -172,7 +176,9 @@ class requestAnrechnung extends Auth_Controller $lehrveranstaltung_id, $begruendung_id, $lastInsert_dms_id, - $anmerkung + $anmerkung, + $begruendung_ects, + $begruendung_lvinhalt ); if (isError($result)) diff --git a/application/libraries/AnrechnungLib.php b/application/libraries/AnrechnungLib.php index d8c4b1fd3..8ee1891b5 100644 --- a/application/libraries/AnrechnungLib.php +++ b/application/libraries/AnrechnungLib.php @@ -174,6 +174,8 @@ class AnrechnungLib $anrechnung_data->insertvon = ''; $anrechnung_data->studiensemester_kurzbz = ''; $anrechnung_data->empfehlung = ''; + $anrechnung_data->begruendung_ects = ''; + $anrechnung_data->begruendung_lvinhalt = ''; $anrechnung_data->status_kurzbz = ''; $anrechnung_data->status = getUserLanguage() == 'German' ? 'neu' : 'new'; $anrechnung_data->dokumentname = ''; @@ -894,6 +896,8 @@ class AnrechnungLib $anrechnung_data->insertvon= $anrechnung->insertvon; $anrechnung_data->studiensemester_kurzbz= $anrechnung->studiensemester_kurzbz; $anrechnung_data->empfehlung= $anrechnung->empfehlung_anrechnung; + $anrechnung_data->begruendung_ects = $anrechnung->begruendung_ects; + $anrechnung_data->begruendung_lvinhalt = $anrechnung->begruendung_lvinhalt; // Get last status_kurzbz $result = $this->ci->AnrechnungModel->getLastAnrechnungstatus($anrechnung->anrechnung_id); diff --git a/application/models/education/Anrechnung_model.php b/application/models/education/Anrechnung_model.php index ebecf4118..cbfdb6607 100644 --- a/application/models/education/Anrechnung_model.php +++ b/application/models/education/Anrechnung_model.php @@ -30,7 +30,7 @@ class Anrechnung_model extends DB_Model */ public function createAnrechnungsantrag( $prestudent_id, $studiensemester_kurzbz, $lehrveranstaltung_id, - $begruendung_id, $dms_id, $anmerkung_student = null + $begruendung_id, $dms_id, $anmerkung_student = null, $begruendung_ects = null, $begruendung_lvinhalt = null ) { // Start DB transaction @@ -44,6 +44,8 @@ class Anrechnung_model extends DB_Model 'dms_id' => $dms_id, 'studiensemester_kurzbz' => $studiensemester_kurzbz, 'anmerkung_student' => $anmerkung_student, + 'begruendung_ects' => $begruendung_ects, + 'begruendung_lvinhalt' => $begruendung_lvinhalt, 'insertvon' => $this->_uid )); From 35d01b042eaaa97aa769554c6a35e37672434cda Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Thu, 20 Jul 2023 15:00:42 +0200 Subject: [PATCH 265/439] Bug canCancel in abmeldung->edit missing --- application/controllers/components/Antrag/Abmeldung.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/application/controllers/components/Antrag/Abmeldung.php b/application/controllers/components/Antrag/Abmeldung.php index 55435c1f6..c55820437 100644 --- a/application/controllers/components/Antrag/Abmeldung.php +++ b/application/controllers/components/Antrag/Abmeldung.php @@ -94,6 +94,11 @@ class Abmeldung extends FHC_Controller if ($data->typ !== Studierendenantrag_model::TYP_ABMELDUNG_STGL && $data->typ !== Studierendenantrag_model::TYP_ABMELDUNG) return show_404(); + $data->canCancel = ( + $data->status == Studierendenantragstatus_model::STATUS_CREATED && + $this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id) + ); + $this->outputJsonSuccess($data); } From 5670bac3f682376582be954e826d3722f1bde20f Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Thu, 20 Jul 2023 15:04:18 +0200 Subject: [PATCH 266/439] Don't allow canceling of Stg Abmeldungen --- application/libraries/AntragLib.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/application/libraries/AntragLib.php b/application/libraries/AntragLib.php index 6e05380a5..c1cab664f 100644 --- a/application/libraries/AntragLib.php +++ b/application/libraries/AntragLib.php @@ -1545,7 +1545,16 @@ class AntragLib */ public function isEntitledToCancelAntrag($antrag_id) { - return $this->isOwnAntrag($antrag_id); + $result = $this->_ci->StudierendenantragModel->load($antrag_id); + if (!hasData($result)) + return false; + $antrag = current(getData($result)); + + if ($antrag->typ != Studierendenantrag_model::TYP_ABMELDUNG_STGL) + return $this->isOwnAntrag($antrag_id); + + // TODO(chris): assistenz can not cancel - should they be able to? + return false; } /** From 8923a099cc257544aba56fdc2fb0c16703350f6d Mon Sep 17 00:00:00 2001 From: cgfhtw Date: Thu, 20 Jul 2023 15:04:49 +0200 Subject: [PATCH 267/439] Sammelmail Stgl & Calltoactions in Student view --- application/controllers/jobs/AntragJob.php | 245 ++++++++++-------- .../views/lehre/Antrag/Student/List.php | 31 +-- system/phrasesupdate.php | 140 ++++++++++ 3 files changed, 289 insertions(+), 127 deletions(-) diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index e0c88ac3a..8130f8a95 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -6,9 +6,9 @@ use \DateTime as DateTime; class AntragJob extends JOB_Controller { - private $allPrestudentsWhereCommitteeExamFailed; + private $allPrestudentsWhereCommitteeExamFailed; - /** + /** * API constructor */ public function __construct() @@ -21,7 +21,7 @@ class AntragJob extends JOB_Controller // Loads SanchoHelper $this->load->helper('hlp_sancho_helper'); - //Load Model + // Load Model $this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel'); $this->load->model('education/Studierendenantragstatus_model', 'StudierendenantragstatusModel'); $this->load->model('education/Pruefung_model', 'PruefungModel'); @@ -34,102 +34,139 @@ class AntragJob extends JOB_Controller */ public function sendStglSammelmail() { - $this->logInfo('Start Job sendStglSammelmail'); + $this->load->model('person/Person_model', 'PersonModel'); - // TODO(chris): get all Abmeldung:Created, Unterbrechung:Created, Wiederholung:LvZugeordnet - $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->logInfo('Start Job sendStglSammelmail'); - $this->StudierendenantragModel->addJoin('public.tbl_prestudent','prestudent_id'); - $this->db->group_start(); - $this->db->where('typ', Studierendenantrag_model::TYP_ABMELDUNG); - $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); - $this->db->group_end(); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); - $this->db->or_group_start(); - $this->db->where('typ', Studierendenantrag_model::TYP_ABMELDUNG_STGL); - $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); - $this->db->group_end(); + $this->StudierendenantragModel->addJoin('public.tbl_prestudent','prestudent_id'); + $this->db->group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_ABMELDUNG); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); + $this->db->group_end(); - $this->db->or_group_start(); - $this->db->where('typ', Studierendenantrag_model::TYP_UNTERBRECHUNG); - $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); - $this->db->group_end(); + $this->db->or_group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_ABMELDUNG_STGL); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); + $this->db->group_end(); - $this->db->or_group_start(); - $this->db->where('typ', Studierendenantrag_model::TYP_WIEDERHOLUNG); - $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_LVSASSIGNED); - $this->db->group_end(); + $this->db->or_group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_UNTERBRECHUNG); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_CREATED); + $this->db->group_end(); - $result = $this->StudierendenantragModel->load(); - if(isError($result)) - return $this->logError(getError($result)); + $this->db->or_group_start(); + $this->db->where('typ', Studierendenantrag_model::TYP_WIEDERHOLUNG); + $this->db->where('campus.get_status_studierendenantrag(studierendenantrag_id)', Studierendenantragstatus_model::STATUS_LVSASSIGNED); + $this->db->group_end(); - if(!hasData($result)) - return $this->logInfo('End Job sendStglSammelmail: 0 Mails sent'); + $result = $this->StudierendenantragModel->load(); + if(isError($result)) + return $this->logError(getError($result)); - $antraege = getData($result); + if(!hasData($result)) + return $this->logInfo('End Job sendStglSammelmail: 0 Mails sent'); - $stgs = array(); - $stgLeitungen = array(); + $antraege = getData($result); - foreach($antraege as $antrag) - { - if(!isset($stgs[$antrag->studiengang_kz])) - { - $result = $this->StudiengangModel->getLeitung($antrag->studiengang_kz); - if(isError($result)) - { - $this->logError(getError($result)); - continue; - } - if(!hasData($result)) - { - $this->logError('Keine Leitung für Studiengang ' . $antrag->studiengang_kz . ' gefunden!'); - continue; - } + $stgs = array(); + $stgLeitungen = array(); - $leitung = current(getData($result)); - if(!isset($stgLeitungen[$leitung->uid])) - { - $stgLeitungen[$leitung->uid] = [ 'Details' => $leitung, 'stgs' => [] ]; - } - $stgLeitungen[$leitung->uid] ['stgs'][] = $antrag->studiengang_kz; + foreach ($antraege as $antrag) + { + if (!isset($stgs[$antrag->studiengang_kz])) + { + $result = $this->StudiengangModel->getLeitung($antrag->studiengang_kz); + if (isError($result)) + { + $this->logError(getError($result)); + continue; + } + if (!hasData($result)) + { + $this->logError('Keine Leitung für Studiengang ' . $antrag->studiengang_kz . ' gefunden!'); + continue; + } - $result = $this->StudiengangModel->load($antrag->studiengang_kz); - if(isError($result)) - { - $this->logError(getError($result)); - continue; - } - if(!hasData($result)) - { - $this->logError('Keine Details für Studiengang ' . $antrag->studiengang_kz . ' gefunden!'); - continue; - } - $details = current(getData($result)); + $leitung = current(getData($result)); + if (!isset($stgLeitungen[$leitung->uid])) + { + $stgLeitungen[$leitung->uid] = [ 'Details' => $leitung, 'stgs' => [] ]; + } + $stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz; - $stgs[$antrag->studiengang_kz] = [ 'Abmeldung' => [], 'Unterbrechung' => [], 'Wiederholung' => [], 'Details' => $details ]; - } - $stgs[$antrag->studiengang_kz] [$antrag->typ] = $antrag; - } + $result = $this->StudiengangModel->load($antrag->studiengang_kz); + if (isError($result)) + { + $this->logError(getError($result)); + continue; + } + if (!hasData($result)) + { + $this->logError('Keine Details für Studiengang ' . $antrag->studiengang_kz . ' gefunden!'); + continue; + } + $details = current(getData($result)); -/* var_dump($stgs); - var_dump($stgLeitungen);*/ + $stgs[$antrag->studiengang_kz] = [ + 'Abmeldung' => [], + 'Unterbrechung' => [], + 'Wiederholung' => [], + 'Details' => $details + ]; + } + $stgs[$antrag->studiengang_kz][str_replace('Stgl', '', $antrag->typ)] = $antrag; + } - $count = 0; - foreach($stgLeitungen as $leitung) - { - $data = array(); - if(sendSanchoMail("Sancho_Mail_Antrag_Stgl",$data,$leitung['Details']->email, 'Anträge - Aktion(en) erforderlich')) - $count++; - } + $this->load->model('system/Sprache_model', 'SpracheModel'); + $result = $this->SpracheModel->loadWhere(['content' => true]); + if (isError($result)) { + $this->logError(getError($result)); + $languages = [DEFAULT_LANGUAGE]; + } else if (!hasData($result)) { + $languages = [DEFAULT_LANGUAGE]; + } else { + $languages = array_map(function ($row) { + return $row->sprache; + }, getData($result)); + } - $this->logInfo($count . " Emails erfolgreich versandt"); + $count = 0; + foreach ($stgLeitungen as $leitung) + { + $data = [ + 'name' => trim($leitung['Details']->vorname . ' ' . $leitung['Details']->nachname) + ]; - // TODO(chris): Emailadresse stg - // TODO(chris): data Fertig + foreach ($languages as $lang) { + unset($this->p); + $this->loadPhrases(['studierendenantrag'], $lang); - $this->logInfo('End Job sendStglSammelmail'); + $table = ''; + foreach ($leitung['stgs'] as $studiengang_kz) { + $rows = ''; + $stg = $stgs[$studiengang_kz]; + foreach (['Abmeldung', 'Unterbrechung', 'Wiederholung'] as $typ) { + $c = count($stg[$typ]); + if ($c) { + $rows .= $this->p->t('studierendenantrag', 'mail_part_x_new_' . $typ, ['count' => $c]); + } + } + $table .= $this->p->t('studierendenantrag', 'mail_part_table', ['stg_bezeichnung' => $stg['Details']->bezeichnung, 'stg_orgform_kurzbz' => $stg['Details']->orgform_kurzbz, 'rows' => $rows]); + } + $data['table_' . $lang] = $table; + } + + $data['table'] = $data['table_' . DEFAULT_LANGUAGE]; + + if (sendSanchoMail("Sancho_Mail_Antrag_Stgl", $data, $leitung['Details']->uid . '@' . DOMAIN, 'Anträge - Aktion(en) erforderlich')) + $count++; + } + + $this->logInfo($count . " Emails erfolgreich versandt"); + + $this->logInfo('End Job sendStglSammelmail'); } /** @@ -210,22 +247,22 @@ class AntragJob extends JOB_Controller return; } - $digi_start= $this->config->item('digitalization_start'); - if($digi_start) - $digi_start = new DateTime($digi_start); + $digi_start= $this->config->item('digitalization_start'); + if($digi_start) + $digi_start = new DateTime($digi_start); $dateDeadline = new DateTime(); $dateDeadline->sub(DateInterval::createFromDateString($modifier_deadline)); - $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed( - [ - null, - Studierendenantragstatus_model::STATUS_REQUESTSENT_1, - Studierendenantragstatus_model::STATUS_REQUESTSENT_2 - ], - $dateDeadline, - $digi_start - ); + $result = $this->PruefungModel->getAllPrestudentsWhereCommitteeExamFailed( + [ + null, + Studierendenantragstatus_model::STATUS_REQUESTSENT_1, + Studierendenantragstatus_model::STATUS_REQUESTSENT_2 + ], + $dateDeadline, + $digi_start + ); if(isError($result)) { $this->logError(getError($result)); @@ -238,18 +275,18 @@ class AntragJob extends JOB_Controller $prestudents = $this->prestudentsGetUnique($prestudents); - foreach ($prestudents as $prestudent) - { - $result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz, $insertvon); - if (isError($result)) - $this->logError(getError($result)); - else - $count++; - } - $this->logInfo($count . " Students set to Abbrecher"); - } + foreach ($prestudents as $prestudent) + { + $result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz, $insertvon); + if (isError($result)) + $this->logError(getError($result)); + else + $count++; + } + $this->logInfo($count . " Students set to Abbrecher"); + } - $this->logInfo('Ende Job handleWiederholerDeadline'); + $this->logInfo('Ende Job handleWiederholerDeadline'); } /** diff --git a/application/views/lehre/Antrag/Student/List.php b/application/views/lehre/Antrag/Student/List.php index b1ec9e061..52242d7d6 100644 --- a/application/views/lehre/Antrag/Student/List.php +++ b/application/views/lehre/Antrag/Student/List.php @@ -33,29 +33,14 @@ $this->load->view( $array){ ?>

()

- - - - p->t('studierendenantrag', 'btn_new'); ?> - -