mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-07-25 00:24:35 +00:00
Merge branch 'feature-76657/AbgabetoolFinetuning' into cis40_2026-02_rc_abgabetool_finetuning
This commit is contained in:
@@ -29,7 +29,7 @@ $config['ALLOWED_NOTEN_ABGABETOOL'] = [10, 14]; // tbl_note pk
|
||||
// benotete projektarbeiten sperren weitere terminanlage & bearbeitung, diese noten sind ausnahmen dieser Regel
|
||||
// wie zB "Nicht beurteilt" & "Noch nicht eingetragen"
|
||||
$config['NONFINAL_NOTEN_ABGABETOOL'] = [9];
|
||||
$config['beurteilung_link_fallback'] = 'addons/fhtw/content/projektbeurteilung/projektbeurteilungDocumentExport.php?projektarbeit_id=?&betreuerart_kurzbz=?&person_id=?';
|
||||
$config['beurteilung_link_fallback'] = 'cis/private/lehre/projektbeurteilungDocumentExport.php?projektarbeit_id=?&betreuerart_kurzbz=?&person_id=?';
|
||||
|
||||
$config['PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ERSTBEGUTACHTER'] = 'index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter';
|
||||
$config['PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ZWEITBEGUTACHTER'] = 'index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter';
|
||||
|
||||
@@ -49,7 +49,9 @@ class Abgabe extends FHCAPI_Controller
|
||||
'getStudiengaenge' => array('basis/abgabe_assistenz:rw'),
|
||||
'getStudentProjektarbeitAbgabeFile' => array('basis/abgabe_student:rw', 'basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'),
|
||||
'postStudentProjektarbeitZusatzdaten' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'),
|
||||
'getSignaturStatusForProjektarbeitAbgaben' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw')
|
||||
'getSignaturStatusForProjektarbeitAbgaben' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'),
|
||||
'sendZweitbetreuerTokenMail' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'),
|
||||
'fetchProjektarbeitenHistory' => array('basis/abgabe_assistenz:rw')
|
||||
]);
|
||||
|
||||
$this->load->library('PhrasesLib');
|
||||
@@ -422,9 +424,16 @@ class Abgabe extends FHCAPI_Controller
|
||||
$this->checkAbgabeSignatur($paabgabe, $projektarbeit->student_uid);
|
||||
$signaturstatus = $paabgabe->signatur;
|
||||
|
||||
// update projektarbeit cols
|
||||
$this->ProjektarbeitModel->updateProjektarbeit($projektarbeit_id, $sprache, $abstract, $abstract_en
|
||||
, $schlagwoerter, $schlagwoerter_en, $seitenanzahl);
|
||||
// update projektarbeit cols with zusatzdaten AND abgabedatum!
|
||||
$this->ProjektarbeitModel->update($projektarbeit->projektarbeit_id, array(
|
||||
'sprache' => $sprache,
|
||||
'seitenanzahl' => $seitenanzahl,
|
||||
'abgabedatum' => date('Y-m-d'),
|
||||
'schlagwoerter_en' => $schlagwoerter_en,
|
||||
'schlagwoerter' => $schlagwoerter,
|
||||
'abstract' => $abstract,
|
||||
'abstract_en' => $abstract_en
|
||||
));
|
||||
|
||||
|
||||
// update paabgabe datum
|
||||
@@ -727,7 +736,7 @@ class Abgabe extends FHCAPI_Controller
|
||||
$showAllBool = false;
|
||||
}
|
||||
|
||||
$projektarbeiten = $this->ProjektarbeitModel->getMitarbeiterProjektarbeiten(getAuthUID(), $showAllBool);
|
||||
$projektarbeiten = $this->ProjektarbeitModel->getMitarbeiterProjektarbeiten(getAuthPersonId(), $showAllBool);
|
||||
|
||||
|
||||
$mapFunc = function($projektarbeit) {
|
||||
@@ -742,18 +751,15 @@ class Abgabe extends FHCAPI_Controller
|
||||
|
||||
forEach($projektarbeiten->retval as $pa) {
|
||||
|
||||
$result = $this->ProjektarbeitModel->getProjektbetreuerAnrede($pa->betreuer_person_id);
|
||||
$anredeArr = $this->getDataOrTerminateWithError($result, 'general');
|
||||
$pa->betreuer = $anredeArr[0];
|
||||
|
||||
$oldLink = ''; // show this when paIsCurrent == false -> moodle course template
|
||||
$newLink = ''; // get curated path for betreuer type
|
||||
$returnFunc = function ( $resultOld, $resultNew) use (&$oldLink, &$newLink) {
|
||||
$returnFunc = function ($resultOld, $resultNew) use (&$oldLink, &$newLink) {
|
||||
$newLink = $resultNew;
|
||||
$oldLink = $resultOld;
|
||||
};
|
||||
|
||||
Events::trigger('projektbeurteilung_formular_link', $pa->betreuerart_kurzbz, APP_ROOT, $pa->projektarbeit_id, $pa->student_uid, $returnFunc);
|
||||
$own_betreuerart_kurzbz = $pa->betreuer_person_id == getAuthPersonId() ? $pa->betreuer_betreuerart_kurzbz : $pa->zweitbetreuer_betreuerart_kurzbz;
|
||||
Events::trigger('projektbeurteilung_formular_link', $own_betreuerart_kurzbz, APP_ROOT, $pa->projektarbeit_id, $pa->student_uid, $returnFunc);
|
||||
$pa->beurteilungLinkNew = $newLink;
|
||||
$pa->beurteilungLinkOld = $oldLink;
|
||||
|
||||
@@ -841,12 +847,22 @@ class Abgabe extends FHCAPI_Controller
|
||||
// load existing entry of paabgabe and check if note has changed to negativ, to avoid sending when
|
||||
// only notiz has changed.
|
||||
|
||||
// TODO: what if paabgabe is a qualgate1, is benotet negativ and then its type is changed to gate2?
|
||||
|
||||
$existingResult = $this->PaabgabeModel->load($paabgabe_id);
|
||||
$existingPaabgabeArr = getData($existingResult);
|
||||
if(count($existingPaabgabeArr) > 0) $existingPaabgabe = $existingPaabgabeArr[0];
|
||||
|
||||
if($existingPaabgabe->note !== null || $existingPaabgabe->abgabedatum !== null) {
|
||||
// check if a change of paabgabetyp is being attempted -> not allowed at this point
|
||||
if($paabgabetyp_kurzbz !== $existingPaabgabe->paabgabetyp_kurzbz) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4abgabetypAendernNichtErlaubt'));
|
||||
}
|
||||
|
||||
// check if a change of deadline aka datum is being attempted -> notallowed at this point
|
||||
if($datum !== $existingPaabgabe->datum) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4datumAendernNichtErlaubt'));
|
||||
}
|
||||
}
|
||||
|
||||
$result = $this->PaabgabeModel->update(
|
||||
$paabgabe_id,
|
||||
array(
|
||||
@@ -1207,10 +1223,10 @@ class Abgabe extends FHCAPI_Controller
|
||||
private function getProjektbetreuerEmailByProjektarbeitID($projektarbeit_id) {
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
$result = $this->ProjektarbeitModel->getProjektbetreuerEmail($projektarbeit_id);
|
||||
if(count($result->retval) > 0) {
|
||||
if(hasData($result)) {
|
||||
$email = getData($result);
|
||||
return $email[0]->uid ? $email[0]->uid.'@'.DOMAIN : $email[0]->private_email;
|
||||
} else return '';
|
||||
} else return null;
|
||||
|
||||
}
|
||||
|
||||
@@ -1221,9 +1237,12 @@ class Abgabe extends FHCAPI_Controller
|
||||
private function getProjektbetreuerEmailByPersonID($person_id) {
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
$result = $this->ProjektarbeitModel->getProjektbetreuerEmailByPersonID($person_id);
|
||||
$email = $this->getDataOrTerminateWithError($result, 'general');
|
||||
|
||||
return $email[0]->uid ? $email[0]->uid.'@'.DOMAIN : $email[0]->private_email;
|
||||
if(hasData($result)) {
|
||||
$email = getData($result);
|
||||
return $email[0]->uid ? $email[0]->uid.'@'.DOMAIN : $email[0]->private_email;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: SWITCH TO NOTEN API ONCE NOTENTOOL IS IN MASTER TO AVOID DUPLICATE API
|
||||
@@ -1466,9 +1485,15 @@ class Abgabe extends FHCAPI_Controller
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent'), 'general');
|
||||
}
|
||||
|
||||
// update projektarbeit cols
|
||||
$this->ProjektarbeitModel->updateProjektarbeit($projektarbeit_id,$sprache,$abstract,$abstract_en
|
||||
,$schlagwoerter, $schlagwoerter_en, $seitenanzahl);
|
||||
// update projektarbeit cols with zusatzdaten only
|
||||
$this->ProjektarbeitModel->update($projektarbeit_id, array(
|
||||
'sprache' => $sprache,
|
||||
'seitenanzahl' => $seitenanzahl,
|
||||
'schlagwoerter_en' => $schlagwoerter_en,
|
||||
'schlagwoerter' => $schlagwoerter,
|
||||
'abstract' => $abstract,
|
||||
'abstract_en' => $abstract_en
|
||||
));
|
||||
|
||||
$this->logLib->logInfoDB(array('zusatzdatenEditMitarbeiter', array(
|
||||
'updatevon' => getAuthUID(),
|
||||
@@ -1504,6 +1529,58 @@ class Abgabe extends FHCAPI_Controller
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
public function sendZweitbetreuerTokenMail() {
|
||||
$projektarbeit_id = $this->input->post('projektarbeit_id');
|
||||
$bperson_id = $this->input->post('bperson_id');
|
||||
$student_uid = $this->input->post('student_uid');
|
||||
|
||||
if ($projektarbeit_id === NULL || trim((string)$projektarbeit_id) === ''
|
||||
|| $bperson_id === NULL || trim((string)$bperson_id) === ''
|
||||
|| $student_uid === NULL || trim((string)$student_uid) === '') {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
$this->checkProjektarbeitForFinishedStatus($projektarbeit_id);
|
||||
|
||||
$zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID());
|
||||
if(!$zugeordnet) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent'));
|
||||
}
|
||||
|
||||
$this->sendUploadEmailZweitbegutachterToken($bperson_id, $projektarbeit_id, $student_uid);
|
||||
}
|
||||
|
||||
// basically what getStudentProjektarbeiten intends to do for the student page but
|
||||
// designed for the assistenz timeline component -> more extensive loading upfront
|
||||
// with every abgabetermin fetched here aswell
|
||||
public function fetchProjektarbeitenHistory() {
|
||||
$student_uid = $this->input->post('student_uid');
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
|
||||
$projektarbeiten = $this->ProjektarbeitModel->getProjektarbeitenForStudent($student_uid);
|
||||
|
||||
$mapFunc = function($projektarbeit) {
|
||||
return $projektarbeit->projektarbeit_id;
|
||||
};
|
||||
$projektarbeiten_ids = array_map($mapFunc, $projektarbeiten->retval);
|
||||
|
||||
if(count($projektarbeiten_ids) > 0) {
|
||||
$ret = $this->ProjektarbeitModel->getProjektarbeitenAbgabetermine($projektarbeiten_ids);
|
||||
$projektabgaben = $this->getDataOrTerminateWithError($ret, 'general');
|
||||
}
|
||||
|
||||
forEach($projektarbeiten->retval as $pa) {
|
||||
|
||||
$filterFunc = function($projektabgabe) use ($pa) {
|
||||
return $projektabgabe->projektarbeit_id == $pa->projektarbeit_id;
|
||||
};
|
||||
|
||||
$pa->abgabetermine = array_values(array_filter($projektabgaben, $filterFunc));
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($projektarbeiten->retval);
|
||||
}
|
||||
|
||||
/**
|
||||
* helper function to check the signature status of uploaded files for zwischenabgabe & endupload
|
||||
*/
|
||||
@@ -1569,13 +1646,6 @@ class Abgabe extends FHCAPI_Controller
|
||||
$this->terminateWithError($this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeitv2'), 'general');
|
||||
}
|
||||
|
||||
// Link to Abgabetool
|
||||
if (defined('CIS4') && CIS4) {
|
||||
$ci3BootstrapFilePath = "cis.php";
|
||||
} else {
|
||||
$ci3BootstrapFilePath = "index.ci.php";
|
||||
}
|
||||
|
||||
$path = $this->config->item('URL_MITARBEITER');
|
||||
$url = APP_ROOT.$path;
|
||||
|
||||
@@ -1587,7 +1657,6 @@ class Abgabe extends FHCAPI_Controller
|
||||
|
||||
// 1. Begutachter mail ohne Token
|
||||
$mail_baselink = APP_ROOT.$this->config->item('PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ERSTBEGUTACHTER');
|
||||
// $mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter";
|
||||
$mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$studentUser->uid;
|
||||
$projekttyp_kurzbz = $projektarbeit->projekttyp_kurzbz;
|
||||
$subject = $projektarbeit->projekttyp_kurzbz == 'Diplom' ? 'Masterarbeitsbetreuung' : 'Bachelorarbeitsbetreuung';
|
||||
@@ -1607,7 +1676,7 @@ class Abgabe extends FHCAPI_Controller
|
||||
$email = $this->getProjektbetreuerEmailByProjektarbeitID($projektarbeit_id);
|
||||
|
||||
if(!$email) $this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailBegutachterv2'), 'general');
|
||||
|
||||
|
||||
$mailres = sendSanchoMail(
|
||||
'ParbeitsbeurteilungEndupload',
|
||||
$maildata,
|
||||
@@ -1625,66 +1694,101 @@ class Abgabe extends FHCAPI_Controller
|
||||
// 2. Begutachter mail, wenn Endabgabe, mit Token wenn extern
|
||||
if ($paabgabetyp_kurzbz == 'end')
|
||||
{
|
||||
// Zweitbegutachter holen
|
||||
$this->load->model('education/Projektbetreuer_model', 'ProjektbetreuerModel');
|
||||
$zweitbegutachterRetval = getData($this->ProjektbetreuerModel->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $studentUser->uid));
|
||||
$this->sendUploadEmailZweitbegutachterToken($bperson_id, $projektarbeit_id, $studentUser->uid);
|
||||
|
||||
if ($zweitbegutachterRetval && count($zweitbegutachterRetval) > 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function sendUploadEmailZweitbegutachterToken($bperson_id, $projektarbeit_id, $student_uid) {
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
$projektarbeitArr = $this->getDataOrTerminateWithError($this->ProjektarbeitModel->load($projektarbeit_id));
|
||||
if(count($projektarbeitArr) > 0) {
|
||||
$projektarbeit = $projektarbeitArr[0];
|
||||
} else {
|
||||
$this->terminateWithError($this->p->t('abgabetool','c4projektarbeitNichtGefunden'), 'general');
|
||||
}
|
||||
|
||||
// Zweitbegutachter holen
|
||||
$this->load->model('education/Projektbetreuer_model', 'ProjektbetreuerModel');
|
||||
$zweitbegutachterRetval = getData($this->ProjektbetreuerModel->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $student_uid));
|
||||
|
||||
$projektarbeitIsCurrent = false;
|
||||
$returnFunc = function ($result) use (&$projektarbeitIsCurrent) {
|
||||
$projektarbeitIsCurrent = $result;
|
||||
};
|
||||
Events::trigger('projektarbeit_is_current', $projektarbeit_id, $returnFunc);
|
||||
if(!$projektarbeitIsCurrent) {
|
||||
$this->terminateWithError($this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeitv2'), 'general');
|
||||
}
|
||||
|
||||
if ($zweitbegutachterRetval && count($zweitbegutachterRetval) > 0)
|
||||
{
|
||||
|
||||
foreach ($zweitbegutachterRetval as $begutachter)
|
||||
{
|
||||
// token generieren, wenn noch nicht vorhanden und notwendig (wird in methode überprüft)
|
||||
$tokenGenRes = $this->ProjektbetreuerModel->generateZweitbegutachterToken($begutachter->person_id, $projektarbeit_id);
|
||||
|
||||
if (!$tokenGenRes)
|
||||
{
|
||||
|
||||
foreach ($zweitbegutachterRetval as $begutachter)
|
||||
{
|
||||
// token generieren, wenn noch nicht vorhanden und notwendig (wird in methode überprüft)
|
||||
$tokenGenRes = $this->ProjektbetreuerModel->generateZweitbegutachterToken($begutachter->person_id, $projektarbeit_id);
|
||||
|
||||
if (!$tokenGenRes)
|
||||
{
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailZweitBegutachterv2'), 'general');
|
||||
}
|
||||
|
||||
$begutachterMitTokenRetval = getData($this->ProjektbetreuerModel->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $studentUser->uid, $begutachter->person_id));
|
||||
|
||||
if (!$begutachterMitTokenRetval && count($begutachterMitTokenRetval) <= 0)
|
||||
{
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailZweitBegutachterv2'), 'general');
|
||||
}
|
||||
|
||||
$begutachterMitToken = $begutachterMitTokenRetval[0];
|
||||
|
||||
$path = $begutachterMitToken->betreuerart_kurzbz == 'Zweitbegutachter' ? 'ProjektarbeitsbeurteilungZweitbegutachter' : 'ProjektarbeitsbeurteilungErstbegutachter';
|
||||
$mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/$path";
|
||||
$mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$studentUser->uid;
|
||||
$intern = isset($begutachterMitToken->uid);
|
||||
$mail_link = $intern ? $mail_fulllink : $mail_baselink;
|
||||
|
||||
$zweitbetmaildata = array();
|
||||
$zweitbetmaildata['geehrt'] = "geehrte" . ($begutachterMitToken->anrede == "Herr" ? "r" : "");
|
||||
$zweitbetmaildata['anrede'] = $begutachterMitToken->anrede;
|
||||
$zweitbetmaildata['betreuer_voller_name'] = $begutachterMitToken->voller_name;
|
||||
$zweitbetmaildata['student_anrede'] = $maildata['student_anrede'];
|
||||
$zweitbetmaildata['student_voller_name'] = $maildata['student_voller_name'];
|
||||
$zweitbetmaildata['abgabetyp'] = $abgabetyp;
|
||||
$zweitbetmaildata['parbeituebersichtlink'] = $intern ? $maildata['parbeituebersichtlink'] : "";
|
||||
$zweitbetmaildata['bewertunglink'] = $projektarbeitIsCurrent ? "<p><a href='$mail_link'>Zur Beurteilung der Arbeit</a></p>" : "";
|
||||
$zweitbetmaildata['token'] = $projektarbeitIsCurrent && isset($begutachterMitToken->zugangstoken) && !$intern ? "<p>Zugangstoken: " . $begutachterMitToken->zugangstoken . "</p>" : "";
|
||||
|
||||
$mailres = sendSanchoMail(
|
||||
'ParbeitsbeurteilungEndupload',
|
||||
$zweitbetmaildata,
|
||||
$begutachterMitToken->email,
|
||||
$subject,
|
||||
'sancho_header_min_bw.jpg',
|
||||
'sancho_footer_min_bw.jpg',
|
||||
get_uid()."@".DOMAIN
|
||||
);
|
||||
|
||||
if (!$mailres)
|
||||
{
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailBegutachterv2'), 'general');
|
||||
}
|
||||
|
||||
}
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailZweitBegutachterv2'), 'general');
|
||||
}
|
||||
|
||||
$begutachterMitTokenRetval = getData($this->ProjektbetreuerModel->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $student_uid, $begutachter->person_id));
|
||||
|
||||
if (!$begutachterMitTokenRetval && count($begutachterMitTokenRetval) <= 0)
|
||||
{
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailZweitBegutachterv2'), 'general');
|
||||
}
|
||||
|
||||
$begutachterMitToken = $begutachterMitTokenRetval[0];
|
||||
|
||||
$studentUser = $this->ProjektarbeitModel->getProjektarbeitBenutzer($student_uid)->retval[0];
|
||||
|
||||
$path = $begutachterMitToken->betreuerart_kurzbz == 'Zweitbegutachter' ? 'ProjektarbeitsbeurteilungZweitbegutachter' : 'ProjektarbeitsbeurteilungErstbegutachter';
|
||||
$mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/$path";
|
||||
$mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$student_uid;
|
||||
$intern = isset($begutachterMitToken->uid);
|
||||
$mail_link = $intern ? $mail_fulllink : $mail_baselink;
|
||||
|
||||
// automatic email ensures that, client only exposes this method if that happened already
|
||||
$paabgabetyp_kurzbz = 'end';
|
||||
$abgabetyp = $paabgabetyp_kurzbz == 'end' ? 'Endabgabe' : 'Zwischenabgabe';
|
||||
|
||||
$path = $this->config->item('URL_MITARBEITER');
|
||||
$url = APP_ROOT.$path;
|
||||
|
||||
$subject = $projektarbeit->projekttyp_kurzbz == 'Diplom' ? 'Masterarbeitsbetreuung' : 'Bachelorarbeitsbetreuung';
|
||||
|
||||
$zweitbetmaildata = array();
|
||||
$zweitbetmaildata['geehrt'] = "geehrte" . ($begutachterMitToken->anrede == "Herr" ? "r" : "");
|
||||
$zweitbetmaildata['anrede'] = $begutachterMitToken->anrede;
|
||||
$zweitbetmaildata['betreuer_voller_name'] = $begutachterMitToken->voller_name;
|
||||
$zweitbetmaildata['student_anrede'] = $studentUser->anrede;
|
||||
$zweitbetmaildata['student_voller_name'] = trim($studentUser->titelpre." ".$studentUser->vorname." ".$studentUser->nachname." ".$studentUser->titelpost);
|
||||
$zweitbetmaildata['abgabetyp'] = $abgabetyp;
|
||||
$zweitbetmaildata['parbeituebersichtlink'] = $intern ? "<p><a href='$url'>Zur Projektarbeitsübersicht</a></p>" : "";
|
||||
$zweitbetmaildata['bewertunglink'] = $projektarbeitIsCurrent ? "<p><a href='$mail_link'>Zur Beurteilung der Arbeit</a></p>" : "";
|
||||
$zweitbetmaildata['token'] = $projektarbeitIsCurrent && isset($begutachterMitToken->zugangstoken) && !$intern ? "<p>Zugangstoken: " . $begutachterMitToken->zugangstoken . "</p>" : "";
|
||||
|
||||
$this->addMeta('$zweitbetmaildata', $zweitbetmaildata);
|
||||
|
||||
$mailres = sendSanchoMail(
|
||||
'ParbeitsbeurteilungEndupload',
|
||||
$zweitbetmaildata,
|
||||
$begutachterMitToken->email,
|
||||
$subject,
|
||||
'sancho_header_min_bw.jpg',
|
||||
'sancho_footer_min_bw.jpg',
|
||||
get_uid()."@".DOMAIN
|
||||
);
|
||||
|
||||
if (!$mailres)
|
||||
{
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailBegutachterv2'), 'general');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -287,10 +287,7 @@ class Projektarbeit extends FHCAPI_Controller
|
||||
*/
|
||||
public function getNoten()
|
||||
{
|
||||
$this->NoteModel->addOrder('notenwert', 'ASC');
|
||||
$this->NoteModel->addOrder('bezeichnung', 'ASC');
|
||||
|
||||
$result = $this->NoteModel->load();
|
||||
$result = $this->NoteModel->getAllActive();
|
||||
|
||||
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
|
||||
@@ -187,7 +187,10 @@ class Projektarbeit_model extends DB_Model
|
||||
campus.tbl_paabgabetyp.bezeichnung,
|
||||
campus.tbl_paabgabetyp.benotbar,
|
||||
campus.tbl_paabgabe.abgabedatum,
|
||||
campus.tbl_paabgabe.insertvon
|
||||
campus.tbl_paabgabe.insertvon,
|
||||
campus.tbl_paabgabe.insertamum,
|
||||
campus.tbl_paabgabe.updatevon,
|
||||
campus.tbl_paabgabe.updateamum
|
||||
FROM campus.tbl_paabgabe JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz)
|
||||
WHERE campus.tbl_paabgabe.projektarbeit_id = ?
|
||||
ORDER BY campus.tbl_paabgabe.datum";
|
||||
@@ -207,7 +210,18 @@ class Projektarbeit_model extends DB_Model
|
||||
campus.tbl_paabgabetyp.paabgabetyp_kurzbz,
|
||||
campus.tbl_paabgabetyp.bezeichnung,
|
||||
campus.tbl_paabgabe.abgabedatum,
|
||||
campus.tbl_paabgabe.insertvon
|
||||
campus.tbl_paabgabe.insertvon,
|
||||
campus.tbl_paabgabe.updatevon,
|
||||
campus.tbl_paabgabe.insertamum,
|
||||
campus.tbl_paabgabe.updateamum,
|
||||
(SELECT p.vorname || ' ' || p.nachname
|
||||
FROM public.tbl_benutzer b
|
||||
JOIN public.tbl_person p USING(person_id)
|
||||
WHERE b.uid = campus.tbl_paabgabe.insertvon) AS insertvon_fullname,
|
||||
(SELECT p.vorname || ' ' || p.nachname
|
||||
FROM public.tbl_benutzer b
|
||||
JOIN public.tbl_person p USING(person_id)
|
||||
WHERE b.uid = campus.tbl_paabgabe.updatevon) AS updatevon_fullname
|
||||
FROM campus.tbl_paabgabe JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz)
|
||||
WHERE campus.tbl_paabgabe.projektarbeit_id IN ?
|
||||
ORDER BY campus.tbl_paabgabe.datum";
|
||||
@@ -240,7 +254,8 @@ class Projektarbeit_model extends DB_Model
|
||||
LEFT JOIN public.tbl_benutzer ben USING (person_id)
|
||||
LEFT JOIN public.tbl_mitarbeiter ma ON ben.uid = ma.mitarbeiter_uid
|
||||
WHERE (ben.aktiv OR ben.aktiv IS NULL)
|
||||
AND projektarbeit_id = ?";
|
||||
AND projektarbeit_id = ?
|
||||
AND lehre.tbl_projektbetreuer.betreuerart_kurzbz = ANY('{Erstbetreuer,Erstbegutachter,Senatsvorsitz}')";
|
||||
|
||||
return $this->execReadOnlyQuery($qry, [$projektarbeit_id]);
|
||||
}
|
||||
@@ -294,34 +309,134 @@ class Projektarbeit_model extends DB_Model
|
||||
* Get a List of Projektarbeiten of a mitarbeiter with zuordnung
|
||||
* used by the mitarbeiter cis4 abgabetool.
|
||||
*/
|
||||
public function getMitarbeiterProjektarbeiten($uid, $showAll){
|
||||
$qry = "SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT tbl_person.vorname, tbl_person.nachname, tbl_studiengang.typ, tbl_studiengang.kurzbz,
|
||||
tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung, tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id, tbl_projektarbeit.note,
|
||||
tbl_projektbetreuer.person_id as betreuer_person_id, tbl_projektbetreuer.betreuerart_kurzbz, tbl_betreuerart.beschreibung AS betreuerart_beschreibung,
|
||||
tbl_benutzer.uid, tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz, public.tbl_student.student_uid
|
||||
FROM lehre.tbl_projektarbeit
|
||||
LEFT JOIN lehre.tbl_projektbetreuer using(projektarbeit_id)
|
||||
LEFT JOIN lehre.tbl_betreuerart using(betreuerart_kurzbz)
|
||||
LEFT JOIN public.tbl_benutzer on(uid=student_uid)
|
||||
LEFT JOIN public.tbl_student on(public.tbl_benutzer.uid=public.tbl_student.student_uid)
|
||||
LEFT JOIN public.tbl_person on(tbl_benutzer.person_id=tbl_person.person_id)
|
||||
LEFT JOIN lehre.tbl_lehreinheit using(lehreinheit_id)
|
||||
LEFT JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id)
|
||||
LEFT JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz=public.tbl_studiengang.studiengang_kz)
|
||||
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
|
||||
WHERE (projekttyp_kurzbz='Bachelor' OR projekttyp_kurzbz='Diplom')
|
||||
AND tbl_projektbetreuer.person_id IN (SELECT person_id FROM public.tbl_benutzer
|
||||
WHERE public.tbl_benutzer.person_id=lehre.tbl_projektbetreuer.person_id
|
||||
AND public.tbl_benutzer.uid= ? )
|
||||
".($showAll?'':' AND public.tbl_benutzer.aktiv AND lehre.tbl_projektarbeit.note IS NULL ')."
|
||||
public function getMitarbeiterProjektarbeiten($person_id, $showAll){
|
||||
$qry = "WITH secondary_betreuer AS (
|
||||
SELECT DISTINCT ON (pb.projektarbeit_id)
|
||||
pb.projektarbeit_id,
|
||||
pb.person_id AS zweitbetreuer_person_id,
|
||||
b.uid AS zweitbetreuer_benutzer_uid,
|
||||
pb.betreuerart_kurzbz AS zweitbetreuer_betreuerart_kurzbz,
|
||||
ba.beschreibung AS zweitbetreuer_betreuerart_beschreibung,
|
||||
p.titelpre AS zweitbetreuer_titelpre,
|
||||
p.vorname AS zweitbetreuer_vorname,
|
||||
p.nachname AS zweitbetreuer_nachname,
|
||||
p.titelpost AS zweitbetreuer_titelpost,
|
||||
trim(
|
||||
COALESCE(p.titelpre, '') || ' ' ||
|
||||
COALESCE(p.vorname, '') || ' ' ||
|
||||
COALESCE(p.nachname, '') || ' ' ||
|
||||
COALESCE(p.titelpost, '')
|
||||
) AS zweitbetreuer_full_name
|
||||
FROM lehre.tbl_projektbetreuer pb
|
||||
JOIN public.tbl_person p ON p.person_id = pb.person_id
|
||||
LEFT JOIN public.tbl_benutzer b ON b.person_id = p.person_id
|
||||
LEFT JOIN lehre.tbl_betreuerart ba ON ba.betreuerart_kurzbz = pb.betreuerart_kurzbz
|
||||
WHERE pb.betreuerart_kurzbz = ANY('{Zweitbetreuer,Zweitbegutachter,Senatsmitglied}')
|
||||
ORDER BY pb.projektarbeit_id
|
||||
),
|
||||
primary_betreuer AS (
|
||||
SELECT DISTINCT ON (pb.projektarbeit_id)
|
||||
pb.projektarbeit_id,
|
||||
pb.person_id AS betreuer_person_id,
|
||||
pb.betreuerart_kurzbz AS betreuer_betreuerart_kurzbz,
|
||||
ba.beschreibung AS betreuer_betreuerart_beschreibung,
|
||||
p.titelpre AS betreuer_titelpre,
|
||||
p.vorname AS betreuer_vorname,
|
||||
p.nachname AS betreuer_nachname,
|
||||
p.titelpost AS betreuer_titelpost,
|
||||
trim(
|
||||
COALESCE(p.titelpre, '') || ' ' ||
|
||||
COALESCE(p.vorname, '') || ' ' ||
|
||||
COALESCE(p.nachname, '') || ' ' ||
|
||||
COALESCE(p.titelpost, '')
|
||||
) AS betreuer_full_name
|
||||
FROM lehre.tbl_projektbetreuer pb
|
||||
JOIN public.tbl_person p ON p.person_id = pb.person_id
|
||||
LEFT JOIN public.tbl_benutzer b ON b.person_id = p.person_id
|
||||
LEFT JOIN lehre.tbl_betreuerart ba ON ba.betreuerart_kurzbz = pb.betreuerart_kurzbz
|
||||
WHERE pb.betreuerart_kurzbz = ANY('{Erstbetreuer,Erstbegutachter,Senatsvorsitz}')
|
||||
ORDER BY pb.projektarbeit_id
|
||||
)
|
||||
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(SELECT DISTINCT ON (tbl_projektarbeit.projektarbeit_id)
|
||||
student_person.vorname, student_person.nachname,
|
||||
tbl_studiengang.typ, tbl_studiengang.kurzbz,
|
||||
tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung,
|
||||
tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id, tbl_projektarbeit.note,
|
||||
student_benutzer.uid, tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz, public.tbl_student.student_uid,
|
||||
|
||||
|
||||
(
|
||||
SELECT orgform_kurzbz
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE prestudent_id = (
|
||||
SELECT prestudent_id FROM public.tbl_student
|
||||
WHERE student_uid = student_benutzer.uid LIMIT 1
|
||||
)
|
||||
ORDER BY datum DESC, insertamum DESC, ext_id DESC
|
||||
LIMIT 1
|
||||
) AS organisationsform,
|
||||
(
|
||||
SELECT COALESCE(tbl_studienplan.orgform_kurzbz,
|
||||
tbl_prestudentstatus.orgform_kurzbz,
|
||||
tbl_studiengang.orgform_kurzbz)
|
||||
FROM public.tbl_prestudent
|
||||
JOIN public.tbl_prestudentstatus USING (prestudent_id)
|
||||
JOIN public.tbl_studiensemester USING (studiensemester_kurzbz)
|
||||
JOIN public.tbl_studiengang USING (studiengang_kz)
|
||||
LEFT JOIN lehre.tbl_studienplan USING (studienplan_id)
|
||||
WHERE prestudent_id = public.tbl_student.prestudent_id
|
||||
ORDER BY tbl_prestudentstatus.datum DESC
|
||||
LIMIT 1
|
||||
) AS orgform,
|
||||
(
|
||||
SELECT status_kurzbz
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE prestudent_id = public.tbl_student.prestudent_id
|
||||
ORDER BY datum DESC, insertamum DESC, ext_id DESC
|
||||
LIMIT 1
|
||||
) AS studienstatus,
|
||||
|
||||
pb.betreuer_person_id,
|
||||
pb.betreuer_betreuerart_kurzbz,
|
||||
pb.betreuer_betreuerart_beschreibung,
|
||||
pb.betreuer_titelpre,
|
||||
pb.betreuer_vorname,
|
||||
pb.betreuer_nachname,
|
||||
pb.betreuer_titelpost,
|
||||
pb.betreuer_full_name,
|
||||
|
||||
sb.zweitbetreuer_person_id,
|
||||
sb.zweitbetreuer_benutzer_uid,
|
||||
sb.zweitbetreuer_betreuerart_kurzbz,
|
||||
sb.zweitbetreuer_betreuerart_beschreibung,
|
||||
sb.zweitbetreuer_titelpre,
|
||||
sb.zweitbetreuer_vorname,
|
||||
sb.zweitbetreuer_nachname,
|
||||
sb.zweitbetreuer_titelpost,
|
||||
sb.zweitbetreuer_full_name
|
||||
FROM lehre.tbl_projektarbeit
|
||||
LEFT JOIN public.tbl_benutzer student_benutzer ON student_benutzer.uid = lehre.tbl_projektarbeit.student_uid
|
||||
LEFT JOIN public.tbl_person student_person ON student_benutzer.person_id = student_person.person_id
|
||||
LEFT JOIN public.tbl_student ON student_benutzer.uid = public.tbl_student.student_uid
|
||||
LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
|
||||
LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
|
||||
LEFT JOIN public.tbl_studiengang ON public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
|
||||
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
|
||||
LEFT JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id)
|
||||
LEFT JOIN primary_betreuer pb ON pb.projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
LEFT JOIN secondary_betreuer sb ON sb.projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
WHERE (projekttyp_kurzbz='Bachelor' OR projekttyp_kurzbz='Diplom')
|
||||
AND (pb.betreuer_person_id = ? OR sb.zweitbetreuer_person_id = ?)
|
||||
".($showAll?'':' AND student_benutzer.aktiv AND lehre.tbl_projektarbeit.note IS NULL ')."
|
||||
AND betreuerart_kurzbz IN ('Betreuer', 'Begutachter', 'Erstbegutachter', 'Zweitbegutachter', 'Erstbetreuer', 'Senatsvorsitz', 'Senatsmitglied')
|
||||
ORDER BY tbl_projektarbeit.projektarbeit_id, betreuerart_kurzbz desc) as xy
|
||||
ORDER BY tbl_projektarbeit.projektarbeit_id, betreuerart_kurzbz desc) as xy
|
||||
ORDER BY nachname;";
|
||||
|
||||
return $this->execReadOnlyQuery($qry, array($uid));
|
||||
return $this->execReadOnlyQuery($qry, array($person_id, $person_id));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -449,7 +564,7 @@ class Projektarbeit_model extends DB_Model
|
||||
LEFT JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id)
|
||||
LEFT JOIN public.tbl_person betreuer_person ON betreuer_person.person_id = lehre.tbl_projektbetreuer.person_id
|
||||
LEFT JOIN public.tbl_benutzer betreuer_benutzer ON betreuer_person.person_id = betreuer_benutzer.person_id
|
||||
LEFT JOIN secondary_betreuer sb ON sb.projektarbeit_id = tbl_projektarbeit.projektarbeit_id -- ← THE NEW LINE
|
||||
LEFT JOIN secondary_betreuer sb ON sb.projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
|
||||
WHERE (projekttyp_kurzbz = 'Bachelor' OR projekttyp_kurzbz = 'Diplom')
|
||||
AND student_benutzer.aktiv
|
||||
@@ -469,6 +584,129 @@ class Projektarbeit_model extends DB_Model
|
||||
|
||||
return $this->execReadOnlyQuery($new_qry, array($studiengang_kz));
|
||||
}
|
||||
|
||||
public function getProjektarbeitenForStudent($student_uid) {
|
||||
$new_qry = "WITH secondary_betreuer AS (
|
||||
SELECT DISTINCT ON (pb.projektarbeit_id)
|
||||
pb.projektarbeit_id,
|
||||
pb.person_id AS zweitbetreuer_person_id,
|
||||
pb.betreuerart_kurzbz AS zweitbetreuer_betreuerart_kurzbz,
|
||||
ba.beschreibung AS zweitbetreuer_betreuerart_beschreibung,
|
||||
p.titelpre AS zweitbetreuer_titelpre,
|
||||
p.vorname AS zweitbetreuer_vorname,
|
||||
p.nachname AS zweitbetreuer_nachname,
|
||||
p.titelpost AS zweitbetreuer_titelpost,
|
||||
trim(
|
||||
COALESCE(p.titelpre, '') || ' ' ||
|
||||
COALESCE(p.vorname, '') || ' ' ||
|
||||
COALESCE(p.nachname, '') || ' ' ||
|
||||
COALESCE(p.titelpost, '')
|
||||
) AS zweitbetreuer_full_name
|
||||
FROM lehre.tbl_projektbetreuer pb
|
||||
JOIN public.tbl_person p ON p.person_id = pb.person_id
|
||||
LEFT JOIN public.tbl_benutzer b ON b.person_id = p.person_id
|
||||
LEFT JOIN lehre.tbl_betreuerart ba ON ba.betreuerart_kurzbz = pb.betreuerart_kurzbz
|
||||
WHERE pb.betreuerart_kurzbz = ANY('{Zweitbetreuer,Zweitbegutachter,Senatsmitglied}')
|
||||
ORDER BY pb.projektarbeit_id -- DISTINCT ON needs this to be deterministic
|
||||
)
|
||||
|
||||
SELECT DISTINCT ON (tmp.projektarbeit_id)
|
||||
*,
|
||||
campus.get_betreuer_details(tmp.zweitbetreuer_person_id) AS zweitbetreuer_full_name,
|
||||
campus.get_betreuer_details(tmp.betreuer_person_id) AS erstbetreuer_full_name
|
||||
FROM (
|
||||
SELECT DISTINCT ON (tbl_projektarbeit.projektarbeit_id)
|
||||
tbl_projektarbeit.projekttyp_kurzbz,
|
||||
tbl_projektarbeit.titel,
|
||||
tbl_projektarbeit.projektarbeit_id,
|
||||
tbl_studiengang.typ,
|
||||
tbl_studiengang.kurzbz,
|
||||
student_benutzer.uid AS student_uid,
|
||||
student_person.vorname AS student_vorname,
|
||||
student_person.nachname AS student_nachname,
|
||||
public.tbl_student.matrikelnr,
|
||||
tbl_lehreinheit.studiensemester_kurzbz,
|
||||
betreuer_benutzer.uid AS betreuer_benutzer_uid,
|
||||
betreuer_person.titelpre AS betreuer_titelpre,
|
||||
betreuer_person.vorname AS betreuer_vorname,
|
||||
betreuer_person.nachname AS betreuer_nachname,
|
||||
betreuer_person.titelpost AS betreuer_titelpost,
|
||||
lehre.tbl_projektbetreuer.betreuerart_kurzbz AS betreuerart,
|
||||
lehre.tbl_projektbetreuer.person_id AS betreuer_person_id,
|
||||
lehre.tbl_projektarbeit.sprache,
|
||||
lehre.tbl_projektarbeit.seitenanzahl,
|
||||
lehre.tbl_projektarbeit.kontrollschlagwoerter,
|
||||
lehre.tbl_projektarbeit.schlagwoerter,
|
||||
lehre.tbl_projektarbeit.schlagwoerter_en,
|
||||
lehre.tbl_projektarbeit.abstract,
|
||||
lehre.tbl_projektarbeit.abstract_en,
|
||||
lehre.tbl_projektarbeit.insertamum,
|
||||
lehre.tbl_projektarbeit.note,
|
||||
|
||||
sb.zweitbetreuer_person_id,
|
||||
sb.zweitbetreuer_betreuerart_kurzbz,
|
||||
sb.zweitbetreuer_betreuerart_beschreibung,
|
||||
sb.zweitbetreuer_full_name,
|
||||
sb.zweitbetreuer_titelpre,
|
||||
sb.zweitbetreuer_vorname,
|
||||
sb.zweitbetreuer_nachname,
|
||||
sb.zweitbetreuer_titelpost,
|
||||
|
||||
(
|
||||
SELECT orgform_kurzbz
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE prestudent_id = (
|
||||
SELECT prestudent_id FROM public.tbl_student
|
||||
WHERE student_uid = student_benutzer.uid LIMIT 1
|
||||
)
|
||||
ORDER BY datum DESC, insertamum DESC, ext_id DESC
|
||||
LIMIT 1
|
||||
) AS organisationsform,
|
||||
(
|
||||
SELECT COALESCE(tbl_studienplan.orgform_kurzbz,
|
||||
tbl_prestudentstatus.orgform_kurzbz,
|
||||
tbl_studiengang.orgform_kurzbz)
|
||||
FROM public.tbl_prestudent
|
||||
JOIN public.tbl_prestudentstatus USING (prestudent_id)
|
||||
JOIN public.tbl_studiensemester USING (studiensemester_kurzbz)
|
||||
JOIN public.tbl_studiengang USING (studiengang_kz)
|
||||
LEFT JOIN lehre.tbl_studienplan USING (studienplan_id)
|
||||
WHERE prestudent_id = public.tbl_student.prestudent_id
|
||||
ORDER BY tbl_prestudentstatus.datum DESC
|
||||
LIMIT 1
|
||||
) AS orgform,
|
||||
(
|
||||
SELECT status_kurzbz
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE prestudent_id = public.tbl_student.prestudent_id
|
||||
ORDER BY datum DESC, insertamum DESC, ext_id DESC
|
||||
LIMIT 1
|
||||
) AS studienstatus
|
||||
|
||||
FROM lehre.tbl_projektarbeit
|
||||
LEFT JOIN public.tbl_benutzer student_benutzer ON student_benutzer.uid = lehre.tbl_projektarbeit.student_uid
|
||||
LEFT JOIN public.tbl_person student_person ON student_benutzer.person_id = student_person.person_id
|
||||
LEFT JOIN public.tbl_student ON student_benutzer.uid = public.tbl_student.student_uid
|
||||
LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
|
||||
LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
|
||||
LEFT JOIN public.tbl_studiengang ON public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
|
||||
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
|
||||
LEFT JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id)
|
||||
LEFT JOIN public.tbl_person betreuer_person ON betreuer_person.person_id = lehre.tbl_projektbetreuer.person_id
|
||||
LEFT JOIN public.tbl_benutzer betreuer_benutzer ON betreuer_person.person_id = betreuer_benutzer.person_id
|
||||
LEFT JOIN secondary_betreuer sb ON sb.projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
|
||||
WHERE (projekttyp_kurzbz = 'Bachelor' OR projekttyp_kurzbz = 'Diplom')
|
||||
AND student_benutzer.aktiv
|
||||
AND lehre.tbl_projektbetreuer.betreuerart_kurzbz IN (
|
||||
'Erstbegutachter', 'Begutachter', 'Betreuer', 'Erstbetreuer', 'Senatsvorsitz'
|
||||
)
|
||||
AND public.tbl_student.student_uid = ?
|
||||
ORDER BY tbl_projektarbeit.projektarbeit_id DESC, student_person.nachname ASC
|
||||
) as tmp";
|
||||
|
||||
return $this->execReadOnlyQuery($new_qry, array($student_uid));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
||||
@@ -396,3 +396,13 @@
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.p-timeline-event-opposite {
|
||||
flex: 0 0 90px;
|
||||
max-width: 90px;
|
||||
}
|
||||
|
||||
.p-timeline-event-content {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@@ -161,6 +161,22 @@ export default {
|
||||
url: '/api/frontend/v1/Abgabe/postStudentProjektarbeitTitel',
|
||||
params: {projektarbeit_id, titel},
|
||||
|
||||
};
|
||||
},
|
||||
sendZweitbetreuerTokenMail(projektarbeit_id, betreuer_person_id, student_uid) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Abgabe/sendZweitbetreuerTokenMail',
|
||||
params: {projektarbeit_id, bperson_id: betreuer_person_id, student_uid},
|
||||
|
||||
};
|
||||
},
|
||||
fetchProjektarbeitenHistory(student_uid) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Abgabe/fetchProjektarbeitenHistory',
|
||||
params: {student_uid},
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -2,7 +2,8 @@ import BsModal from '../../Bootstrap/Modal.js';
|
||||
import VueDatePicker from '../../vueDatepicker.js.php';
|
||||
import ApiAbgabe from '../../../api/factory/abgabe.js'
|
||||
import { getDateStyleClass } from "./getDateStyleClass.js";
|
||||
import { compareISODateValues, formatISODate, getViennaTodayISO } from "./dateUtils.js";
|
||||
import {compareISODateValues, formatDateTime, formatISODate, getViennaTodayISO} from "./dateUtils.js";
|
||||
|
||||
|
||||
export const AbgabeMitarbeiterDetail = {
|
||||
name: "AbgabeMitarbeiterDetail",
|
||||
@@ -77,6 +78,19 @@ export const AbgabeMitarbeiterDetail = {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getSavedTerminInfoString(termin) {
|
||||
const isUpdate = termin.updateamum != null;
|
||||
|
||||
const fullname = isUpdate
|
||||
? termin.updatevon_fullname
|
||||
: termin.insertvon_fullname;
|
||||
|
||||
const datetime = isUpdate
|
||||
? termin.updateamum
|
||||
: termin.insertamum;
|
||||
|
||||
return this.$p.t('ui/savedAtByV3', [formatDateTime(datetime), fullname])
|
||||
},
|
||||
terminIsInvalid(termin) {
|
||||
return termin.note?.positiv == false && !termin.beurteilungsnotiz
|
||||
},
|
||||
@@ -817,7 +831,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
<div class="col-12 col-md-9">
|
||||
<Dropdown
|
||||
:style="{'width': '100%'}"
|
||||
:disabled="!termin.allowedToSave"
|
||||
:disabled="!termin.allowedToSave || termin.abgabedatum !== null || termin.noteBackend"
|
||||
:placeholder="getPlaceholderTermin(termin)"
|
||||
v-model="termin.bezeichnung"
|
||||
@change="handleChangeAbgabetyp(termin)"
|
||||
@@ -905,7 +919,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
<div class="col-12 col-md-3 fw-bold align-content-center">
|
||||
{{ $capitalize( $p.t('abgabetool/c4actions') )}}
|
||||
</div>
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="col-12 col-md-5">
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<button v-if="termin.allowedToSave && !terminIsInvalid(termin)" style="max-height: 40px;" class="btn btn-primary border-0" @click="saveTermin(termin)">
|
||||
@@ -933,6 +947,9 @@ export const AbgabeMitarbeiterDetail = {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 align-content-center text-end text-muted small">
|
||||
{{getSavedTerminInfoString(termin)}}
|
||||
</div>
|
||||
</div>
|
||||
</AccordionTab>
|
||||
</template>
|
||||
|
||||
@@ -410,7 +410,7 @@ export const AbgabeStudentDetail = {
|
||||
|
||||
<div v-if="projektarbeit">
|
||||
|
||||
<h5>{{$capitalize( $p.t('abgabetool/c4abgabeStudentenbereich') )}}</h5>
|
||||
<h5>{{$capitalize( $p.t('abgabetool/c4abgabeStudentenbereichv2') )}}</h5>
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<p>{{$capitalize( $p.t('person/student') ) }}: {{projektarbeit?.student}}</p>
|
||||
@@ -658,7 +658,7 @@ export const AbgabeStudentDetail = {
|
||||
</label>
|
||||
<Textarea
|
||||
v-model="editingTitel"
|
||||
rows="10"
|
||||
rows="2"
|
||||
maxlength="1024"
|
||||
class="form-control w-100"
|
||||
@keydown.enter.prevent="saveTitel"
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
import AbgabeterminStatusLegende from "./StatusLegende.js";
|
||||
import {formatDateTime} from "./dateUtils.js";
|
||||
|
||||
export const AbgabeStudentTimeline = {
|
||||
name: "AbgabeStudentTimeline",
|
||||
components: {
|
||||
AbgabeterminStatusLegende,
|
||||
Timeline: primevue.timeline,
|
||||
},
|
||||
props: {
|
||||
projekte: { type: Array, default: () => [] },
|
||||
notenOptions: { type: Array, default: () => [] },
|
||||
formatDateFn: { type: Function, required: true }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
legendExpanded: false,
|
||||
expandedProjects: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
student() {
|
||||
return this.projekte?.[0] ?? null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
projekte: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
// open all projects by default whenever the student changes
|
||||
const state = {}
|
||||
val?.forEach(p => { state[p.projektarbeit_id] = true })
|
||||
this.expandedProjects = state
|
||||
this.legendExpanded = false
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getNoteBezeichnung(projektarbeit) {
|
||||
if(projektarbeit.note && this.notenOptions) {
|
||||
const noteOpt = this.notenOptions.find(opt => opt.note == projektarbeit.note)
|
||||
return noteOpt?.bezeichnung
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
},
|
||||
getSavedTerminInfoString(termin) {
|
||||
const isUpdate = termin.updateamum != null;
|
||||
|
||||
const fullname = isUpdate
|
||||
? termin.updatevon_fullname
|
||||
: termin.insertvon_fullname;
|
||||
|
||||
const datetime = isUpdate
|
||||
? termin.updateamum
|
||||
: termin.insertamum;
|
||||
|
||||
return this.$p.t('ui/savedAtByV3', [formatDateTime(datetime), fullname])
|
||||
},
|
||||
getItemBezeichnung(item) {
|
||||
if (!item?.bezeichnung) return ''
|
||||
return item.bezeichnung?.bezeichnung ?? item.bezeichnung
|
||||
},
|
||||
getItemNote(item) {
|
||||
if (!item?.note) return ''
|
||||
if (item.note?.bezeichnung) return item.note.bezeichnung
|
||||
return this.notenOptions?.find(n => n.note == item.note)?.bezeichnung ?? String(item.note)
|
||||
},
|
||||
getIconClass(dateStyle) {
|
||||
return ({
|
||||
verspaetet: 'fa-solid fa-triangle-exclamation',
|
||||
verpasst: 'fa-solid fa-calendar-xmark',
|
||||
abzugeben: 'fa-solid fa-hourglass-half',
|
||||
standard: 'fa-solid fa-clock',
|
||||
abgegeben: 'fa-solid fa-paperclip',
|
||||
beurteilungerforderlich: 'fa-solid fa-list-check',
|
||||
bestanden: 'fa-solid fa-check',
|
||||
nichtbestanden: 'fa-solid fa-circle-exclamation',
|
||||
})[dateStyle] ?? ''
|
||||
},
|
||||
getBetreuerLabel(projekt) {
|
||||
return projekt.erstbetreuer_full_name
|
||||
|| (projekt.betreuer_vorname ? `${projekt.betreuer_vorname} ${projekt.betreuer_nachname}`.trim() : null)
|
||||
},
|
||||
toggleProject(id) {
|
||||
this.expandedProjects[id] = !this.expandedProjects[id]
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div v-if="student">
|
||||
|
||||
<div class="d-flex align-items-baseline gap-2 mb-3 pb-2 border-bottom">
|
||||
<span class="fw-bold fs-6">{{ student.student_vorname }} {{ student.student_nachname }}</span>
|
||||
<span class="text-muted small">{{ student.student_uid }}</span>
|
||||
<span v-if="student.matrikelnr" class="text-muted small ms-auto">{{ student.matrikelnr }}</span>
|
||||
</div>
|
||||
|
||||
<div v-for="projekt in projekte" :key="projekt.projektarbeit_id" class="mb-2">
|
||||
|
||||
<button
|
||||
class="btn btn-sm w-100 text-start d-flex align-items-center gap-2 rounded bg-light border-0 py-2 px-3"
|
||||
@click="toggleProject(projekt.projektarbeit_id)"
|
||||
>
|
||||
<i
|
||||
:class="expandedProjects[projekt.projektarbeit_id] ? 'fa-solid fa-chevron-down' : 'fa-solid fa-chevron-right'"
|
||||
style="width: 12px; flex-shrink: 0;"
|
||||
></i>
|
||||
<span class="fw-semibold text-truncate flex-grow-1" :title="projekt.titel">
|
||||
{{ projekt.titel || projekt.projekttyp_kurzbz || projekt.projektarbeit_id }}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-if="projekt.note"
|
||||
class="small fw-semibold mx-2 flex-shrink-0"
|
||||
>
|
||||
{{ getNoteBezeichnung(projekt) }}
|
||||
</span>
|
||||
|
||||
<span class="text-muted small me-1 flex-shrink-0">{{ projekt.studiensemester_kurzbz }}</span>
|
||||
<span class="badge bg-secondary flex-shrink-0">{{ projekt.abgabetermine?.length ?? 0 }}</span>
|
||||
</button>
|
||||
|
||||
<div v-show="expandedProjects[projekt.projektarbeit_id]" class="px-2 pt-1">
|
||||
|
||||
<div v-if="getBetreuerLabel(projekt)" class="text-muted small px-1 mb-2">
|
||||
{{ projekt.betreuerart || $capitalize($p.t('abgabetool/c4erstbetreuerv2')) }}:
|
||||
{{ getBetreuerLabel(projekt) }}
|
||||
</div>
|
||||
|
||||
<Timeline :value="projekt.abgabetermine" align="right">
|
||||
|
||||
<template #marker="slotProps">
|
||||
<!-- padding:0 overrides the 34px accordion left-padding from the -header CSS class -->
|
||||
<div
|
||||
:class="slotProps.item.dateStyle + '-header'"
|
||||
style="height: 26px; width: 26px; padding: 0; border-radius: 4px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;"
|
||||
>
|
||||
<i :class="getIconClass(slotProps.item.dateStyle)" style="font-size: 0.75rem;"></i>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #opposite="slotProps">
|
||||
<div class="text-end small text-nowrap text-muted">
|
||||
{{ formatDateFn(slotProps.item.datum) }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #content="slotProps">
|
||||
<div class="small pb-1">
|
||||
|
||||
<div class="d-flex align-items-center gap-1 fw-semibold">
|
||||
|
||||
<div
|
||||
:class="slotProps.item.dateStyle + '-header'"
|
||||
style="height:20px;width:20px;padding:0;border-radius:3px;display:flex;align-items:center;justify-content:center;flex-shrink:0;"
|
||||
>
|
||||
<i :class="getIconClass(slotProps.item.dateStyle)" style="font-size:.65rem;"></i>
|
||||
</div>
|
||||
|
||||
<span>
|
||||
{{ getItemBezeichnung(slotProps.item) }}
|
||||
</span>
|
||||
|
||||
<i
|
||||
v-if="slotProps.item.fixtermin"
|
||||
class="fa-solid fa-lock text-muted"
|
||||
title="Fixtermin"
|
||||
></i>
|
||||
|
||||
<i
|
||||
v-if="slotProps.item.abgabedatum"
|
||||
class="fa-solid fa-file text-muted"
|
||||
:title="$capitalize($p.t('abgabetool/c4abgabedatum'))"
|
||||
></i>
|
||||
|
||||
<div class="flex-grow-1 text-end">
|
||||
<span
|
||||
v-if="slotProps.item.noteBackend?.bezeichnung"
|
||||
class="fw-bold"
|
||||
>
|
||||
{{ slotProps.item.noteBackend?.positiv
|
||||
? $capitalize($p.t('abgabetool/c4positivBenotet'))
|
||||
: $capitalize($p.t('abgabetool/c4negativBenotet'))
|
||||
}}
|
||||
</span>
|
||||
|
||||
<span
|
||||
v-else-if="slotProps.item.bezeichnung?.benotbar"
|
||||
class="fw-bold text-muted"
|
||||
>
|
||||
{{ $capitalize($p.t('abgabetool/c4notYetGraded')) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="slotProps.item.kurzbz"
|
||||
class="text-muted fst-italic ms-4"
|
||||
>
|
||||
{{ slotProps.item.kurzbz }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="slotProps.item.abgabedatum"
|
||||
class="small text-muted ms-4"
|
||||
>
|
||||
{{ $capitalize($p.t('abgabetool/c4abgabedatum')) }}:
|
||||
{{ formatDateFn(slotProps.item.abgabedatum) }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="slotProps.item.beurteilungsnotiz"
|
||||
class="small ms-4 mt-1 text-muted"
|
||||
>
|
||||
{{ slotProps.item.beurteilungsnotiz }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="slotProps.item.insertamum"
|
||||
class="small text-muted ms-4 mt-1"
|
||||
style="font-size: .72rem;"
|
||||
>
|
||||
<i class="fa-solid fa-clock-rotate-left me-1"></i>
|
||||
{{ getSavedTerminInfoString(slotProps.item) }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</Timeline>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3 border-top pt-2">
|
||||
<button
|
||||
class="btn btn-link btn-sm p-0 text-muted text-decoration-none d-flex align-items-center gap-1"
|
||||
@click="legendExpanded = !legendExpanded"
|
||||
>
|
||||
<i :class="legendExpanded ? 'fa-solid fa-chevron-up' : 'fa-solid fa-chevron-down'" style="font-size: 0.7rem;"></i>
|
||||
Legende
|
||||
</button>
|
||||
<div v-show="legendExpanded" class="mt-2">
|
||||
<AbgabeterminStatusLegende />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
export default AbgabeStudentTimeline;
|
||||
@@ -7,15 +7,17 @@ import ApiAbgabe from '../../../api/factory/abgabe.js'
|
||||
import ApiStudiensemester from '../../../api/factory/studiensemester.js';
|
||||
import AbgabeterminStatusLegende from "./StatusLegende.js";
|
||||
import FhcOverlay from "../../Overlay/FhcOverlay.js";
|
||||
import AbgabeStudentTimeline from "./AbgabeStudentTimeline.js";
|
||||
import { splitMailsHelper } from "../../../helpers/EmailHelpers.js"
|
||||
import { getDateStyleClass} from "./getDateStyleClass.js";
|
||||
import { dateFilter } from '../../../tabulator/filters/Dates.js';
|
||||
import { dateFilter } from '../../../tabulator/filters/DatesManual.js';
|
||||
import { compareISODateValues, formatISODate, getViennaTodayISO, toViennaDate } from "./dateUtils.js";
|
||||
|
||||
export const AbgabetoolAssistenz = {
|
||||
name: "AbgabetoolAssistenz",
|
||||
components: {
|
||||
AbgabeterminStatusLegende,
|
||||
AbgabeStudentTimeline,
|
||||
BsModal,
|
||||
BsOffcanvas,
|
||||
CoreFilterCmpt,
|
||||
@@ -76,7 +78,7 @@ export const AbgabetoolAssistenz = {
|
||||
colLayoutRestoredFlat: false,
|
||||
sortRestoredFlat: false,
|
||||
stateRestoredFlat: false,
|
||||
timelineProjekt: null,
|
||||
timelineProjekte: [],
|
||||
selectedStudiengangOption: null,
|
||||
studiengaengeOptions: null,
|
||||
detailIsFullscreen: false,
|
||||
@@ -209,7 +211,7 @@ export const AbgabetoolAssistenz = {
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4orgformv2'))), field: 'orgform', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 50, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4projekttyp'))), field: 'projekttyp_kurzbz', formatter: this.centeredTextFormatter, minWidth: 150, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4stg'))), field: 'stg', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 50, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4note'))), field: 'note_bez', headerFilter: true, visible: false, minWidth: 200, formatter: this.centeredTextFormatter},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4note'))), field: 'note_bez', headerFilter: true, sorter: this.notenSorter, visible: false, minWidth: 200, formatter: this.centeredTextFormatter},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4sem'))), field: 'studiensemester_kurzbz', headerFilter: true, visible: false, formatter: this.centeredTextFormatter, minWidth: 100},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4titel'))), field: 'titel', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4erstbetreuerv2'))), field: 'erstbetreuer', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
@@ -431,6 +433,7 @@ export const AbgabetoolAssistenz = {
|
||||
if (!val) return '';
|
||||
return val?.bezeichnung ?? this.notenOptions?.find(n => n.note == val)?.bezeichnung ?? val;
|
||||
},
|
||||
sorter: this.notenSorterFlat,
|
||||
minWidth: 100,
|
||||
tooltip: false,
|
||||
headerFilter: this.notenHeaderFilterEditor,
|
||||
@@ -519,6 +522,18 @@ export const AbgabetoolAssistenz = {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
notenSorterFlat(a, b, aRow, bRow, column, dir, sorterParams) {
|
||||
// flat table has their own sort since the field is called sligthly different in that context
|
||||
// since note would be bestanden/nicht bestanden and that hardly needs sorting
|
||||
const aData = aRow.getData()
|
||||
const bData = bRow.getData()
|
||||
return aData.pa_note - bData.pa_note
|
||||
},
|
||||
notenSorter(a, b, aRow, bRow, column, dir, sorterParams) {
|
||||
const aData = aRow.getData()
|
||||
const bData = bRow.getData()
|
||||
return aData.note - bData.note
|
||||
},
|
||||
notenHeaderFilterEditor(cell, onRendered, success, cancel, editorParams) {
|
||||
if (!this.notenOptions) return;
|
||||
|
||||
@@ -611,7 +626,7 @@ export const AbgabetoolAssistenz = {
|
||||
return filterVal.some(val => val == noteId); // loose equality: filter vals are numbers, noteId might be string
|
||||
},
|
||||
handleFilterActiveChanged(active) {
|
||||
if(!active && this.allSemOption) {
|
||||
if(!active && this.allSemOption && this.stateRestored) {
|
||||
this.curSem = this.allSemOption
|
||||
}
|
||||
},
|
||||
@@ -1361,6 +1376,11 @@ export const AbgabetoolAssistenz = {
|
||||
// calculate Abgabetermin time diff to now and assign last and next to projekt
|
||||
projekt.abgabetermine.forEach(termin => {
|
||||
|
||||
// only set this if it has not been set yet and abgabetermin has a note (qgate)
|
||||
if(!termin.noteBackend && termin.note) {
|
||||
termin.noteBackend = termin.note
|
||||
}
|
||||
|
||||
termin.bezeichnung = this.abgabeTypeOptions.find(opt => opt.paabgabetyp_kurzbz === termin.paabgabetyp_kurzbz)
|
||||
|
||||
// while already looping through each termin, calculate datestyle beforehand
|
||||
@@ -1778,7 +1798,8 @@ export const AbgabetoolAssistenz = {
|
||||
if(this.notenOptions && projekt.note) {
|
||||
const opt = this.notenOptions.find(n => n.note == projekt.note)
|
||||
|
||||
// TODO: mehrsprachig englisch
|
||||
// TODO: mehrsprachig englisch -> nevermind the english field in
|
||||
// notenoption->bezeichnung_mehrsprachig is ALWAYS german
|
||||
projekt.note_bez = opt.bezeichnung
|
||||
}
|
||||
|
||||
@@ -1851,20 +1872,17 @@ export const AbgabetoolAssistenz = {
|
||||
if(typeof termin.note !== 'object') {
|
||||
termin.note = this.allowedNotenOptions.find(opt => opt.note == termin.note)
|
||||
}
|
||||
|
||||
// only set this if it has not been set yet and abgabetermin has a note (qgate)
|
||||
if(!termin.noteBackend && termin.note) {
|
||||
termin.noteBackend = termin.note
|
||||
}
|
||||
|
||||
termin.file = []
|
||||
|
||||
// assistenz should be able to edit every abgabe
|
||||
// update 21-01-2026: actually blocking operations on finished projektarbeiten seems like a decent idea
|
||||
const terminHasAbgabe = termin.abgabedatum != null
|
||||
const terminHasNote = termin.noteBackend
|
||||
termin.allowedToSave = paIsBenotet ? false : true
|
||||
|
||||
// assistenz are not allowed to delete deadlines with existing submissions
|
||||
termin.allowedToDelete = paIsBenotet ? false : !termin.abgabedatum && !termin.note
|
||||
termin.allowedToDelete = paIsBenotet || terminHasNote || terminHasAbgabe ? false : true
|
||||
|
||||
})
|
||||
|
||||
@@ -1876,21 +1894,54 @@ export const AbgabetoolAssistenz = {
|
||||
this.$refs.modalContainerAbgabeDetail.show()
|
||||
},
|
||||
openTimeline(val) {
|
||||
const projekt = this.projektarbeiten.find(p => p.projektarbeit_id == val.projektarbeit_id)
|
||||
if(!projekt) {
|
||||
|
||||
this.$api.call(ApiAbgabe.fetchProjektarbeitenHistory(val.student_uid)).then(res => {
|
||||
console.log(res)
|
||||
|
||||
this.$fhcAlert.alertInfo('Keine projektarbeit gefunden')
|
||||
|
||||
return
|
||||
}
|
||||
projekt.abgabetermine.forEach(termin => {
|
||||
// show note only on termine with abgabetypen which are benotbar
|
||||
const terminTypOpt = this.abgabeTypeOptions.find(opt => opt.paabgabetyp_kurzbz == termin.paabgabetyp_kurzbz)
|
||||
termin.benotbar = terminTypOpt.benotbar
|
||||
res.data.forEach(projekt => {
|
||||
projekt.abgabetermine?.forEach(termin => {
|
||||
// only set this if it has not been set yet and abgabetermin has a note (qgate)
|
||||
if(!termin.noteBackend && termin.note) {
|
||||
termin.noteBackend = this.notenOptions.find(opt => termin.note == opt.note)
|
||||
}
|
||||
|
||||
termin.dateStyle = getDateStyleClass(termin, this.notenOptions)
|
||||
|
||||
const terminTypOpt = this.abgabeTypeOptions.find(opt => opt.paabgabetyp_kurzbz == termin.paabgabetyp_kurzbz)
|
||||
if (terminTypOpt) termin.benotbar = terminTypOpt.benotbar
|
||||
})
|
||||
})
|
||||
|
||||
// keep the history API stub for future use
|
||||
|
||||
|
||||
this.timelineProjekte = res.data
|
||||
this.$refs.drawer.show()
|
||||
})
|
||||
this.timelineProjekt = projekt
|
||||
this.$refs.drawer.show()
|
||||
},
|
||||
// openTimeline(val) {
|
||||
//
|
||||
// this.$api.call(ApiAbgabe.fetchProjektarbeitenHistory(val.student_uid)).then(res => {
|
||||
// console.log(res)
|
||||
// })
|
||||
//
|
||||
// const projekt = this.projektarbeiten.find(p => p.projektarbeit_id == val.projektarbeit_id)
|
||||
// if(!projekt) {
|
||||
//
|
||||
// this.$fhcAlert.alertInfo('Keine projektarbeit gefunden')
|
||||
//
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// projekt.abgabetermine.forEach(termin => {
|
||||
// // show note only on termine with abgabetypen which are benotbar
|
||||
// const terminTypOpt = this.abgabeTypeOptions.find(opt => opt.paabgabetyp_kurzbz == termin.paabgabetyp_kurzbz)
|
||||
// termin.benotbar = terminTypOpt.benotbar
|
||||
// })
|
||||
//
|
||||
// this.timelineProjekt = projekt
|
||||
// this.$refs.drawer.show()
|
||||
// },
|
||||
paabgabetypFormatter(cell) {
|
||||
const key = cell.getValue()
|
||||
return this.$p.t('abgabetool/c4paatyp' + key)
|
||||
@@ -2100,8 +2151,14 @@ export const AbgabetoolAssistenz = {
|
||||
if (!this.projektarbeiten) return [];
|
||||
return this.projektarbeiten.flatMap(pa =>
|
||||
pa.abgabetermine.map(termin => {
|
||||
const allowedToSave = pa.note !== null ? false : true
|
||||
const allowedToDelete = pa.note !== null ? false : !termin.abgabedatum && !termin.note
|
||||
const terminHasAbgabe = termin.abgabedatum != null
|
||||
const terminHasNote = termin.noteBackend
|
||||
|
||||
// IN multiedit changing anything for a termin with an existing note is not allowed anymore, to avoid
|
||||
// confusing UX behaviour why some fields could be edited and others not -> just edit in detail view
|
||||
const allowedToSave = pa.note !== null || terminHasNote || terminHasAbgabe ? false : true
|
||||
const allowedToDelete = pa.note !== null || terminHasNote || terminHasAbgabe ? false : true
|
||||
|
||||
return {
|
||||
allowedToSave,
|
||||
allowedToDelete,
|
||||
@@ -2554,102 +2611,11 @@ export const AbgabetoolAssistenz = {
|
||||
{{ $p.t('abgabetool/c4projektarbeitTimelineTitle') }}
|
||||
</template>
|
||||
|
||||
<div class="row" style="margin-bottom: 12px;">
|
||||
<Inplace
|
||||
closable
|
||||
:closeButtonProps="{
|
||||
style: {
|
||||
position: 'absolute',
|
||||
top: '80px',
|
||||
right: '80px',
|
||||
zIndex: 1
|
||||
}
|
||||
}"
|
||||
>
|
||||
<template #display> {{ $capitalize($p.t('abgabetool/showStudentDetails'))}} </template>
|
||||
<template #content>
|
||||
<div class="col-auto">
|
||||
<div class="row">
|
||||
<div class="col-3">Student: </div>
|
||||
<div class="col-7">{{timelineProjekt?.student_vorname}} {{timelineProjekt?.student_nachname}}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3">Uid: </div>
|
||||
<div class="col-7">{{timelineProjekt?.student_uid}}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3">{{timelineProjekt?.betreuerart}}: </div>
|
||||
<div class="col-7">{{timelineProjekt?.erstbetreuer_full_name}}</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-3">Titel: </div>
|
||||
<div class="col-7">{{timelineProjekt?.titel}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Inplace>
|
||||
</div>
|
||||
|
||||
<Timeline
|
||||
:value="timelineProjekt?.abgabetermine"
|
||||
align="right"
|
||||
>
|
||||
<template #marker="slotProps">
|
||||
<div :class="slotProps.item.dateStyle + '-header'" style="height: 48px; width:48px; padding: 0px; display: flex; align-items: center; justify-content: center;">
|
||||
<i v-if="slotProps.item.dateStyle == 'verspaetet'" class="fa-solid fa-triangle-exclamation"></i>
|
||||
<i v-else-if="slotProps.item.dateStyle == 'verpasst'" class="fa-solid fa-calendar-xmark"></i>
|
||||
<i v-else-if="slotProps.item.dateStyle == 'abzugeben'" class="fa-solid fa-hourglass-half"></i>
|
||||
<i v-else-if="slotProps.item.dateStyle == 'standard'" class="fa-solid fa-clock"></i>
|
||||
<i v-else-if="slotProps.item.dateStyle == 'abgegeben'" class="fa-solid fa-paperclip"></i>
|
||||
<i v-else-if="slotProps.item.dateStyle == 'beurteilungerforderlich'" class="fa-solid fa-list-check"></i>
|
||||
<i v-else-if="slotProps.item.dateStyle == 'bestanden'" class="fa-solid fa-check"></i>
|
||||
<i v-else-if="slotProps.item.dateStyle == 'nichtbestanden'" class="fa-solid fa-circle-exclamation"></i>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #opposite="slotProps">
|
||||
<div class="row g-1">
|
||||
<div class="col-5 fw-semibold text-end">
|
||||
{{ $capitalize($p.t('abgabetool/c4zieldatumv2')) }}:
|
||||
</div>
|
||||
<div class="col-7">
|
||||
{{ formatDate(slotProps.item.datum) }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #content="slotProps">
|
||||
<div class="row g-1">
|
||||
<div class="col-5 fw-semibold text-end">
|
||||
{{ $capitalize($p.t('abgabetool/c4abgabetyp')) }}:
|
||||
</div>
|
||||
<div class="col-7">
|
||||
{{ getItemBezeichnung(slotProps.item) }}
|
||||
</div>
|
||||
|
||||
<div class="col-5 fw-semibold text-end">
|
||||
{{ $capitalize($p.t('abgabetool/c4abgabedatum')) }}:
|
||||
</div>
|
||||
<div class="col-7">
|
||||
{{ formatDate(slotProps.item.abgabedatum) }}
|
||||
</div>
|
||||
|
||||
<div v-if="slotProps.item.benotbar" class="col-5 fw-semibold text-end">
|
||||
{{ $capitalize($p.t('abgabetool/c4note')) }}:
|
||||
</div>
|
||||
<div v-if="slotProps.item.benotbar" class="col-7">
|
||||
{{ getItemNote(slotProps.item) }}
|
||||
</div>
|
||||
</div>
|
||||
<hr/>
|
||||
</template>
|
||||
|
||||
</Timeline>
|
||||
|
||||
<template #footer>
|
||||
<AbgabeterminStatusLegende></AbgabeterminStatusLegende>
|
||||
</template>
|
||||
<AbgabeStudentTimeline
|
||||
:projekte="timelineProjekte"
|
||||
:notenOptions="notenOptions"
|
||||
:formatDateFn="formatDate"
|
||||
/>
|
||||
</BsOffcanvas>
|
||||
|
||||
<div id="abgabetable" style="max-height:40vw;">
|
||||
@@ -2713,6 +2679,7 @@ export const AbgabetoolAssistenz = {
|
||||
>
|
||||
<template #actions>
|
||||
<Dropdown
|
||||
v-if="curSem"
|
||||
@change="semesterChanged"
|
||||
:placeholder="$capitalize($p.t('lehre/studiensemester'))"
|
||||
:style="{'scroll-behavior': 'auto !important'}"
|
||||
|
||||
@@ -137,15 +137,31 @@ export const AbgabetoolMitarbeiter = {
|
||||
cssClass: 'sticky-col',
|
||||
visible: true
|
||||
},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.formAction, headerFilter: false, headerSort: false, minWidth: 85, visible: true, tooltip: false, cssClass: 'sticky-col'},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.formAction, headerFilter: false, headerSort: false, minWidth: 140, visible: true, tooltip: false, cssClass: 'sticky-col'},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4personenkennzeichen'))), headerFilter: true, field: 'pkz', formatter: this.pkzTextFormatter, minWidth: 140, visible: false,tooltip: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4vorname'))), field: 'vorname', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100,visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nachname'))), field: 'nachname', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100,visible: true},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4studstatus'))), field: 'studienstatus', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 150, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4orgformv2'))), field: 'orgform', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 50, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4projekttyp'))), field: 'projekttyp_kurzbz', formatter: this.centeredTextFormatter, minWidth: 100,visible: true},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4stg'))), field: 'stg', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 50, visible: true},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4note'))), field: 'note_bez', headerFilter: true, visible: false, sorter: this.notenSorter, minWidth: 200, formatter: this.centeredTextFormatter},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4sem'))), field: 'studiensemester_kurzbz', headerFilter: true, formatter: this.centeredTextFormatter, visible: true, minWidth: 100},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4titel'))), field: 'titel', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, width: 500, visible: true},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4betreuerartv2'))), field: 'betreuerart_beschreibung',formatter: this.centeredTextFormatter, visible: true, minWidth: 100, width: 200},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4erstbetreuerv2'))), field: 'betreuer_full_name', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4erstbetreuerTitelPre'))), field: 'betreuer_titelpre', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4erstbetreuerVorname'))), field: 'betreuer_vorname', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: true},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4erstbetreuerNachname'))), field: 'betreuer_nachname', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: true},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4erstbetreuerTitelPost'))), field: 'betreuer_titelpost', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4zweitbetreuerv2'))), field: 'zweitbetreuer_full_name', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4zweitbetreuerTitelPre'))), field: 'zweitbetreuer_titelpre', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4zweitbetreuerVorname'))), field: 'zweitbetreuer_vorname', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4zweitbetreuerNachname'))), field: 'zweitbetreuer_nachname', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4zweitbetreuerTitelPost'))), field: 'zweitbetreuer_titelpost', headerFilter: true, formatter: this.centeredTextFormatter, minWidth: 100, visible: false},
|
||||
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4prevAbgabetermin'))),
|
||||
headerFilter: dateFilter,
|
||||
headerFilterFunc: this.headerFilterTerminCol,
|
||||
@@ -248,6 +264,11 @@ export const AbgabetoolMitarbeiter = {
|
||||
]};
|
||||
},
|
||||
methods: {
|
||||
notenSorter(a, b, aRow, bRow, column, dir, sorterParams) {
|
||||
const aData = aRow.getData()
|
||||
const bData = bRow.getData()
|
||||
return aData.note - bData.note
|
||||
},
|
||||
async openBenotung(type, link) {
|
||||
if(type === 'new') {
|
||||
window.open(link, '_blank')
|
||||
@@ -277,6 +298,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
}
|
||||
},
|
||||
formAction(cell) {
|
||||
|
||||
const actionButtons = document.createElement('div');
|
||||
actionButtons.className = "d-flex gap-3";
|
||||
actionButtons.style.display = "flex";
|
||||
@@ -316,9 +338,27 @@ export const AbgabetoolMitarbeiter = {
|
||||
} else if(data.abgabetermine?.find(termin => termin.paabgabetyp_kurzbz == 'end' && termin.abgabedatum !== null) && data.beurteilungLinkOld) {
|
||||
actionButtons.append(createButton('fa fa-user-check', 'abgabetool/c4benoten', () => this.openBenotung('old', data.beurteilungLinkOld)))
|
||||
}
|
||||
|
||||
if(this.checkForZweitbetreuerTokenMailAvailability(data)) {
|
||||
actionButtons.append(createButton('fa fa-envelope-open-text', 'abgabetool/c4zweitBegutachterTokenMailSenden', () => this.sendZweitbetreuerToken(data)))
|
||||
|
||||
}
|
||||
|
||||
return actionButtons;
|
||||
},
|
||||
checkForZweitbetreuerTokenMailAvailability(data) {
|
||||
const hasEndabgabeWithUpload = !!data.abgabetermine.find(termin => termin.abgabedatum !== null && termin.paabgabetyp_kurzbz == 'end')
|
||||
const hasZweitbetreuerWithoutBenutzerUid = data.zweitbetreuer_person_id !== null && data.zweitbetreuer_benutzer_uid === null
|
||||
|
||||
return hasEndabgabeWithUpload && hasZweitbetreuerWithoutBenutzerUid
|
||||
},
|
||||
sendZweitbetreuerToken(data) {
|
||||
|
||||
this.$api.call(ApiAbgabe.sendZweitbetreuerTokenMail(data.projektarbeit_id, data.betreuer_person_id, data.student_uid))
|
||||
.then(res => {
|
||||
if(res.meta.status == 'success') this.$fhcAlert.alertSuccess(this.$p.t('abgabetool/c4zweitBegutachterTokenMailSuccess'))
|
||||
})
|
||||
},
|
||||
getDateStyleHtml(dateStyle) {
|
||||
const iconMap = {
|
||||
'verspaetet': '<i class="fa-solid fa-triangle-exclamation"></i>',
|
||||
@@ -1174,14 +1214,19 @@ export const AbgabetoolMitarbeiter = {
|
||||
return (projekt.typ + projekt.kurzbz)?.toUpperCase()
|
||||
},
|
||||
setupData(data){
|
||||
|
||||
|
||||
this.domain = data[1]
|
||||
|
||||
this.projektarbeiten = data[0]?.retval?.map(projekt => {
|
||||
this.checkAbgabetermineProjektarbeit(projekt)
|
||||
projekt.selectable = projekt.betreuerart_kurzbz !== 'Zweitbegutachter'
|
||||
|
||||
if(this.notenOptions && projekt.note) {
|
||||
const opt = this.notenOptions.find(n => n.note == projekt.note)
|
||||
// TODO: mehrsprachig englisch -> nevermind the english field in
|
||||
// notenoption->bezeichnung_mehrsprachig is ALWAYS german
|
||||
projekt.note_bez = opt?.bezeichnung
|
||||
}
|
||||
|
||||
return {
|
||||
...projekt,
|
||||
details: {
|
||||
@@ -1249,7 +1294,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
}
|
||||
|
||||
this.serienTermin.upload_allowed = newVal.upload_allowed_default
|
||||
},
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
countsToHTML() {
|
||||
|
||||
@@ -402,7 +402,7 @@ export const AbgabetoolStudent = {
|
||||
</label>
|
||||
<Textarea
|
||||
v-model="editingTitel"
|
||||
rows="10"
|
||||
rows="2"
|
||||
maxlength="1024"
|
||||
class="form-control w-100"
|
||||
@keydown.enter.prevent="saveTitel"
|
||||
|
||||
@@ -11,6 +11,13 @@ export function formatISODate(dateParam) {
|
||||
return date.isValid ? date.toFormat('dd.MM.yyyy') : '';
|
||||
}
|
||||
|
||||
export function formatDateTime(dateParam) {
|
||||
if (!dateParam) return '';
|
||||
|
||||
const date = luxon.DateTime.fromSQL(dateParam);
|
||||
return date.isValid ? date.toFormat("dd.MM.yyyy HH:mm") : '';
|
||||
}
|
||||
|
||||
export function toViennaDate(dateParam) {
|
||||
if (!dateParam) return null;
|
||||
|
||||
|
||||
@@ -293,6 +293,21 @@ export default {
|
||||
this.$refs.projektbetreuerTable.tabulator.replaceData(this.addIds(result.data));
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
// get other initial data
|
||||
this.$api
|
||||
.call(ApiStvProjektbetreuer.getBetreuerarten())
|
||||
.then(result => {
|
||||
this.arrBetreuerart = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
|
||||
this.$api
|
||||
.call(ApiStvProjektbetreuer.getNoten())
|
||||
.then(result => {
|
||||
this.arrNoten = result.data;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
} else {
|
||||
this.emptyBetreuerList();
|
||||
}
|
||||
@@ -547,6 +562,9 @@ export default {
|
||||
|
||||
</form-form>
|
||||
|
||||
<button class="btn btn-primary" v-show="betreuerFormOpened" @click="saveProjektbetreuer">
|
||||
{{ $p.t('projektarbeit', 'betreuerSpeichernv2') }}
|
||||
</button>
|
||||
<!-- <div class = "mt-5" v-if="beurteilungDownloadLink !== null">
|
||||
<div class="mb-1">
|
||||
<a :href="beurteilungDownloadLink" class="btn btn-primary d-block" :class="{ 'disabled' : beurteilungDownloadLink === ''}">
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
export async function splitMailsHelper(mails, event, subject, body, alertPluginRef, phrasenPluginRef) {
|
||||
await phrasenPluginRef.loadCategory('ui');
|
||||
debugger
|
||||
let splititem = ",";
|
||||
let maillist = mails.join(splititem);
|
||||
let useBcc = event?.ctrlKey || event?.metaKey;
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
// DatesManual.js: implemented custom input handling for tabulator date header filter,
|
||||
// since primevue3 calendar manual input seems to be broken in this case. Main difference
|
||||
// to normal Dates.js headerfilter is that this one does not automatically open the calendar
|
||||
// overlay, as it tries to aggressively steal the focus away from the input field. try it out!
|
||||
|
||||
// Custom evaluation logic so Tabulator knows how to filter the array of Date objects
|
||||
Tabulator.extendModule('filter', 'filters', {
|
||||
"dates": (headerValue, rowValue) => {
|
||||
if (!headerValue) return true;
|
||||
|
||||
let rowDate = new Date(rowValue);
|
||||
|
||||
if (Array.isArray(headerValue)) {
|
||||
let startDate = new Date(headerValue[0]);
|
||||
if (headerValue[1]) {
|
||||
let endDate = new Date(headerValue[1]);
|
||||
endDate.setHours(23, 59, 59, 999);
|
||||
return rowDate >= startDate && rowDate <= endDate;
|
||||
}
|
||||
return rowDate.toDateString() === startDate.toDateString();
|
||||
}
|
||||
let singleDate = new Date(headerValue);
|
||||
return rowDate.toDateString() === singleDate.toDateString();
|
||||
}
|
||||
});
|
||||
|
||||
export function dateFilter(cell, onRendered, success) {
|
||||
let div = document.createElement('div');
|
||||
|
||||
let initialValue = null;
|
||||
let val = cell.getValue();
|
||||
if (Array.isArray(val)) {
|
||||
const start = val[0] ? new Date(val[0]) : null;
|
||||
const end = val[1] ? new Date(val[1]) : null;
|
||||
initialValue = [start, end];
|
||||
}
|
||||
|
||||
// Manual parser needed since we are bypassing PrimeVue's broken manualInput mode
|
||||
function parseDMY(str) {
|
||||
const m = str.trim().match(/^(\d{1,2})\.(\d{1,2})\.(\d{2,4})$/);
|
||||
if (!m) return null;
|
||||
let year = parseInt(m[3]);
|
||||
if (year < 100) year += 2000;
|
||||
const d = new Date(year, parseInt(m[2]) - 1, parseInt(m[1]));
|
||||
return isNaN(d.getTime()) ? null : d;
|
||||
}
|
||||
|
||||
// String formatter to sync the raw text field when dates are picked via the calendar UI
|
||||
function formatRange(dates) {
|
||||
if (!dates) return '';
|
||||
const fmt = d => d
|
||||
? `${String(d.getDate()).padStart(2,'0')}.${String(d.getMonth()+1).padStart(2,'0')}.${d.getFullYear()}`
|
||||
: '';
|
||||
if (Array.isArray(dates)) {
|
||||
return fmt(dates[0]) + (dates[1] ? ` - ${fmt(dates[1])}` : '');
|
||||
}
|
||||
return fmt(dates);
|
||||
}
|
||||
|
||||
Vue.createApp({
|
||||
components: { PrimevueCalendar: primevue.calendar },
|
||||
data() {
|
||||
return {
|
||||
// Split state into a proper Date object (calendar) and a raw string (text input)
|
||||
calVal: initialValue,
|
||||
textVal: formatRange(initialValue)
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
calVal(n) {
|
||||
// Centralized synchronization: updates text representation
|
||||
// AND safely notifies Tabulator of the value change
|
||||
this.textVal = formatRange(n);
|
||||
success(n);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// Translates the typed string back into Date objects for Tabulator's filter
|
||||
onTextChange() {
|
||||
if (!this.textVal) {
|
||||
this.calVal = null; // Triggers watcher -> success(null)
|
||||
return;
|
||||
}
|
||||
const parts = this.textVal.split(/\s*-\s*/);
|
||||
const start = parseDMY(parts[0]);
|
||||
const end = parts[1] ? parseDMY(parts[1]) : null;
|
||||
|
||||
if (start) {
|
||||
// Changing calVal automatically triggers the watcher,
|
||||
// which handles executing success() exactly once.
|
||||
this.calVal = [start, end];
|
||||
}
|
||||
}
|
||||
},
|
||||
// Native HTML input handles typing, PrimeVue calendar input is hidden (icon-only)
|
||||
// Placeholder removed to match the rest of the application's header filters
|
||||
template: `
|
||||
<div style="display:flex;align-items:center;width:100%">
|
||||
<input
|
||||
type="text"
|
||||
v-model="textVal"
|
||||
@change="onTextChange"
|
||||
@keydown.stop
|
||||
@keypress.stop
|
||||
@keyup.stop
|
||||
@mousedown.stop
|
||||
class="p-inputtext p-component"
|
||||
style="flex:1;min-width:0"
|
||||
/>
|
||||
<primevue-calendar
|
||||
v-model="calVal"
|
||||
selection-mode="range"
|
||||
show-button-bar
|
||||
:showIcon="true"
|
||||
:input-style="{display:'none'}"
|
||||
dateFormat="dd.mm.yy">
|
||||
</primevue-calendar>
|
||||
</div>`
|
||||
}).use(primevue.config.default).mount(div);
|
||||
|
||||
return div;
|
||||
}
|
||||
+164
-64
@@ -1036,7 +1036,7 @@ $phrases = array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BewerberIn möglicherweise vorhanden',
|
||||
'text' => 'Bewerber*In möglicherweise vorhanden',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -2134,6 +2134,26 @@ $phrases = array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'savedAtByV3',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Gespeichert am {0} von {1}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Saved on {0} by {1}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'anrechnung',
|
||||
@@ -3771,7 +3791,7 @@ $phrases = array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'LektorIn',
|
||||
'text' => 'Lektor*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -4400,7 +4420,7 @@ $phrases = array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BewerberIn',
|
||||
'text' => 'Bewerber*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -5300,7 +5320,7 @@ $phrases = array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BewerberIn parken',
|
||||
'text' => 'Bewerber*In parken',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -5320,7 +5340,7 @@ $phrases = array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BewerberIn ausparken',
|
||||
'text' => 'Bewerber*In ausparken',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -5400,7 +5420,7 @@ $phrases = array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BewerberIn geparkt bis',
|
||||
'text' => 'Bewerber*In geparkt bis',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -5460,7 +5480,7 @@ $phrases = array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BewerberIn zurückstellen',
|
||||
'text' => 'Bewerber*In zurückstellen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -5500,7 +5520,7 @@ $phrases = array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BewerberIn zurückgestellt bis',
|
||||
'text' => 'Bewerber*In zurückgestellt bis',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -5580,8 +5600,8 @@ $phrases = array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Geparkte und zurückgestellte BewerberInnen werden von der Bearbeitung temporär ausgenommen.
|
||||
Geparkte BewerberInnen werden zum angegebenen Datum automatisch entparkt, während zurückgestellte BewerberInnen nur manuell durch Drücken des Buttons den Zurückgestellt-Status verlieren.
|
||||
'text' => 'Geparkte und zurückgestellte Bewerber*Innen werden von der Bearbeitung temporär ausgenommen.
|
||||
Geparkte Bewerber*Innen werden zum angegebenen Datum automatisch entparkt, während zurückgestellte Bewerber*Innen nur manuell durch Drücken des Buttons den Zurückgestellt-Status verlieren.
|
||||
Bei einer Zurückstellung dient das Datum nur der Erinnerung.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
@@ -8811,7 +8831,7 @@ The invoice will be sent to you again. <u><strong>The amount is only to be trans
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ANNEHMEN<br>(LektorIn)',
|
||||
'text' => 'ANNEHMEN<br>(Lektor*In)',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -13682,7 +13702,7 @@ Any unusual occurrences
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'StudentIn',
|
||||
'text' => 'Student*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -15858,7 +15878,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Alle anzeigen, die auf Empfehlung von LektorIn warten.",
|
||||
'text' => "Alle anzeigen, die auf Empfehlung von Lektor*In warten.",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -25145,7 +25165,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'StudentIn ({prestudent_id})',
|
||||
'text' => 'Student*In ({prestudent_id})',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -28188,7 +28208,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'MitarbeiterIn',
|
||||
'text' => 'Mitarbeiter*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -29191,7 +29211,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'MitarbeiterIn',
|
||||
'text' => 'Mitarbeiter*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -29231,7 +29251,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Mitarbeiter Information',
|
||||
'text' => 'Mitarbeiter*In Information',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -29251,7 +29271,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'StudentIn',
|
||||
'text' => 'Student*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -29271,7 +29291,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Student Information',
|
||||
'text' => 'Student*In Information',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -37852,7 +37872,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'In welches Semester sollen diese {count} PrestudentInnen ({status})verschoben werden?',
|
||||
'text' => 'In welches Semester sollen diese {count} Prestudent*Innen ({status})verschoben werden?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -40097,7 +40117,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'InteressentIn',
|
||||
'text' => 'Interessent*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -40277,7 +40297,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'PreStudentIn',
|
||||
'text' => 'PreStudent*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -41241,7 +41261,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'LektorIn',
|
||||
'text' => 'Lektor*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -41381,7 +41401,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'StudentIn hat keinen Status in diesem Semester',
|
||||
'text' => 'Student*In hat keinen Status in diesem Semester',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -42289,7 +42309,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Dokumentabgabe - MitarbeiterInbereich",
|
||||
'text' => "Dokumentabgabe - Mitarbeiter*Inbereich",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -44095,7 +44115,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "BetreuerIn",
|
||||
'text' => "Betreuer*In",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -44170,7 +44190,7 @@ array(
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4abgabeStudentenbereich',
|
||||
'phrase' => 'c4abgabeStudentenbereichv2',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
@@ -45135,7 +45155,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Projektarbeit Detailansicht MitarbeiterIn",
|
||||
'text' => "Projektarbeit Detailansicht Mitarbeiter*In",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -45691,7 +45711,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "E-Mail BetreuerIn",
|
||||
'text' => "E-Mail Betreuer*In",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -45731,7 +45751,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "ErstbetreuerIn Beurteilung herunterladen",
|
||||
'text' => "Erstbetreuer*In Beurteilung herunterladen",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -45751,7 +45771,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "ZweitbetreuerIn Beurteilung herunterladen",
|
||||
'text' => "Zweitbetreuer*In Beurteilung herunterladen",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -45931,7 +45951,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Fehler beim Laden der Projektarbeit - StudentIn Zuordnung",
|
||||
'text' => "Fehler beim Laden der Projektarbeit - Student*In Zuordnung",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -45951,7 +45971,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Kein zugeteilter StudentIn gefunden für Projektarbeit",
|
||||
'text' => "Kein zugeteilter Student*In gefunden für Projektarbeit",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -46226,7 +46246,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ErstbetreuerIn',
|
||||
'text' => 'Erstbetreuer*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -46246,7 +46266,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ZweitbetreuerIn',
|
||||
'text' => 'Zweitbetreuer*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -46458,6 +46478,46 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4zweitBegutachterTokenMailSenden',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Access Token E-Mail an Zweitbegutachter*In senden',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Send access token email to second reviewer',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4zweitBegutachterTokenMailSuccess',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Access Token E-Mail an Zweitbegutachter*In wurde erfolgreich versandt.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Access token email has been successfully sent to second reviewer.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
@@ -46911,7 +46971,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BetreuerIn Berufspraktikum oder Projektarbeit',
|
||||
'text' => 'Betreuer*In Berufspraktikum oder Projektarbeit',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -47192,7 +47252,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ErstbetreuerIn Titel Pre',
|
||||
'text' => 'Erstbetreuer*In Titel Pre',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -47212,7 +47272,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ErstbetreuerIn Vorname',
|
||||
'text' => 'Erstbetreuer*In Vorname',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -47232,7 +47292,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ErstbetreuerIn Nachname',
|
||||
'text' => 'Erstbetreuer*In Nachname',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -47252,7 +47312,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ErstbetreuerIn Titel Post',
|
||||
'text' => 'Erstbetreuer*In Titel Post',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -47272,7 +47332,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ZweitbetreuerIn Titel Pre',
|
||||
'text' => 'Zweitbetreuer*In Titel Pre',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -47292,7 +47352,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ZweitbetreuerIn Vorname',
|
||||
'text' => 'Zweitbetreuer*In Vorname',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -47312,7 +47372,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ZweitbetreuerIn Nachname',
|
||||
'text' => 'Zweitbetreuer*In Nachname',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -47332,7 +47392,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ZweitbetreuerIn Titel Post',
|
||||
'text' => 'Zweitbetreuer*In Titel Post',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -47424,6 +47484,46 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4abgabetypAendernNichtErlaubt',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Ändern des Abgabetyps ist nach erfolgtem Upload oder einer erfolgten Benotung nicht erlaubt.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'You are not allowed to change the submission type after the upload is complete or after grades have been assigned.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4datumAendernNichtErlaubt',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Ändern des Termin Zieldatums ist nach erfolgtem Upload oder einer erfolgten Benotung nicht erlaubt.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'You are not allowed to change the deadline date after the upload is complete or after grades have been assigned.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
// ABGABETOOL PHRASEN END
|
||||
array(
|
||||
'app' => 'core',
|
||||
@@ -48099,7 +48199,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'PrüferIn 1',
|
||||
'text' => 'Prüfer*In 1',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -48119,7 +48219,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'PrüferIn 2',
|
||||
'text' => 'Prüfer*In 2',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -48139,7 +48239,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'PrüferIn 3',
|
||||
'text' => 'Prüfer*In 3',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -49243,7 +49343,7 @@ array(
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'PrestudentIn ID',
|
||||
'text' => 'Prestudent*In ID',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -51909,7 +52009,7 @@ and represent the current state of research on the topic. The prescribed citatio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'LektorIn hinzufügen',
|
||||
'text' => 'Lektor*In hinzufügen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -52291,7 +52391,7 @@ and represent the current state of research on the topic. The prescribed citatio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'SenderIn',
|
||||
'text' => 'Sender*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -52311,7 +52411,7 @@ and represent the current state of research on the topic. The prescribed citatio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'EmpfängerIn',
|
||||
'text' => 'Empfänger*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -52351,7 +52451,7 @@ and represent the current state of research on the topic. The prescribed citatio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'EmpfängerIn ID',
|
||||
'text' => 'Empfänger*In ID',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -54388,7 +54488,7 @@ and represent the current state of research on the topic. The prescribed citatio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Bitte StudentIn auswählen!',
|
||||
'text' => 'Bitte Student*In auswählen!',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -54853,7 +54953,7 @@ and represent the current state of research on the topic. The prescribed citatio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'MitarbeiterIn',
|
||||
'text' => 'Mitarbeiter*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -56289,7 +56389,7 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BetreuerIn',
|
||||
'text' => 'Betreuer*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -56309,7 +56409,7 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BetreuerIn',
|
||||
'text' => 'Betreuer*In',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -56529,7 +56629,7 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Löschen nicht möglich, dieser Projektarbeit sind bereits BetreuerInnen zugewiesen',
|
||||
'text' => 'Löschen nicht möglich, dieser Projektarbeit sind bereits Betreuer*Innen zugewiesen',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -56569,7 +56669,7 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'ProjektbetreuerIn ungültig',
|
||||
'text' => 'Projektbetreuer*In ungültig',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -56589,7 +56689,7 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Löschen nicht möglich, ProjektbetreuerIn hat bereits einen Vertrag',
|
||||
'text' => 'Löschen nicht möglich, Projektbetreuer*In hat bereits einen Vertrag',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -57029,7 +57129,7 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BetreuerIn bearbeiten',
|
||||
'text' => 'Betreuer*In bearbeiten',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -57044,12 +57144,12 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'projektarbeit',
|
||||
'phrase' => 'betreuerSpeichern',
|
||||
'phrase' => 'betreuerSpeichernv2',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'BetreuerIn speichern',
|
||||
'text' => 'Betreuer*In speichern',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -58186,7 +58286,7 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Saved on {date} von {name}',
|
||||
'text' => 'Saved on {date} by {name}',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
@@ -58906,7 +59006,7 @@ I have been informed that I am under no obligation to consent to the transmissio
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'StudentIn ist in diesem Semester keinem Lehrverband zugeteilt',
|
||||
'text' => 'Student*In ist in diesem Semester keinem Lehrverband zugeteilt',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user