mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-06-26 00:19:28 +00:00
Compare commits
25 Commits
master
..
2eb2c36d5b
| Author | SHA1 | Date | |
|---|---|---|---|
| 2eb2c36d5b | |||
| 22eed92c86 | |||
| 557e43e19c | |||
| 790568e1e0 | |||
| dfc3096587 | |||
| c0192e9e00 | |||
| 9b823dbaa1 | |||
| 398e3aa139 | |||
| 553a33aa42 | |||
| 05e9d948ea | |||
| a5d343268f | |||
| 9e061de9bd | |||
| d0adf2dfc3 | |||
| f51d0f72c6 | |||
| c62c3c23f6 | |||
| b22375bd21 | |||
| f9550c99bb | |||
| df369c7149 | |||
| 6868e68145 | |||
| 44e43d9479 | |||
| 079a8e3ec1 | |||
| 6ddb064c9e | |||
| 9b8b1b2532 | |||
| aba4bc2909 | |||
| f6d2b55f75 |
@@ -43,3 +43,11 @@ $config['ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'] = true;
|
||||
$config['ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'] = true;
|
||||
|
||||
$config['BETREUER_SAMMELMAIL_BUTTON_STUDENT'] = true;
|
||||
|
||||
$config['MULTIEDIT_TABLE'] = true;
|
||||
|
||||
$config['STUDENT_EDIT_PROJEKTARBEIT_TITLE'] = true;
|
||||
|
||||
$config['CONFETTI_ON_ENDUPLOAD'] = true;
|
||||
|
||||
|
||||
|
||||
@@ -35,9 +35,12 @@ class Abgabe extends FHCAPI_Controller
|
||||
'getStudentProjektabgaben' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_student:rw', 'basis/abgabe_lektor:rw'),
|
||||
'postStudentProjektarbeitZwischenabgabe' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_student:rw'),
|
||||
'postStudentProjektarbeitEndupload' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_student:rw'),
|
||||
'postStudentProjektarbeitTitel' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_student:rw'),
|
||||
'getMitarbeiterProjektarbeiten' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'),
|
||||
'postProjektarbeitAbgabe' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'),
|
||||
'patchProjektarbeitAbgabeMultiple' => array('basis/abgabe_assistenz:rw'),
|
||||
'deleteProjektarbeitAbgabe' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'),
|
||||
'deleteProjektarbeitAbgabeMultiple' => array('basis/abgabe_assistenz:rw'),
|
||||
'postSerientermin' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'),
|
||||
'fetchDeadlines' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'),
|
||||
'getPaAbgabetypen' => self::PERM_LOGGED,
|
||||
@@ -90,6 +93,7 @@ class Abgabe extends FHCAPI_Controller
|
||||
$ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT');
|
||||
$ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER');
|
||||
$BETREUER_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('BETREUER_SAMMELMAIL_BUTTON_STUDENT');
|
||||
$MULTIEDIT_TABLE = $this->config->item('MULTIEDIT_TABLE');
|
||||
|
||||
$ret = array(
|
||||
'old_abgabe_beurteilung_link' => $old_abgabe_beurteilung_link,
|
||||
@@ -97,7 +101,7 @@ class Abgabe extends FHCAPI_Controller
|
||||
'abgabetypenBetreuer' => $abgabetypenBetreuer,
|
||||
'ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT' => $ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT,
|
||||
'ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER' => $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER,
|
||||
'BETREUER_SAMMELMAIL_BUTTON_STUDENT' => $BETREUER_SAMMELMAIL_BUTTON_STUDENT,
|
||||
'MULTIEDIT_TABLE' => $MULTIEDIT_TABLE,
|
||||
);
|
||||
|
||||
$this->terminateWithSuccess($ret);
|
||||
@@ -107,10 +111,14 @@ class Abgabe extends FHCAPI_Controller
|
||||
* loads config related to abgabetool for students to avoid handing out links reserved for employees
|
||||
*/
|
||||
public function getConfigStudent() {
|
||||
$moodle_link =$this->config->item('STG_MOODLE_LINK');
|
||||
$moodle_link = $this->config->item('STG_MOODLE_LINK');
|
||||
$title_edit_allowed = $this->config->item('STUDENT_EDIT_PROJEKTARBEIT_TITLE');
|
||||
$confetti_on_endupload = $this->config->item('CONFETTI_ON_ENDUPLOAD');
|
||||
|
||||
$ret = array(
|
||||
'moodle_link' => $moodle_link,
|
||||
'title_edit_allowed' => $title_edit_allowed,
|
||||
'confetti_on_endupload' => $confetti_on_endupload
|
||||
);
|
||||
|
||||
$this->terminateWithSuccess($ret);
|
||||
@@ -187,8 +195,8 @@ class Abgabe extends FHCAPI_Controller
|
||||
} else {
|
||||
$result = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer(getAuthUID());
|
||||
}
|
||||
|
||||
$projektarbeiten = getData($result);
|
||||
|
||||
$projektarbeiten = hasData($result) ? getData($result) : array();
|
||||
|
||||
if(count($projektarbeiten)) {
|
||||
foreach($projektarbeiten as $pa) {
|
||||
@@ -448,7 +456,207 @@ class Abgabe extends FHCAPI_Controller
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* POST METHOD
|
||||
* allows a student (or assistenz on their behalf) to update the titel of their own projektarbeit.
|
||||
* blocked once the projektarbeit has been graded (checkProjektarbeitForFinishedStatus).
|
||||
*/
|
||||
public function postStudentProjektarbeitTitel()
|
||||
{
|
||||
if(!$this->config->item('STUDENT_EDIT_PROJEKTARBEIT_TITLE')) {
|
||||
$this->terminateWithError($this->p->t('global', 'c4studentEditNotAllowed'), 'general');
|
||||
};
|
||||
|
||||
$projektarbeit_id = $this->input->post('projektarbeit_id');
|
||||
$titel = $this->input->post('titel');
|
||||
|
||||
if ($projektarbeit_id === NULL || trim((string)$projektarbeit_id) === ''
|
||||
|| $titel === NULL || trim((string)$titel) === '') {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
// strip all HTML tags to prevent XSS in mail bodies, table views and Projektarbeitsbenotung
|
||||
$titel = trim(strip_tags($titel));
|
||||
if ($titel === '') {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
|
||||
$this->checkProjektarbeitForFinishedStatus($projektarbeit_id);
|
||||
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
|
||||
// Verify the projektarbeit actually belongs to the supplied student_uid
|
||||
$res = $this->ProjektarbeitModel->getStudentInfoForProjektarbeitId($projektarbeit_id);
|
||||
if (isError($res) || !hasData($res)) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4projektarbeitNichtGefunden'), 'general');
|
||||
}
|
||||
$assignedStudentUid = getData($res)[0]->uid;
|
||||
|
||||
// A student may only update their own title; assistenz is covered by checkZuordnung
|
||||
$zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID());
|
||||
if (getAuthUID() !== $assignedStudentUid && !$zugeordnet) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent'), 'general');
|
||||
}
|
||||
|
||||
|
||||
|
||||
$result = $this->ProjektarbeitModel->load($projektarbeit_id);
|
||||
$data = getData($result);
|
||||
|
||||
$oldTitle = $data[0]->titel ?? '';
|
||||
|
||||
$result = $this->ProjektarbeitModel->update(
|
||||
$projektarbeit_id,
|
||||
array(
|
||||
'titel' => $titel,
|
||||
'updatevon' => getAuthUID(),
|
||||
'updateamum' => date('Y-m-d H:i:s')
|
||||
)
|
||||
);
|
||||
|
||||
$this->getDataOrTerminateWithError($result, 'general');
|
||||
|
||||
$this->logLib->logInfoDB(array(
|
||||
'titelUpdate',
|
||||
array(
|
||||
'projektarbeit_id' => $projektarbeit_id,
|
||||
'titel' => $titel,
|
||||
'updatevon' => getAuthUID(),
|
||||
'updateamum' => date('Y-m-d H:i:s')
|
||||
),
|
||||
getAuthUID(),
|
||||
getAuthPersonId()
|
||||
));
|
||||
|
||||
$this->sendTitelChangedEmail(
|
||||
$projektarbeit_id,
|
||||
$titel,
|
||||
$oldTitle,
|
||||
$assignedStudentUid
|
||||
);
|
||||
|
||||
$result = $this->ProjektarbeitModel->load($projektarbeit_id);
|
||||
$this->terminateWithSuccess($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies all betreuer of a projektarbeit and all assistenzen responsible for its studiengang
|
||||
* when a student updates the titel of their projektarbeit.
|
||||
*
|
||||
* Betreuer retrieval mirrors AbgabetoolJob->notifyBetreuerAboutChangedAbgaben.
|
||||
* Assistenz retrieval mirrors AbgabetoolJob->notifyAssistenzAboutChangedAbgaben.
|
||||
*
|
||||
* @param int $projektarbeit_id
|
||||
* @param string $new_titel The titel as it was saved
|
||||
* @param string $student_uid
|
||||
*/
|
||||
private function sendTitelChangedEmail($projektarbeit_id, $new_titel, $old_titel, $student_uid)
|
||||
{
|
||||
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
|
||||
$this->load->model('education/Projektbetreuer_model', 'ProjektbetreuerModel');
|
||||
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
|
||||
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
|
||||
$this->load->model('person/Person_model', 'PersonModel');
|
||||
|
||||
$this->load->model('person/Person_model', 'PersonModel');
|
||||
$studentNameResult = $this->PersonModel->getFullName($student_uid);
|
||||
$studentFullName = hasData($studentNameResult) ? getData($studentNameResult) : $student_uid;
|
||||
|
||||
$studentInfoResult = $this->ProjektarbeitModel->getStudentInfoForProjektarbeitId($projektarbeit_id);
|
||||
if (isError($studentInfoResult) || !hasData($studentInfoResult)) {
|
||||
$this->logLib->logInfoDB(array('sendTitelChangedEmail: student info not found', $projektarbeit_id));
|
||||
return;
|
||||
}
|
||||
$studentInfo = getData($studentInfoResult)[0];
|
||||
$studiengang_kz = $studentInfo->studiengang_kz;
|
||||
|
||||
$stgResult = $this->StudiengangModel->load($studiengang_kz);
|
||||
$oe_kurzbz = null;
|
||||
if (!isError($stgResult) && hasData($stgResult)) {
|
||||
$oe_kurzbz = getData($stgResult)[0]->oe_kurzbz ?? null;
|
||||
}
|
||||
|
||||
// build shared mail data
|
||||
$base_mail_data = array(
|
||||
'studentFullName' => $studentFullName,
|
||||
'new_titel' => $new_titel,
|
||||
'old_titel' => $old_titel
|
||||
);
|
||||
|
||||
// notify all betreuer
|
||||
$betreuerResult = $this->ProjektbetreuerModel->getAllBetreuerOfProjektarbeit($projektarbeit_id);
|
||||
if (!isError($betreuerResult) && hasData($betreuerResult)) {
|
||||
|
||||
$linkAbgabetool = APP_ROOT . $this->config->item('URL_MITARBEITER');
|
||||
|
||||
foreach (getData($betreuerResult) as $betreuer) {
|
||||
$email = $betreuer->uid ? $betreuer->uid . '@' . DOMAIN : ($betreuer->private_email ?? null);
|
||||
if (!$email) {
|
||||
$this->logLib->logInfoDB(array('sendTitelChangedEmail: no email for betreuer', $betreuer->person_id));
|
||||
continue;
|
||||
}
|
||||
|
||||
$anredeResult = $this->ProjektarbeitModel->getProjektbetreuerAnrede($betreuer->person_id);
|
||||
$anrede = (!isError($anredeResult) && hasData($anredeResult)) ? getData($anredeResult)[0] : null;
|
||||
|
||||
$mail_data = array_merge($base_mail_data, array(
|
||||
'anredeFillString' => ($anrede->anrede ?? '') === 'Herr' ? 'r' : '',
|
||||
'anrede' => $anrede->anrede ?? '',
|
||||
'fullFormattedNameString' => $anrede->first ?? $email,
|
||||
'linkAbgabetool' => $linkAbgabetool,
|
||||
));
|
||||
|
||||
sendSanchoMail(
|
||||
'PATitleUpdated',
|
||||
$mail_data,
|
||||
$email,
|
||||
$this->p->t('abgabetool', 'c4PATitleChanged')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// notify assistenz for the studiengang OE
|
||||
if (!$oe_kurzbz) {
|
||||
$this->logLib->logInfoDB(array('sendTitelChangedEmail: no oe_kurzbz resolved, skipping assistenz', $studiengang_kz));
|
||||
return;
|
||||
}
|
||||
|
||||
$assistenzResult = $this->OrganisationseinheitModel->getAssistenzForOE($oe_kurzbz);
|
||||
if (isError($assistenzResult) || !hasData($assistenzResult)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$linkAbgabetool = APP_ROOT . $this->config->item('URL_ASSISTENZ');
|
||||
|
||||
// similar pattern as job uses via the assistenzMap
|
||||
$sentTo = [];
|
||||
foreach (getData($assistenzResult) as $assistenz) {
|
||||
if (in_array($assistenz->person_id, $sentTo)) {
|
||||
continue;
|
||||
}
|
||||
$sentTo[] = $assistenz->person_id;
|
||||
|
||||
$email = $assistenz->uid . '@' . DOMAIN;
|
||||
|
||||
$mail_data = array_merge($base_mail_data, array(
|
||||
'anredeFillString' => $assistenz->anrede === 'Herr' ? 'r' : '',
|
||||
'anrede' => $assistenz->anrede ?? '',
|
||||
'fullFormattedNameString' => $assistenz->first ?? ($assistenz->uid . '@' . DOMAIN),
|
||||
'linkAbgabetool' => $linkAbgabetool,
|
||||
));
|
||||
|
||||
sendSanchoMail(
|
||||
'PATitleUpdated',
|
||||
$mail_data,
|
||||
$email,
|
||||
$this->p->t('abgabetool', 'c4PATitleChanged')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// validate paabgabe deadline against servertime just in case a student spoofs their local clock and thus
|
||||
// unlocks the upload ui
|
||||
private function checkPaabgabeDeadline($paabgabe_id) {
|
||||
@@ -687,6 +895,99 @@ class Abgabe extends FHCAPI_Controller
|
||||
$this->terminateWithSuccess([$paabgabe, $existingPaabgabe]);
|
||||
}
|
||||
|
||||
/**
|
||||
* called by abgabetool/assistenz when bulk-editing multiple abgabetermine via the flat termine table view
|
||||
* only fields present in the payload are updated - absent fields are left untouched
|
||||
*/
|
||||
public function patchProjektarbeitAbgabeMultiple() {
|
||||
$paabgabe_ids = $this->input->post('paabgabe_ids');
|
||||
|
||||
if ($paabgabe_ids === NULL || !is_array($paabgabe_ids) || count($paabgabe_ids) === 0) {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
// collect only fields that were actually sent
|
||||
$updateFields = [];
|
||||
|
||||
$datum = $this->input->post('datum');
|
||||
if ($datum !== NULL && trim((string)$datum) !== '') {
|
||||
$updateFields['datum'] = $datum;
|
||||
}
|
||||
|
||||
$paabgabetyp_kurzbz = $this->input->post('paabgabetyp_kurzbz');
|
||||
if ($paabgabetyp_kurzbz !== NULL && trim((string)$paabgabetyp_kurzbz) !== '') {
|
||||
$updateFields['paabgabetyp_kurzbz'] = $paabgabetyp_kurzbz;
|
||||
}
|
||||
|
||||
$kurzbz = $this->input->post('kurzbz');
|
||||
if ($kurzbz !== NULL) {
|
||||
$updateFields['kurzbz'] = $kurzbz;
|
||||
}
|
||||
|
||||
// booleans: only include if explicitly posted
|
||||
$upload_allowed = $this->input->post('upload_allowed');
|
||||
if ($upload_allowed !== NULL) {
|
||||
$updateFields['upload_allowed'] = filter_var($upload_allowed, FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
$fixtermin = $this->input->post('fixtermin');
|
||||
if ($fixtermin !== NULL) {
|
||||
$updateFields['fixtermin'] = filter_var($fixtermin, FILTER_VALIDATE_BOOLEAN);
|
||||
}
|
||||
|
||||
if (empty($updateFields)) {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
|
||||
|
||||
$results = [];
|
||||
foreach ($paabgabe_ids as $paabgabe_id) {
|
||||
$paabgabe_id = trim((string)$paabgabe_id);
|
||||
|
||||
if ($paabgabe_id === '') {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
$projektarbeit_id = $this->getProjektarbeitIDForPaabgabeID($paabgabe_id);
|
||||
|
||||
$this->checkProjektarbeitForFinishedStatus($projektarbeit_id);
|
||||
|
||||
$zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID());
|
||||
if (!$zugeordnet) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent'), 'general');
|
||||
}
|
||||
|
||||
$paabgabeResult = $this->PaabgabeModel->load($paabgabe_id);
|
||||
$paabgabeArr = $this->getDataOrTerminateWithError($paabgabeResult, 'general');
|
||||
|
||||
if (count($paabgabeArr) === 0) {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
$result = $this->PaabgabeModel->update(
|
||||
$paabgabe_id,
|
||||
array_merge($updateFields, [
|
||||
'updatevon' => getAuthUID(),
|
||||
'updateamum' => date('Y-m-d H:i:s')
|
||||
])
|
||||
);
|
||||
|
||||
$this->getDataOrTerminateWithError($result, 'general');
|
||||
$results[] = getData($this->PaabgabeModel->load($paabgabe_id))[0];
|
||||
|
||||
$this->logLib->logInfoDB(array(
|
||||
'paabgabe bulk updated',
|
||||
$paabgabe_id,
|
||||
$updateFields,
|
||||
getAuthUID(),
|
||||
getAuthPersonId()
|
||||
));
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* called by abgabetool/mitarbeiter in mitarbeiterdetail.js when deleting an abgabetermin
|
||||
* deletion is only possible if user is assistenz OR betreuer deletes their own custom termin
|
||||
@@ -719,11 +1020,55 @@ class Abgabe extends FHCAPI_Controller
|
||||
$result = $this->PaabgabeModel->delete($paabgabe_id);
|
||||
$result = $this->getDataOrTerminateWithError($result, 'general');
|
||||
|
||||
// TODO: consider this in nightly email job
|
||||
$this->logLib->logInfoDB(array($paabgabeArr[0], getAuthUID(), getAuthPersonId()));
|
||||
$this->terminateWithSuccess($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* called by abgabetool/assistenz when deleting multiple abgabetermine via the flat termine table view
|
||||
*/
|
||||
public function deleteProjektarbeitAbgabeMultiple() {
|
||||
$paabgabe_ids = $this->input->post('paabgabe_ids');
|
||||
|
||||
if ($paabgabe_ids === NULL || !is_array($paabgabe_ids) || count($paabgabe_ids) === 0) {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
|
||||
|
||||
$results = [];
|
||||
foreach ($paabgabe_ids as $paabgabe_id) {
|
||||
$paabgabe_id = trim((string)$paabgabe_id);
|
||||
|
||||
if ($paabgabe_id === '') {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
$this->checkProjektarbeitForFinishedStatus($this->getProjektarbeitIDForPaabgabeID($paabgabe_id));
|
||||
|
||||
$zugeordnet = $this->checkZuordnungByPaabgabe($paabgabe_id, getAuthUID());
|
||||
|
||||
if (!$zugeordnet) {
|
||||
$this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent'), 'general');
|
||||
}
|
||||
|
||||
$paabgabeResult = $this->PaabgabeModel->load($paabgabe_id);
|
||||
$paabgabeArr = $this->getDataOrTerminateWithError($paabgabeResult, 'general');
|
||||
|
||||
if (count($paabgabeArr) == 0) {
|
||||
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
|
||||
}
|
||||
|
||||
$result = $this->PaabgabeModel->delete($paabgabe_id);
|
||||
$result = $this->getDataOrTerminateWithError($result, 'general');
|
||||
$results[] = $result;
|
||||
|
||||
$this->logLib->logInfoDB(array($paabgabeArr[0], getAuthUID(), getAuthPersonId()));
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* endpoint for adding the same paabgabe for multiple projektarbeiten
|
||||
* can be slow for large n since it queries twice per projektarbeit_id
|
||||
@@ -1206,7 +1551,7 @@ class Abgabe extends FHCAPI_Controller
|
||||
};
|
||||
Events::trigger('projektarbeit_is_current', $projektarbeit_id, $returnFunc);
|
||||
if(!$projektarbeitIsCurrent) {
|
||||
$this->terminateWithError($this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeit'), 'general');
|
||||
$this->terminateWithError($this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeitv2'), 'general');
|
||||
}
|
||||
|
||||
// Link to Abgabetool
|
||||
@@ -1411,7 +1756,13 @@ class Abgabe extends FHCAPI_Controller
|
||||
|
||||
$data = getData($res)[0];
|
||||
if($data->note !== NULL) {
|
||||
$this->terminateWithError($this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeit'), 'general');
|
||||
// hardcode this error msg cause phrasen arent reliable and people keep bugging why the cant edit old entries they definitely shouldnt update
|
||||
$message = $this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeitv2');
|
||||
if(strpos($message, "<<") === 0) { // phrase could not be loaded
|
||||
$this->terminateWithError('Die Projektarbeit wurde bereits benotet, Sie dürfen deshalb keine weiteren Termine anlegen oder bearbeiten.', 'general');
|
||||
} else {
|
||||
$this->terminateWithError($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -78,32 +78,52 @@ class Dokumente extends FHCAPI_Controller
|
||||
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$resultPreDoc = $this->_getPrestudentDokumente($prestudent_id);
|
||||
|
||||
$arrayAccepted = [];
|
||||
$person_id = $this->_getPersonId($prestudent_id);
|
||||
|
||||
$mergedArray = [];
|
||||
$docNames = array_map(function ($item) {
|
||||
return $item->dokument_kurzbz;
|
||||
}, $resultPreDoc);
|
||||
|
||||
foreach ($resultPreDoc as $pre)
|
||||
foreach($docNames as $doc)
|
||||
{
|
||||
$result = $this->AkteModel->getAktenFAS($person_id, $pre->dokument_kurzbz, $studiengang_kz, $prestudent_id, true);
|
||||
$result = $this->AkteModel->getAktenFAS($person_id, $doc, $studiengang_kz, $prestudent_id, true);
|
||||
|
||||
if (isError($result))
|
||||
{
|
||||
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
|
||||
|
||||
}
|
||||
if (hasData($result))
|
||||
{
|
||||
foreach (getData($result) as $doc)
|
||||
$data = getData($result);
|
||||
foreach ($data as $value)
|
||||
{
|
||||
$merged = clone $doc;
|
||||
$merged->docdatum = $pre->docdatum;
|
||||
$merged->insertvonma = $pre->insertvonma;
|
||||
$merged->bezeichnung = $pre->bezeichnung;
|
||||
$mergedArray[] = $merged;
|
||||
array_push($arrayAccepted, $value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$mergedArray[] = $pre;
|
||||
}
|
||||
|
||||
//Mapping with document_kurzbz
|
||||
$preDocMap = [];
|
||||
foreach ($resultPreDoc as $pre) {
|
||||
$preDocMap[$pre->dokument_kurzbz] = $pre;
|
||||
}
|
||||
|
||||
$mergedArray = [];
|
||||
foreach ($arrayAccepted as $doc) {
|
||||
$merged = clone $doc;
|
||||
|
||||
if (isset($preDocMap[$doc->dokument_kurzbz])) {
|
||||
$merged->docdatum = $preDocMap[$doc->dokument_kurzbz]->docdatum;
|
||||
$merged->insertvonma = $preDocMap[$doc->dokument_kurzbz]->insertvonma;
|
||||
$merged->bezeichnung = $preDocMap[$doc->dokument_kurzbz]->bezeichnung;
|
||||
} else {
|
||||
$merged->akzeptiertdatum = null;
|
||||
$merged->akzeptiertvon = null;
|
||||
}
|
||||
|
||||
$mergedArray[] = $merged;
|
||||
}
|
||||
|
||||
$this->terminateWithSuccess($mergedArray);
|
||||
|
||||
@@ -48,8 +48,7 @@ class Konto extends FHCAPI_Controller
|
||||
|
||||
// Load language phrases
|
||||
$this->loadPhrases([
|
||||
'konto',
|
||||
'lehre'
|
||||
'konto'
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -113,7 +112,7 @@ class Konto extends FHCAPI_Controller
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getBuchungstypen($studiensemester_kurzbz = null)
|
||||
public function getBuchungstypen()
|
||||
{
|
||||
$this->load->model('crm/Buchungstyp_model', 'BuchungstypModel');
|
||||
|
||||
@@ -123,7 +122,6 @@ class Konto extends FHCAPI_Controller
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->_getOEHBeitrag($data, $studiensemester_kurzbz);
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
@@ -496,43 +494,4 @@ class Konto extends FHCAPI_Controller
|
||||
|
||||
$this->terminateWithSuccess();
|
||||
}
|
||||
|
||||
private function _getOEHBeitrag(&$data, $studiensemester_kurzbz = null)
|
||||
{
|
||||
if (is_null($studiensemester_kurzbz))
|
||||
{
|
||||
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
|
||||
$studiensemester_akt = $this->variablelib->getVar('semester_aktuell');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
if ($this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
|
||||
$studiensemester_akt = $studiensemester_kurzbz;
|
||||
else
|
||||
$this->terminateWithError($this->p->t('lehre', 'error_noStudiensemester'));
|
||||
}
|
||||
|
||||
$this->load->model('codex/Oehbeitrag_model', 'OehbeitragModel');
|
||||
$oehBeitrag = $this->OehbeitragModel->getByStudiensemester($studiensemester_akt);
|
||||
|
||||
$oehStandardbetrag = null;
|
||||
if (hasData($oehBeitrag))
|
||||
{
|
||||
$oeh = getData($oehBeitrag)[0];
|
||||
$summe = ($oeh->studierendenbeitrag + $oeh->versicherung) * -1;
|
||||
$oehStandardbetrag = number_format((float)$summe, 2, '.', '');
|
||||
}
|
||||
|
||||
if ($oehStandardbetrag !== null)
|
||||
{
|
||||
$data = array_map(function ($buchungstyp) use ($oehStandardbetrag) {
|
||||
if (isset($buchungstyp->buchungstyp_kurzbz) && (strtolower($buchungstyp->buchungstyp_kurzbz) === 'oeh'))
|
||||
{
|
||||
$buchungstyp->standardbetrag = $oehStandardbetrag;
|
||||
}
|
||||
return $buchungstyp;
|
||||
}, $data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,15 @@ class Projektarbeit extends FHCAPI_Controller
|
||||
|
||||
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id)) return $this->terminateWithError('Projektarbeit Id missing', self::ERROR_TYPE_GENERAL);
|
||||
|
||||
$result = $this->fetchProjektarbeitByID($projektarbeit_id);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess(current($data));
|
||||
}
|
||||
|
||||
private function fetchProjektarbeitById($projektarbeit_id) {
|
||||
$this->ProjektarbeitModel->resetQuery();
|
||||
$this->ProjektarbeitModel->addSelect(
|
||||
'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, lehrveranstaltung_id, lehreinheit_id,
|
||||
firma_id, beginn, ende, gesperrtbis, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name'
|
||||
@@ -97,13 +106,10 @@ class Projektarbeit extends FHCAPI_Controller
|
||||
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
|
||||
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
|
||||
$this->ProjektarbeitModel->addJoin('public.tbl_firma fa', 'firma_id', 'LEFT');
|
||||
$result = $this->ProjektarbeitModel->loadWhere(
|
||||
return $this->ProjektarbeitModel->loadWhere(
|
||||
array('projektarbeit_id' => $projektarbeit_id)
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess(current($data));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,7 +138,8 @@ class Projektarbeit extends FHCAPI_Controller
|
||||
);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($this->fetchProjektarbeitById($data));
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
*/
|
||||
class Students extends FHCAPI_Controller
|
||||
{
|
||||
private $allowedStgs = [];
|
||||
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$permissions = [];
|
||||
@@ -32,17 +35,16 @@ class Students extends FHCAPI_Controller
|
||||
$permissions[$router->method] = ['admin:r', 'assistenz:r'];
|
||||
parent::__construct($permissions);
|
||||
|
||||
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('admin') ?: [];
|
||||
$allowedStgs = array_merge($allowedStgs, $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []);
|
||||
$this->allowedStgs = $this->permissionlib->getSTG_isEntitledFor('admin') ?: [];
|
||||
$this->allowedStgs = array_merge($this->allowedStgs, $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []);
|
||||
|
||||
if (!$allowedStgs) {
|
||||
if (!$this->allowedStgs) {
|
||||
$this->_outputAuthError([$router->method => ['admin:r', 'assistenz:r']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Load Libraries
|
||||
$this->load->library('PhrasesLib');
|
||||
$this->load->library('stv/StudentListLib', ['allowedStgs' => $allowedStgs]);
|
||||
$this->loadPhrases(
|
||||
array(
|
||||
'lehre'
|
||||
@@ -109,19 +111,23 @@ class Students extends FHCAPI_Controller
|
||||
]);
|
||||
|
||||
|
||||
$this->studentlistlib->addJoin(
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
|
||||
$this->PrestudentModel->addJoin(
|
||||
"(
|
||||
SELECT prestudent_id
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE status_kurzbz = 'Incoming'
|
||||
AND studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
) test",
|
||||
"prestudent_id",
|
||||
"",
|
||||
"start"
|
||||
"prestudent_id"
|
||||
);
|
||||
|
||||
$this->studentlistlib->addSelect("COALESCE(
|
||||
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(
|
||||
v.semester::text,
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
@@ -129,13 +135,16 @@ class Students extends FHCAPI_Controller
|
||||
ELSE ''::text
|
||||
END
|
||||
) AS semester", false);
|
||||
$this->studentlistlib->addSelect("COALESCE(v.verband::text, ''::text) AS verband");
|
||||
$this->studentlistlib->addSelect("COALESCE(v.gruppe::text, ''::text) AS gruppe");
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->PrestudentModel->load();
|
||||
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
@@ -155,7 +164,10 @@ class Students extends FHCAPI_Controller
|
||||
]);
|
||||
|
||||
|
||||
$this->studentlistlib->addJoin(
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
|
||||
$this->PrestudentModel->addJoin(
|
||||
"(
|
||||
SELECT prestudent_id
|
||||
FROM bis.tbl_bisio bis
|
||||
@@ -175,12 +187,14 @@ class Students extends FHCAPI_Controller
|
||||
) AND stdsem.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
GROUP BY prestudent_id
|
||||
) test",
|
||||
"prestudent_id",
|
||||
"",
|
||||
"start"
|
||||
"prestudent_id"
|
||||
);
|
||||
|
||||
$this->studentlistlib->addSelect("COALESCE(
|
||||
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(
|
||||
v.semester::text,
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
@@ -188,13 +202,16 @@ class Students extends FHCAPI_Controller
|
||||
ELSE ''::text
|
||||
END
|
||||
) AS semester", false);
|
||||
$this->studentlistlib->addSelect("COALESCE(v.verband::text, ''::text) AS verband");
|
||||
$this->studentlistlib->addSelect("COALESCE(v.gruppe::text, ''::text) AS gruppe");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->PrestudentModel->load();
|
||||
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
@@ -214,18 +231,23 @@ class Students extends FHCAPI_Controller
|
||||
]);
|
||||
|
||||
|
||||
$this->studentlistlib->addJoin(
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
|
||||
$this->PrestudentModel->addJoin(
|
||||
"(
|
||||
SELECT prestudent_id
|
||||
FROM bis.tbl_mobilitaet
|
||||
WHERE studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
) bis",
|
||||
"prestudent_id",
|
||||
"",
|
||||
"start"
|
||||
"prestudent_id"
|
||||
);
|
||||
|
||||
$this->studentlistlib->addSelect("COALESCE(
|
||||
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(
|
||||
v.semester::text,
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
@@ -233,13 +255,16 @@ class Students extends FHCAPI_Controller
|
||||
ELSE ''::text
|
||||
END
|
||||
) AS semester", false);
|
||||
$this->studentlistlib->addSelect("COALESCE(v.verband::text, ''::text) AS verband");
|
||||
$this->studentlistlib->addSelect("COALESCE(v.gruppe::text, ''::text) AS gruppe");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->PrestudentModel->load();
|
||||
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
@@ -288,6 +313,8 @@ class Students extends FHCAPI_Controller
|
||||
*/
|
||||
protected function fetchPrestudents($studiengang_kz, $studiensemester_kurzbz = null, $filter = null, $orgform_kurzbz = null)
|
||||
{
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
$stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
|
||||
|
||||
$selectRT = "
|
||||
@@ -304,38 +331,38 @@ class Students extends FHCAPI_Controller
|
||||
AND r.studiensemester_kurzbz=" . $stdsemEsc;
|
||||
|
||||
|
||||
$this->studentlistlib->addWhere('tbl_prestudent.studiengang_kz', $studiengang_kz);
|
||||
$where = ['tbl_prestudent.studiengang_kz' => $studiengang_kz];
|
||||
|
||||
if ($orgform_kurzbz) {
|
||||
$this->studentlistlib->addWhere('ps.orgform_kurzbz', $orgform_kurzbz);
|
||||
$where['ps.orgform_kurzbz'] = $orgform_kurzbz;
|
||||
}
|
||||
|
||||
switch ($filter) {
|
||||
case "interessenten":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Interessent');
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
break;
|
||||
case "bewerbungnichtabgeschickt":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Interessent');
|
||||
$this->studentlistlib->addWhere('ps.bewerbung_abgeschicktamum IS NULL');
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
$where['ps.bewerbung_abgeschicktamum'] = null;
|
||||
break;
|
||||
case "bewerbungabgeschickt":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Interessent');
|
||||
$this->studentlistlib->addWhere('ps.bewerbung_abgeschicktamum IS NOT NULL');
|
||||
$this->studentlistlib->addWhere('ps.bestaetigtam IS NULL');
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
$where['ps.bewerbung_abgeschicktamum IS NOT NULL'] = null;
|
||||
$where['ps.bestaetigtam'] = null;
|
||||
break;
|
||||
case "statusbestaetigt":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Interessent');
|
||||
$this->studentlistlib->addWhere('ps.bestaetigtam IS NOT NULL');
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
$where['ps.bestaetigtam IS NOT NULL'] = null;
|
||||
break;
|
||||
case "statusbestaetigtrtnichtangemeldet":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Interessent');
|
||||
$this->studentlistlib->addWhere('ps.bestaetigtam IS NOT NULL');
|
||||
$this->studentlistlib->addWhere('NOT EXISTS(' . $selectRT . ')', null, false);
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
$where['ps.bestaetigtam IS NOT NULL'] = null;
|
||||
$this->PrestudentModel->db->where('NOT EXISTS(' . $selectRT . ')', null, false);
|
||||
break;
|
||||
case "statusbestaetigtrtangemeldet":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Interessent');
|
||||
$this->studentlistlib->addWhere('ps.bestaetigtam IS NOT NULL');
|
||||
$this->studentlistlib->addWhere('EXISTS(' . $selectRT . ')', null, false);
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
$where['ps.bestaetigtam IS NOT NULL'] = null;
|
||||
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
|
||||
break;
|
||||
case "zgv":
|
||||
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
|
||||
@@ -347,69 +374,69 @@ class Students extends FHCAPI_Controller
|
||||
$this->terminateWithSuccess([]);
|
||||
$stg = current($stg);
|
||||
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Interessent');
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
|
||||
if ($stg->typ == 'm') {
|
||||
$this->studentlistlib->addWhere('zgvmas_code IS NOT NULL');
|
||||
$where['zgvmas_code IS NOT NULL'] = null;
|
||||
if (defined('ZGV_ERFUELLT_ANZEIGEN') && ZGV_ERFUELLT_ANZEIGEN)
|
||||
$this->studentlistlib->addWhere('zgvmas_erfuellt', true);
|
||||
$where['zgvmas_erfuellt'] = true;
|
||||
} elseif ($stg->typ == 'p') {
|
||||
$this->studentlistlib->addWhere('zgvdoktor_code IS NOT NULL');
|
||||
$where['zgvdoktor_code IS NOT NULL'] = null;
|
||||
if (defined('ZGV_DOKTOR_ANZEIGEN') && ZGV_DOKTOR_ANZEIGEN)
|
||||
$this->studentlistlib->addWhere('zgvdoktor_erfuellt', true);
|
||||
$where['zgvdoktor_erfuellt'] = true;
|
||||
} else {
|
||||
$this->studentlistlib->addWhere('zgv_code IS NOT NULL');
|
||||
$where['zgv_code IS NOT NULL'] = null;
|
||||
if (defined('ZGV_ERFUELLT_ANZEIGEN') && ZGV_ERFUELLT_ANZEIGEN)
|
||||
$this->studentlistlib->addWhere('zgv_erfuellt', true);
|
||||
$where['zgv_erfuellt'] = true;
|
||||
}
|
||||
break;
|
||||
case "reihungstestangemeldet":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Interessent');
|
||||
$this->studentlistlib->addWhere('EXISTS(' . $selectRT . ')', null, false);
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
|
||||
break;
|
||||
case "reihungstestnichtangemeldet":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Interessent');
|
||||
$this->studentlistlib->addWhere('NOT EXISTS(' . $selectRT . ')', null, false);
|
||||
$where['ps.status_kurzbz'] = 'Interessent';
|
||||
$this->PrestudentModel->db->where('NOT EXISTS(' . $selectRT . ')', null, false);
|
||||
break;
|
||||
case "bewerber":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Bewerber');
|
||||
$where['ps.status_kurzbz'] = 'Bewerber';
|
||||
break;
|
||||
case "bewerberrtnichtangemeldet":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Bewerber');
|
||||
$this->studentlistlib->addWhere('NOT EXISTS(' . $selectRT . ')', null, false);
|
||||
$where['ps.status_kurzbz'] = 'Bewerber';
|
||||
$this->PrestudentModel->db->where('NOT EXISTS(' . $selectRT . ')', null, false);
|
||||
break;
|
||||
case "bewerberrtangemeldet":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Bewerber');
|
||||
$this->studentlistlib->addWhere('EXISTS(' . $selectRT . ')', null, false);
|
||||
$where['ps.status_kurzbz'] = 'Bewerber';
|
||||
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
|
||||
break;
|
||||
case "bewerberrtangemeldetteilgenommen":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Bewerber');
|
||||
$this->studentlistlib->addWhere('EXISTS(' . $selectRT . ')', null, false);
|
||||
$this->studentlistlib->addWhere('reihungstestangetreten', true);
|
||||
$where['ps.status_kurzbz'] = 'Bewerber';
|
||||
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
|
||||
$where['reihungstestangetreten'] = true;
|
||||
break;
|
||||
case "bewerberrtangemeldetnichtteilgenommen":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Bewerber');
|
||||
$this->studentlistlib->addWhere('EXISTS(' . $selectRT . ')', null, false);
|
||||
$this->studentlistlib->addWhere('reihungstestangetreten', false);
|
||||
$where['ps.status_kurzbz'] = 'Bewerber';
|
||||
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
|
||||
$where['reihungstestangetreten'] = false;
|
||||
break;
|
||||
case "aufgenommen":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Aufgenommener');
|
||||
$where['ps.status_kurzbz'] = 'Aufgenommener';
|
||||
break;
|
||||
case "warteliste":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Wartender');
|
||||
$where['ps.status_kurzbz'] = 'Wartender';
|
||||
break;
|
||||
case "absage":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Abgewiesener');
|
||||
$where['ps.status_kurzbz'] = 'Abgewiesener';
|
||||
break;
|
||||
case "incoming":
|
||||
// NOTE(chris): in FAS it was not filtered for studiengang_kz
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Incoming');
|
||||
$where['ps.status_kurzbz'] = 'Incoming';
|
||||
break;
|
||||
case "absolvent":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Absolvent');
|
||||
$where['ps.status_kurzbz'] = 'Absolvent';
|
||||
break;
|
||||
case "diplomand":
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', 'Diplomand');
|
||||
$where['ps.status_kurzbz'] = 'Diplomand';
|
||||
break;
|
||||
default:
|
||||
if (!$studiensemester_kurzbz) {
|
||||
@@ -417,9 +444,9 @@ class Students extends FHCAPI_Controller
|
||||
* show all prestudents in this stg who don't have a status
|
||||
* $orgform_kurzbz does not change the results since orgform is stored in the status table
|
||||
*/
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz IS NULL');
|
||||
$where['ps.status_kurzbz'] = null;
|
||||
} else {
|
||||
$this->studentlistlib->addWhere('ps.status_kurzbz', [
|
||||
$this->PrestudentModel->db->where_in('ps.status_kurzbz', [
|
||||
'Interessent',
|
||||
'Bewerber',
|
||||
'Aufgenommener',
|
||||
@@ -430,19 +457,21 @@ class Students extends FHCAPI_Controller
|
||||
break;
|
||||
}
|
||||
|
||||
$this->studentlistlib->addSelect("
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect("
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
THEN ps.ausbildungssemester::text
|
||||
ELSE ''::text
|
||||
END AS semester", false);
|
||||
$this->studentlistlib->addSelect("'' AS verband");
|
||||
$this->studentlistlib->addSelect("'' AS gruppe");
|
||||
|
||||
$this->PrestudentModel->addSelect("'' AS verband");
|
||||
$this->PrestudentModel->addSelect("'' AS gruppe");
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
|
||||
$result = $this->PrestudentModel->loadWhere($where);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
@@ -545,6 +574,7 @@ class Students extends FHCAPI_Controller
|
||||
$gruppe_kurzbz = null,
|
||||
$orgform_kurzbz = null
|
||||
) {
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
|
||||
|
||||
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
|
||||
@@ -552,29 +582,34 @@ class Students extends FHCAPI_Controller
|
||||
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
|
||||
}
|
||||
|
||||
// NOTE(chris): overwrite 'LEFT JOIN' with 'JOIN'
|
||||
$this->studentlistlib->addJoin("public.tbl_student s", "prestudent_id");
|
||||
$this->prepareQuery($studiensemester_kurzbz, '');
|
||||
|
||||
$this->studentlistlib->addSelect("'' AS priorisierung_relativ");
|
||||
$this->PrestudentModel->addSelect('v.semester');
|
||||
$this->PrestudentModel->addSelect('v.verband');
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
$this->PrestudentModel->addSelect("'' AS priorisierung_relativ");
|
||||
|
||||
|
||||
$where = [];
|
||||
|
||||
if ($gruppe_kurzbz !== null) {
|
||||
$this->studentlistlib->addJoin('public.tbl_benutzergruppe g', 'uid', '', 'after_b');
|
||||
$this->studentlistlib->addWhere('g.gruppe_kurzbz', $gruppe_kurzbz);
|
||||
$this->studentlistlib->addWhere('g.studiensemester_kurzbz', $studiensemester_kurzbz);
|
||||
$this->PrestudentModel->addJoin('public.tbl_benutzergruppe g', 'uid');
|
||||
$where['g.gruppe_kurzbz'] = $gruppe_kurzbz;
|
||||
$where['g.studiensemester_kurzbz'] = $studiensemester_kurzbz;
|
||||
} else {
|
||||
$this->studentlistlib->addWhere('v.studiengang_kz', $studiengang_kz);
|
||||
$where['v.studiengang_kz'] = $studiengang_kz;
|
||||
|
||||
if ($semester !== null)
|
||||
$this->studentlistlib->addWhere('v.semester', $semester);
|
||||
$where['v.semester'] = $semester;
|
||||
|
||||
if ($verband !== null)
|
||||
$this->studentlistlib->addWhere('v.verband', $verband);
|
||||
$where['v.verband'] = $verband;
|
||||
|
||||
if ($gruppe !== null)
|
||||
$this->studentlistlib->addWhere('v.gruppe', $gruppe);
|
||||
$where['v.gruppe'] = $gruppe;
|
||||
|
||||
if (!$verband && !$gruppe && $orgform_kurzbz !== null) {
|
||||
$this->studentlistlib->addWhere(
|
||||
$this->PrestudentModel->db->where(
|
||||
"(
|
||||
SELECT orgform_kurzbz
|
||||
FROM public.tbl_prestudentstatus
|
||||
@@ -588,10 +623,9 @@ class Students extends FHCAPI_Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
|
||||
$result = $this->PrestudentModel->loadWhere($where);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
@@ -618,8 +652,11 @@ class Students extends FHCAPI_Controller
|
||||
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
|
||||
}
|
||||
|
||||
|
||||
$this->studentlistlib->addSelect("COALESCE(
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(
|
||||
v.semester::text,
|
||||
CASE
|
||||
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
@@ -627,15 +664,16 @@ class Students extends FHCAPI_Controller
|
||||
ELSE ''::text
|
||||
END
|
||||
) AS semester", false);
|
||||
$this->studentlistlib->addSelect("COALESCE(v.verband::text, ''::text) AS verband");
|
||||
$this->studentlistlib->addSelect("COALESCE(v.gruppe::text, ''::text) AS gruppe");
|
||||
|
||||
$this->studentlistlib->addWhere('tbl_prestudent.prestudent_id', $prestudent_id);
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
|
||||
$result = $this->PrestudentModel->loadWhere([
|
||||
'tbl_prestudent.prestudent_id' => $prestudent_id
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
@@ -662,13 +700,23 @@ class Students extends FHCAPI_Controller
|
||||
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
|
||||
}
|
||||
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect('v.semester');
|
||||
$this->PrestudentModel->addSelect('v.verband');
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
|
||||
$this->studentlistlib->addWhere('s.student_uid', $student_uid);
|
||||
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
|
||||
$result = $this->PrestudentModel->loadWhere([
|
||||
's.student_uid' => $student_uid
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
@@ -696,13 +744,21 @@ class Students extends FHCAPI_Controller
|
||||
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
|
||||
}
|
||||
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
$this->studentlistlib->addWhere('p.person_id', $person_id);
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect('v.semester');
|
||||
$this->PrestudentModel->addSelect('v.verband');
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
|
||||
$result = $this->PrestudentModel->loadWhere([
|
||||
'p.person_id' => $person_id
|
||||
]);
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
@@ -734,8 +790,29 @@ class Students extends FHCAPI_Controller
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
|
||||
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
$this->prepareQuery($studiensemester_kurzbz);
|
||||
|
||||
$this->PrestudentModel->addSelect("COALESCE(v.semester::text, CASE WHEN public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent') THEN public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)::text ELSE ''::text END) AS semester", false);
|
||||
$this->PrestudentModel->addSelect('v.verband');
|
||||
$this->PrestudentModel->addSelect('v.gruppe');
|
||||
|
||||
//add status per semester
|
||||
$this->PrestudentModel->addSelect(
|
||||
"public.get_rolle_prestudent(public.tbl_prestudent.prestudent_id, "
|
||||
. $this->PrestudentModel->escape($studiensemester_kurzbz)
|
||||
. ") AS statusofsemester"
|
||||
);
|
||||
|
||||
$this->addSelectPrioRel();
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$prestudent_ids = [];
|
||||
$student_uids = [];
|
||||
$this->addMeta('data', $data);
|
||||
foreach ($data as $row) {
|
||||
$dataset = json_decode($row->data);
|
||||
if ($row->type == 'prestudent') {
|
||||
@@ -745,38 +822,197 @@ class Students extends FHCAPI_Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$this->studentlistlib->addSelect("COALESCE(
|
||||
v.semester::text,
|
||||
CASE
|
||||
WHEN public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
|
||||
THEN public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)::text
|
||||
ELSE ''::text
|
||||
END
|
||||
) AS semester", false);
|
||||
|
||||
|
||||
if ($prestudent_ids && $student_uids) {
|
||||
$this->studentlistlib->addWhere('tbl_prestudent.prestudent_id', $prestudent_ids);
|
||||
$this->studentlistlib->addOrWhere('s.student_uid', $student_uids);
|
||||
$this->PrestudentModel->db->where_in('tbl_prestudent.prestudent_id', $prestudent_ids);
|
||||
$this->PrestudentModel->db->or_where_in('s.student_uid', $student_uids);
|
||||
} elseif ($prestudent_ids) {
|
||||
$this->studentlistlib->addWhere('tbl_prestudent.prestudent_id', $prestudent_ids);
|
||||
$this->PrestudentModel->db->where_in('tbl_prestudent.prestudent_id', $prestudent_ids);
|
||||
} elseif ($student_uids) {
|
||||
$this->studentlistlib->addWhere('s.student_uid', $student_uids);
|
||||
$this->PrestudentModel->db->where_in('s.student_uid', $student_uids);
|
||||
} else {
|
||||
$this->terminateWithSuccess([]);
|
||||
}
|
||||
|
||||
|
||||
$this->addFilter($studiensemester_kurzbz);
|
||||
|
||||
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
|
||||
$result = $this->PrestudentModel->load();
|
||||
|
||||
$data = $this->getDataOrTerminateWithError($result);
|
||||
|
||||
$this->terminateWithSuccess($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $studiensemester_kurzbz
|
||||
* @param string $type
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function prepareQuery($studiensemester_kurzbz, $type = 'LEFT')
|
||||
{
|
||||
$stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
|
||||
|
||||
$this->load->config('stv');
|
||||
|
||||
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
|
||||
{
|
||||
$tags = $this->config->item('stv_prestudent_tags');
|
||||
|
||||
$whereTags = '';
|
||||
if (is_array($tags) && !isEmptyArray($tags)) {
|
||||
$tags = array_keys($tags);
|
||||
|
||||
foreach ($tags as $key => $tag) {
|
||||
$tags[$key] = $this->db->escape($tag);
|
||||
}
|
||||
$whereTags = " AND nt.typ_kurzbz IN (" . implode(",", $tags) . ")";
|
||||
}
|
||||
$subQueryTag = "
|
||||
(
|
||||
SELECT
|
||||
tag.prestudent_id,
|
||||
COALESCE(json_agg(tag ORDER BY tag.done), '[]'::json) AS tags
|
||||
FROM (
|
||||
SELECT DISTINCT ON (n.notiz_id)
|
||||
n.notiz_id AS id,
|
||||
nt.typ_kurzbz,
|
||||
array_to_json(nt.bezeichnung_mehrsprachig)->>0 AS beschreibung,
|
||||
n.text AS notiz,
|
||||
nt.style,
|
||||
n.erledigt AS done,
|
||||
nz.prestudent_id
|
||||
FROM public.tbl_notizzuordnung AS nz
|
||||
JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id
|
||||
JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz "
|
||||
. $whereTags .
|
||||
"
|
||||
) AS tag
|
||||
GROUP BY tag.prestudent_id
|
||||
) AS tag_data_agg
|
||||
";
|
||||
}
|
||||
|
||||
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
|
||||
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', $type);
|
||||
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus pls', '
|
||||
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.prestudent_id=tbl_prestudent.prestudent_id
|
||||
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
|
||||
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid', 'LEFT');
|
||||
$this->PrestudentModel->addJoin(
|
||||
'public.tbl_studentlehrverband v',
|
||||
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz' . ($studiensemester_kurzbz ? '=' . $stdsemEsc : ' IS NULL'),
|
||||
$type
|
||||
);
|
||||
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus ps', '
|
||||
ps.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
|
||||
AND ps.prestudent_id=tbl_prestudent.prestudent_id
|
||||
AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
|
||||
AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')', 'LEFT');
|
||||
|
||||
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
|
||||
{
|
||||
$this->PrestudentModel->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT');
|
||||
}
|
||||
|
||||
|
||||
$this->PrestudentModel->addSelect("b.uid");
|
||||
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
|
||||
{
|
||||
$this->PrestudentModel->addSelect('tag_data_agg.tags');
|
||||
}
|
||||
$this->PrestudentModel->addSelect('titelpre');
|
||||
$this->PrestudentModel->addSelect('nachname');
|
||||
$this->PrestudentModel->addSelect('vorname');
|
||||
$this->PrestudentModel->addSelect('wahlname');
|
||||
$this->PrestudentModel->addSelect('vornamen');
|
||||
$this->PrestudentModel->addSelect('titelpost');
|
||||
$this->PrestudentModel->addSelect('ersatzkennzeichen');
|
||||
$this->PrestudentModel->addSelect('gebdatum');
|
||||
$this->PrestudentModel->addSelect('geschlecht');
|
||||
$this->PrestudentModel->addSelect('foto');
|
||||
$this->PrestudentModel->addSelect('foto_sperre');
|
||||
|
||||
// semester
|
||||
// verband
|
||||
// gruppe
|
||||
|
||||
//add status per semester
|
||||
$this->PrestudentModel->addSelect(
|
||||
"public.get_rolle_prestudent(public.tbl_prestudent.prestudent_id, "
|
||||
. $this->PrestudentModel->escape($studiensemester_kurzbz)
|
||||
. ") AS statusofsemester"
|
||||
);
|
||||
|
||||
$this->PrestudentModel->addSelect('UPPER(stg.typ || stg.kurzbz) AS studiengang');
|
||||
$this->PrestudentModel->addSelect('tbl_prestudent.studiengang_kz');
|
||||
$this->PrestudentModel->addSelect('stg.bezeichnung AS stg_bezeichnung');
|
||||
$this->PrestudentModel->addSelect("s.matrikelnr");
|
||||
$this->PrestudentModel->addSelect('p.person_id');
|
||||
$this->PrestudentModel->addSelect('pls.status_kurzbz AS status');
|
||||
$this->PrestudentModel->addSelect('pls.datum AS status_datum');
|
||||
$this->PrestudentModel->addSelect('pls.bestaetigtam AS status_bestaetigung');
|
||||
$this->PrestudentModel->addSelect(
|
||||
"(SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp='email' AND person_id=p.person_id AND zustellung LIMIT 1) AS mail_privat",
|
||||
false
|
||||
);
|
||||
$this->PrestudentModel->addSelect("
|
||||
CASE WHEN b.uid IS NOT NULL AND b.uid<>''
|
||||
THEN CONCAT(b.uid, '@', " . $this->PrestudentModel->escape(DOMAIN) . ")
|
||||
ELSE '' END AS mail_intern", false);
|
||||
$this->PrestudentModel->addSelect('p.anmerkung AS anmerkungen');
|
||||
$this->PrestudentModel->addSelect('tbl_prestudent.anmerkung');
|
||||
$this->PrestudentModel->addSelect('pls.orgform_kurzbz');
|
||||
$this->PrestudentModel->addSelect('aufmerksamdurch_kurzbz');
|
||||
$this->PrestudentModel->addSelect(
|
||||
"(SELECT rt_gesamtpunkte AS punkte FROM public.tbl_prestudent WHERE prestudent_id=ps.prestudent_id) AS punkte",
|
||||
false
|
||||
);
|
||||
$this->PrestudentModel->addSelect('tbl_prestudent.aufnahmegruppe_kurzbz');
|
||||
$this->PrestudentModel->addSelect('tbl_prestudent.dual');
|
||||
$this->PrestudentModel->addSelect('p.matr_nr');
|
||||
$this->PrestudentModel->addSelect('sp.bezeichnung AS studienplan_bezeichnung');
|
||||
$this->PrestudentModel->addSelect('tbl_prestudent.prestudent_id');
|
||||
|
||||
// priorisierung_relativ
|
||||
|
||||
$this->PrestudentModel->addSelect('mentor');
|
||||
$this->PrestudentModel->addSelect('b.aktiv AS bnaktiv');
|
||||
$this->PrestudentModel->addSelect('unruly');
|
||||
|
||||
$this->PrestudentModel->db->where_in('tbl_prestudent.studiengang_kz', $this->allowedStgs);
|
||||
|
||||
$this->PrestudentModel->addOrder('nachname');
|
||||
$this->PrestudentModel->addOrder('vorname');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function addSelectPrioRel()
|
||||
{
|
||||
$this->PrestudentModel->addSelect("(
|
||||
SELECT count(*)
|
||||
FROM (
|
||||
SELECT *, public.get_rolle_prestudent(pss.prestudent_id, NULL) AS laststatus
|
||||
FROM public.tbl_prestudent pss
|
||||
JOIN public.tbl_prestudentstatus USING (prestudent_id)
|
||||
WHERE person_id = p.person_id
|
||||
AND studiensemester_kurzbz = (
|
||||
SELECT studiensemester_kurzbz
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE prestudent_id = tbl_prestudent.prestudent_id
|
||||
AND status_kurzbz = 'Interessent'
|
||||
LIMIT 1
|
||||
)
|
||||
AND status_kurzbz = 'Interessent'
|
||||
) prest
|
||||
WHERE laststatus NOT IN ('Abbrecher', 'Abgewiesener', 'Absolvent')
|
||||
AND priorisierung <= tbl_prestudent.priorisierung
|
||||
) || ' (' || COALESCE(tbl_prestudent.priorisierung::text, ' '::text) || ')' AS priorisierung_relativ", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds additional filters to the query
|
||||
*
|
||||
|
||||
@@ -417,7 +417,6 @@ abstract class Notiz_Controller extends FHCAPI_Controller
|
||||
$notiz_id = $this->input->post('notiz_id');
|
||||
|
||||
$this->NotizModel->addSelect('campus.tbl_dms_version.*');
|
||||
$this->NotizModel->addSelect($this->NotizModel->escape(base_url('content/notizdokdownload.php?id=')) . ' || public.tbl_notiz_dokument.dms_id AS preview');
|
||||
|
||||
$this->NotizModel->addJoin('public.tbl_notiz_dokument', 'ON (public.tbl_notiz_dokument.notiz_id = public.tbl_notiz.notiz_id)');
|
||||
$this->NotizModel->addJoin('campus.tbl_dms_version', 'ON (public.tbl_notiz_dokument.dms_id = campus.tbl_dms_version.dms_id)');
|
||||
|
||||
@@ -1,363 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright (C) 2025 fhcomplete.org
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* This generates a list of students and or prestudents used for Studierendenverwaltung
|
||||
*/
|
||||
class StudentListLib
|
||||
{
|
||||
private $_ci; // Code igniter instance
|
||||
|
||||
private $_allowedStgs = [];
|
||||
private $_selects = [];
|
||||
private $_joins = [];
|
||||
|
||||
/**
|
||||
* Gets the CI instance, loads model and prepares default values
|
||||
*
|
||||
* @param array $params
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($params = null)
|
||||
{
|
||||
$this->_ci =& get_instance(); // get code igniter instance
|
||||
|
||||
$this->_ci->load->model('crm/Prestudent_model', 'PrestudentModel');
|
||||
|
||||
if (isset($params['allowedStgs']))
|
||||
$this->_allowedStgs = $params['allowedStgs'];
|
||||
|
||||
// Add default SELECTs
|
||||
$this->addSelect("b.uid");
|
||||
if (defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
|
||||
$this->addSelect('tag_data_agg.tags');
|
||||
$this->addSelect('titelpre');
|
||||
$this->addSelect('nachname');
|
||||
$this->addSelect('vorname');
|
||||
$this->addSelect('wahlname');
|
||||
$this->addSelect('vornamen');
|
||||
$this->addSelect('titelpost');
|
||||
$this->addSelect('ersatzkennzeichen');
|
||||
$this->addSelect('gebdatum');
|
||||
$this->addSelect('geschlecht');
|
||||
$this->addSelect('foto');
|
||||
$this->addSelect('foto_sperre');
|
||||
$this->addSelect('v.semester');
|
||||
$this->addSelect('v.verband');
|
||||
$this->addSelect('v.gruppe');
|
||||
$this->addSelect("statusofsemester"); // Will be replaced later
|
||||
$this->addSelect('UPPER(stg.typ || stg.kurzbz) AS studiengang');
|
||||
$this->addSelect('tbl_prestudent.studiengang_kz');
|
||||
$this->addSelect('stg.bezeichnung AS stg_bezeichnung');
|
||||
$this->addSelect("s.matrikelnr");
|
||||
$this->addSelect('p.person_id');
|
||||
$this->addSelect('pls.status_kurzbz AS status');
|
||||
$this->addSelect('pls.datum AS status_datum');
|
||||
$this->addSelect('pls.bestaetigtam AS status_bestaetigung');
|
||||
$this->addSelect(
|
||||
"(SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp='email' AND person_id=p.person_id AND zustellung LIMIT 1) AS mail_privat",
|
||||
false
|
||||
);
|
||||
$this->addSelect("
|
||||
CASE WHEN b.uid IS NOT NULL AND b.uid<>''
|
||||
THEN CONCAT(b.uid, '@', " . $this->_ci->PrestudentModel->escape(DOMAIN) . ")
|
||||
ELSE '' END AS mail_intern", false);
|
||||
$this->addSelect('p.anmerkung AS anmerkungen');
|
||||
$this->addSelect('tbl_prestudent.anmerkung');
|
||||
$this->addSelect('pls.orgform_kurzbz');
|
||||
$this->addSelect('aufmerksamdurch_kurzbz');
|
||||
$this->addSelect(
|
||||
"(SELECT rt_gesamtpunkte AS punkte FROM public.tbl_prestudent WHERE prestudent_id=ps.prestudent_id) AS punkte",
|
||||
false
|
||||
);
|
||||
$this->addSelect('tbl_prestudent.aufnahmegruppe_kurzbz');
|
||||
$this->addSelect('tbl_prestudent.dual');
|
||||
$this->addSelect('p.matr_nr');
|
||||
$this->addSelect('sp.bezeichnung AS studienplan_bezeichnung');
|
||||
$this->addSelect('tbl_prestudent.prestudent_id');
|
||||
$this->addSelect("(
|
||||
SELECT count(*)
|
||||
FROM (
|
||||
SELECT *, public.get_rolle_prestudent(pss.prestudent_id, NULL) AS laststatus
|
||||
FROM public.tbl_prestudent pss
|
||||
JOIN public.tbl_prestudentstatus USING (prestudent_id)
|
||||
WHERE person_id = p.person_id
|
||||
AND studiensemester_kurzbz = (
|
||||
SELECT studiensemester_kurzbz
|
||||
FROM public.tbl_prestudentstatus
|
||||
WHERE prestudent_id = tbl_prestudent.prestudent_id
|
||||
AND status_kurzbz = 'Interessent'
|
||||
LIMIT 1
|
||||
)
|
||||
AND status_kurzbz = 'Interessent'
|
||||
) prest
|
||||
WHERE laststatus NOT IN ('Abbrecher', 'Abgewiesener', 'Absolvent')
|
||||
AND priorisierung <= tbl_prestudent.priorisierung
|
||||
) || ' (' || COALESCE(tbl_prestudent.priorisierung::text, ' '::text) || ')' AS priorisierung_relativ", false); // TODO(chris): overwrite in fetchStudents
|
||||
$this->addSelect('mentor');
|
||||
$this->addSelect('b.aktiv AS bnaktiv');
|
||||
$this->addSelect('unruly');
|
||||
|
||||
// Add default JOINs
|
||||
$this->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
|
||||
$this->addJoin('public.tbl_person p', 'person_id');
|
||||
$this->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT'); // TODO(chris): overwrite in fetchStudents
|
||||
$this->addJoin('public.tbl_prestudentstatus pls', '
|
||||
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.prestudent_id=tbl_prestudent.prestudent_id
|
||||
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
|
||||
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
|
||||
$this->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
|
||||
$this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid', 'LEFT');
|
||||
$this->addJoin("v", "", ""); // Will be replaced later
|
||||
$this->addJoin("ps", "", ""); // Will be replaced later
|
||||
if (defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED) {
|
||||
$this->_ci->load->config('stv');
|
||||
$tags = $this->_ci->config->item('stv_prestudent_tags');
|
||||
|
||||
$whereTags = '';
|
||||
if (is_array($tags) && !isEmptyArray($tags)) {
|
||||
$tags = array_keys($tags);
|
||||
|
||||
foreach ($tags as $key => $tag) {
|
||||
$tags[$key] = $this->_ci->PrestudentModel->escape($tag);
|
||||
}
|
||||
$whereTags = " AND nt.typ_kurzbz IN (" . implode(",", $tags) . ")";
|
||||
}
|
||||
$subQueryTag = "(
|
||||
SELECT
|
||||
tag.prestudent_id,
|
||||
COALESCE(json_agg(tag ORDER BY tag.done), '[]'::json) AS tags
|
||||
FROM (
|
||||
SELECT DISTINCT ON (n.notiz_id)
|
||||
n.notiz_id AS id,
|
||||
nt.typ_kurzbz,
|
||||
array_to_json(nt.bezeichnung_mehrsprachig)->>0 AS beschreibung,
|
||||
n.text AS notiz,
|
||||
nt.style,
|
||||
n.erledigt AS done,
|
||||
nz.prestudent_id
|
||||
FROM public.tbl_notizzuordnung AS nz
|
||||
JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id
|
||||
JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz " . $whereTags . "
|
||||
) AS tag
|
||||
GROUP BY tag.prestudent_id
|
||||
) AS tag_data_agg";
|
||||
|
||||
$this->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT');
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Public methods
|
||||
|
||||
/**
|
||||
* Adds a SELECT statement to the query.
|
||||
*
|
||||
* @param string|array $select
|
||||
* @param boolean $escape (optional)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addSelect($select, $escape = true)
|
||||
{
|
||||
if (is_array($select)) {
|
||||
foreach ($select as $s)
|
||||
$this->addSelect($s, $escape);
|
||||
return;
|
||||
}
|
||||
$alias = $this->getAliasFromSelect($select);
|
||||
$this->_selects[$alias] = [$select, $escape];
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins a table to the query.
|
||||
*
|
||||
* @param string $table
|
||||
* @param string $cond
|
||||
* @param string $type (optional)
|
||||
* @param string $position (optional)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addJoin($table, $cond, $type = '', $position = 'end')
|
||||
{
|
||||
$alias = $this->getAliasFromTable($table);
|
||||
|
||||
if ($position == 'end') {
|
||||
return $this->_joins[$alias] = [$table, $cond, $type];
|
||||
}
|
||||
|
||||
if ($position == 'start') {
|
||||
return $this->_joins = [$alias => [$table, $cond, $type]] + $this->_joins;
|
||||
}
|
||||
|
||||
if (substr($position, 0, 7) == 'before_') {
|
||||
$ref = substr($position, 7);
|
||||
$index = 0;
|
||||
} elseif (substr($position, 0, 6) == 'after_') {
|
||||
$ref = substr($position, 6);
|
||||
$index = 1;
|
||||
} else {
|
||||
return $this->addJoin($table, $cond, $type);
|
||||
}
|
||||
if (!isset($this->_joins[$ref]))
|
||||
return $this->addJoin($table, $cond, $type);
|
||||
|
||||
$key_indeces = array_flip(array_keys($this->_joins));
|
||||
$index += $key_indeces[$ref];
|
||||
|
||||
if (!$index)
|
||||
return $this->addJoin($table, $cond, $type, 'start');
|
||||
|
||||
$front_part = array_slice($this->_joins, 0, $index, true);
|
||||
$back_part = array_slice($this->_joins, $index, null, true);
|
||||
|
||||
if (isset($front_part[$alias])) {
|
||||
unset($front_part[$alias]);
|
||||
}
|
||||
|
||||
$this->_joins = $front_part + [$alias => [$table, $cond, $type]] + $back_part;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a WHERE clause to the query.
|
||||
*
|
||||
* @param string|array $key
|
||||
* @param string|array $value
|
||||
* @param boolean $escape
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addWhere($key, $value = null, $escape = true)
|
||||
{
|
||||
if (!is_array($key) && is_array($value)) {
|
||||
$this->_ci->PrestudentModel->db->where_in($key, $value, $escape);
|
||||
} else {
|
||||
$this->_ci->PrestudentModel->db->where($key, $value, $escape);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a OR WHERE clause to the query.
|
||||
*
|
||||
* @param string|array $key
|
||||
* @param string|array $value
|
||||
* @param boolean $escape
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addOrWhere($key, $value = null, $escape = true)
|
||||
{
|
||||
if (!is_array($key) && is_array($value)) {
|
||||
$this->_ci->PrestudentModel->db->or_where_in($key, $value, $escape);
|
||||
} else {
|
||||
$this->_ci->PrestudentModel->db->or_where($key, $value, $escape);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the query and executes it.
|
||||
*
|
||||
* @param string|null $studiensemester_kurzbz
|
||||
*
|
||||
* @return stdClass result of the query
|
||||
*/
|
||||
public function execute($studiensemester_kurzbz)
|
||||
{
|
||||
$stdsemEsc = $studiensemester_kurzbz ? $this->_ci->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
|
||||
|
||||
|
||||
$this->addSelect(
|
||||
"public.get_rolle_prestudent(
|
||||
public.tbl_prestudent.prestudent_id,
|
||||
" . $this->_ci->PrestudentModel->escape($studiensemester_kurzbz) . "
|
||||
) AS statusofsemester"
|
||||
);
|
||||
$this->addJoin(
|
||||
'public.tbl_studentlehrverband v',
|
||||
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz' . ($studiensemester_kurzbz ? '=' . $stdsemEsc : ' IS NULL'),
|
||||
'LEFT'
|
||||
);
|
||||
$this->addJoin(
|
||||
'public.tbl_prestudentstatus ps',
|
||||
'ps.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
|
||||
AND ps.prestudent_id=tbl_prestudent.prestudent_id
|
||||
AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
|
||||
AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
|
||||
',
|
||||
'LEFT'
|
||||
);
|
||||
|
||||
$this->addWhere('tbl_prestudent.studiengang_kz', $this->_allowedStgs);
|
||||
|
||||
foreach ($this->_joins as $join)
|
||||
$this->_ci->PrestudentModel->addJoin($join[0], $join[1], $join[2]);
|
||||
|
||||
foreach ($this->_selects as $select)
|
||||
$this->_ci->PrestudentModel->addSelect($select[0], $select[1]);
|
||||
|
||||
$this->_ci->PrestudentModel->addOrder('nachname');
|
||||
$this->_ci->PrestudentModel->addOrder('vorname');
|
||||
|
||||
return $this->_ci->PrestudentModel->load();
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
// Protected methods
|
||||
|
||||
/**
|
||||
* Get alias of a table or select statement
|
||||
*
|
||||
* @param string $select
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
final protected function getAliasFromSelect($select)
|
||||
{
|
||||
if (strpos($select, ' ') !== false) {
|
||||
return trim(strrchr($select, ' '));
|
||||
}
|
||||
|
||||
if (strpos($select, '.') !== false) {
|
||||
return substr(strrchr($select, '.'), 1);
|
||||
}
|
||||
|
||||
return $select;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alias of a table or select statement
|
||||
*
|
||||
* @param string|array $table
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
final protected function getAliasFromTable($table)
|
||||
{
|
||||
if (strpos($table, ' ') !== false) {
|
||||
return trim(strrchr($table, ' '));
|
||||
}
|
||||
|
||||
return $table;
|
||||
}
|
||||
}
|
||||
@@ -40,9 +40,7 @@ abstract class AbstractBestandteil implements IValidation
|
||||
|
||||
if( is_bool($new_value) && ($old_value !== $new_value) ) {
|
||||
$this->modifiedcolumns[$columnname] = $columnname;
|
||||
} else if(is_null($old_value) xor is_null($new_value)) {
|
||||
$this->modifiedcolumns[$columnname] = $columnname;
|
||||
} else if($old_value != $new_value) {
|
||||
} else if($old_value != $new_value) {
|
||||
$this->modifiedcolumns[$columnname] = $columnname;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,25 +137,19 @@ EOTXT;
|
||||
return parent::__toString() . $txt;
|
||||
}
|
||||
|
||||
public function validate()
|
||||
/* public function validate()
|
||||
{
|
||||
$value = $this->vordienstzeit;
|
||||
|
||||
if ($value === null || $value === '') {
|
||||
$result = null; // allow null value
|
||||
} else {
|
||||
$result = filter_var($value, FILTER_VALIDATE_INT, [
|
||||
'options' => [
|
||||
'min_range' => 0,
|
||||
'max_range' => 100
|
||||
]
|
||||
]);
|
||||
|
||||
if ($result === false) {
|
||||
$this->validationerrors[] = 'Vordienstjahre muss eine ganze Zahl (0 bis 100) enthalten oder leer sein.';
|
||||
}
|
||||
if( !(filter_var($this->tage, FILTER_VALIDATE_INT,
|
||||
array(
|
||||
'options' => array(
|
||||
'min_range' => 1,
|
||||
'max_range' => 50
|
||||
)
|
||||
)
|
||||
)) ) {
|
||||
$this->validationerrors[] = 'Urlaubsanspruch muss eine Tagesanzahl im Bereich 1 bis 50 sein.';
|
||||
}
|
||||
|
||||
return parent::validate();
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
@@ -341,172 +341,130 @@ class Projektarbeit_model extends DB_Model
|
||||
|
||||
|
||||
public function getProjektarbeitenForStudiengang($studiengang_kz, $benotet) {
|
||||
$new_qry = "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,
|
||||
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 as sprache,
|
||||
lehre.tbl_projektarbeit.seitenanzahl as seitenanzahl,
|
||||
lehre.tbl_projektarbeit.kontrollschlagwoerter as kontrollschlagwoerter,
|
||||
lehre.tbl_projektarbeit.schlagwoerter as schlagwoerter,
|
||||
lehre.tbl_projektarbeit.schlagwoerter_en as schlagwoerter_en,
|
||||
lehre.tbl_projektarbeit.abstract as abstract,
|
||||
lehre.tbl_projektarbeit.abstract_en as abstract_en,
|
||||
lehre.tbl_projektarbeit.insertamum as insertamum,
|
||||
lehre.tbl_projektarbeit.note as note,
|
||||
(
|
||||
SELECT orgform_kurzbz
|
||||
FROM tbl_prestudentstatus
|
||||
WHERE prestudent_id = (SELECT prestudent_id
|
||||
FROM tbl_student
|
||||
WHERE student_uid = student_benutzer.uid
|
||||
LIMIT 1)
|
||||
ORDER BY datum DESC, insertamum DESC, ext_id DESC
|
||||
LIMIT 1
|
||||
)
|
||||
as organisationsform,
|
||||
(
|
||||
SELECT person_id
|
||||
FROM lehre.tbl_projektbetreuer
|
||||
WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied')
|
||||
LIMIT 1
|
||||
)
|
||||
AS zweitbetreuer_person_id,
|
||||
(
|
||||
SELECT betreuerart_kurzbz
|
||||
FROM lehre.tbl_projektbetreuer
|
||||
WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied')
|
||||
LIMIT 1
|
||||
)
|
||||
AS zweitbetreuer_betreuerart_kurzbz,
|
||||
(
|
||||
SELECT tbl_betreuerart.beschreibung
|
||||
FROM lehre.tbl_projektbetreuer
|
||||
JOIN lehre.tbl_betreuerart USING (betreuerart_kurzbz)
|
||||
WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied')
|
||||
LIMIT 1
|
||||
)
|
||||
AS zweitbetreuer_betreuerart_beschreibung,
|
||||
(
|
||||
SELECT trim(COALESCE(titelpre, '') || ' ' || COALESCE(vorname, '') || ' ' || COALESCE(nachname, '') || ' ' ||
|
||||
COALESCE(titelpost, ''))
|
||||
FROM public.tbl_person
|
||||
JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid)
|
||||
WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied')
|
||||
LIMIT 1
|
||||
)
|
||||
as zweitbetreuer_full_name,
|
||||
(
|
||||
SELECT titelpre
|
||||
FROM public.tbl_person
|
||||
JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid)
|
||||
WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied')
|
||||
LIMIT 1
|
||||
)
|
||||
as zweitbetreuer_titelpre,
|
||||
(
|
||||
SELECT vorname
|
||||
FROM public.tbl_person
|
||||
JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid)
|
||||
WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied')
|
||||
LIMIT 1
|
||||
)
|
||||
as zweitbetreuer_vorname,
|
||||
(
|
||||
SELECT nachname
|
||||
FROM public.tbl_person
|
||||
JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid)
|
||||
WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied')
|
||||
LIMIT 1
|
||||
)
|
||||
as zweitbetreuer_nachname,
|
||||
(
|
||||
SELECT titelpost
|
||||
FROM public.tbl_person
|
||||
JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
|
||||
LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid)
|
||||
WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id
|
||||
AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied')
|
||||
LIMIT 1
|
||||
)
|
||||
as zweitbetreuer_titelpost,
|
||||
(
|
||||
SELECT
|
||||
COALESCE(tbl_studienplan.orgform_kurzbz,
|
||||
tbl_prestudentstatus.orgform_kurzbz, tbl_studiengang.orgform_kurzbz) as
|
||||
orgform
|
||||
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=tbl_student.prestudent_id
|
||||
ORDER BY tbl_prestudentstatus.datum DESC LIMIT 1
|
||||
) as orgform,
|
||||
(SELECT status_kurzbz FROM public.tbl_prestudentstatus
|
||||
WHERE prestudent_id=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)
|
||||
WHERE (projekttyp_kurzbz = 'Bachelor' OR projekttyp_kurzbz = 'Diplom')
|
||||
AND student_benutzer.aktiv AND (
|
||||
lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Erstbegutachter'
|
||||
OR lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Begutachter'
|
||||
OR lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Betreuer'
|
||||
OR lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Erstbetreuer'
|
||||
OR lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Senatsvorsitz'
|
||||
)
|
||||
AND public.tbl_studiengang.studiengang_kz = ?";
|
||||
$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
|
||||
)
|
||||
|
||||
if($benotet == 0) {
|
||||
$new_qry .= " AND lehre.tbl_projektarbeit.note IS NULL ";
|
||||
} else if ($benotet == 1) {
|
||||
$new_qry .= " AND lehre.tbl_projektarbeit.note IS NOT NULL ";
|
||||
}
|
||||
|
||||
$new_qry .= " ORDER BY tbl_projektarbeit.projektarbeit_id DESC, student_person.nachname ASC
|
||||
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 -- ← THE NEW LINE
|
||||
|
||||
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_studiengang.studiengang_kz = ?";
|
||||
|
||||
if($benotet == 0) {
|
||||
$new_qry .= " AND lehre.tbl_projektarbeit.note IS NULL ";
|
||||
} else if ($benotet == 1) {
|
||||
$new_qry .= " AND lehre.tbl_projektarbeit.note IS NOT NULL ";
|
||||
}
|
||||
|
||||
$new_qry .= " ORDER BY tbl_projektarbeit.projektarbeit_id DESC, student_person.nachname ASC
|
||||
) as tmp";
|
||||
|
||||
return $this->execReadOnlyQuery($new_qry, array($studiengang_kz));
|
||||
|
||||
@@ -38,7 +38,7 @@ $includesArray = array(
|
||||
|
||||
$this->load->view('templates/FHC-Header', $includesArray);
|
||||
?>
|
||||
<div id="abgabetoolroot" class="h-100" style="max-width: 95%;" route=<?php echo json_encode($route) ?>
|
||||
<div id="abgabetoolroot" class="h-100" style="max-width: 99%" route=<?php echo json_encode($route) ?>
|
||||
uid=<?php echo $uid ?>
|
||||
student_uid_prop="<?php echo $student_uid_prop ?? '' ?>"
|
||||
stg_kz_prop="<?php echo $stg_kz_prop ?? '' ?>"
|
||||
|
||||
@@ -315,15 +315,22 @@
|
||||
WHERE tpl.app = '.$APP.'
|
||||
) pl USING(person_id)
|
||||
LEFT JOIN (
|
||||
SELECT DISTINCT ON (tbl_rueckstellung.person_id)
|
||||
SELECT
|
||||
tbl_rueckstellung.person_id,
|
||||
tbl_rueckstellung.datum_bis,
|
||||
tbl_rueckstellung.status_kurzbz,
|
||||
array_to_json(bezeichnung_mehrsprachig::varchar[])->>0 as bezeichnung
|
||||
FROM public.tbl_rueckstellung
|
||||
JOIN public.tbl_rueckstellung_status USING(status_kurzbz)
|
||||
WHERE tbl_rueckstellung.datum_bis >= NOW()
|
||||
ORDER BY tbl_rueckstellung.person_id, tbl_rueckstellung.datum_bis DESC
|
||||
JOIN public.tbl_person sp ON tbl_rueckstellung.person_id = sp.person_id
|
||||
WHERE tbl_rueckstellung.rueckstellung_id =
|
||||
(
|
||||
SELECT srueck.rueckstellung_id
|
||||
FROM public.tbl_rueckstellung srueck
|
||||
WHERE srueck.person_id = tbl_rueckstellung.person_id
|
||||
AND datum_bis >= NOW()
|
||||
ORDER BY srueck.datum_bis DESC LIMIT 1
|
||||
)
|
||||
) rueck ON rueck.person_id = p.person_id
|
||||
WHERE
|
||||
EXISTS (
|
||||
|
||||
@@ -24,15 +24,22 @@ $query = '
|
||||
WHERE tpl.app = '.$APP.'
|
||||
) pl ON p.person_id = pl.person_id
|
||||
LEFT JOIN (
|
||||
SELECT DISTINCT ON (tbl_rueckstellung.person_id)
|
||||
SELECT
|
||||
tbl_rueckstellung.person_id,
|
||||
tbl_rueckstellung.datum_bis,
|
||||
tbl_rueckstellung.status_kurzbz,
|
||||
array_to_json(bezeichnung_mehrsprachig::varchar[])->>0 as bezeichnung
|
||||
FROM public.tbl_rueckstellung
|
||||
JOIN public.tbl_rueckstellung_status USING(status_kurzbz)
|
||||
WHERE tbl_rueckstellung.datum_bis >= NOW()
|
||||
ORDER BY tbl_rueckstellung.person_id, tbl_rueckstellung.datum_bis DESC
|
||||
JOIN public.tbl_rueckstellung_status USING(status_kurzbz)
|
||||
JOIN public.tbl_person sp ON tbl_rueckstellung.person_id = sp.person_id
|
||||
WHERE tbl_rueckstellung.rueckstellung_id =
|
||||
(
|
||||
SELECT srueck.rueckstellung_id
|
||||
FROM public.tbl_rueckstellung srueck
|
||||
WHERE srueck.person_id = tbl_rueckstellung.person_id
|
||||
AND datum_bis >= NOW()
|
||||
ORDER BY srueck.datum_bis DESC LIMIT 1
|
||||
)
|
||||
) rueck ON rueck.person_id = p.person_id
|
||||
WHERE p.person_id NOT IN (SELECT person_id FROM public.tbl_prestudent)';
|
||||
|
||||
|
||||
+11
-75
@@ -80,17 +80,9 @@ echo '
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/xhtml; charset=UTF-8" />
|
||||
<link rel="stylesheet" href="../../vendor/components/jqueryui/themes/base/jquery-ui.min.css" type="text/css" />
|
||||
<link rel="stylesheet" href="../../vendor/twbs/bootstrap3/dist/css/bootstrap.min.css" type="text/css"/>
|
||||
<link href="../../skin/style.css.php" rel="stylesheet" type="text/css" />
|
||||
<style>
|
||||
.ui-dialog-titlebar-close
|
||||
{
|
||||
visibility: hidden !important;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="../../vendor/components/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="../../vendor/components/jqueryui/jquery-ui.min.js"></script>
|
||||
<script type="text/javascript" src="../../vendor/twbs/bootstrap3/dist/js/bootstrap.min.js"></script>
|
||||
<script language="Javascript" type="text/javascript">
|
||||
//<![CDATA[
|
||||
@@ -139,78 +131,22 @@ echo '
|
||||
}
|
||||
}
|
||||
|
||||
function GebietStarten(bezeichnung, stunde, minute, sekunde, gebiet_id)
|
||||
function GebietStarten(bezeichnung,stunde,minute,sekunde,gebiet_id)
|
||||
{
|
||||
let message = <?php echo "'".$p->t('testtool/okKlickenUmZuStarten')."'"?> + ' ' + stunde + 'h ' + minute + 'm ' + sekunde + 's';
|
||||
let title = <?php echo "'".$p->t('testtool/startGebiet')."'"?>;
|
||||
let abbrechen = <?php echo "'".$p->t('testtool/abbrechen')."'"?>;
|
||||
|
||||
if ($('#gebiet-dialog').length === 0)
|
||||
{
|
||||
$('body').append(
|
||||
'<div id="gebiet-dialog" title="' + title + '">' +
|
||||
'<p id="gebiet-dialog-msg">' + message + '</p>' +
|
||||
'</div>'
|
||||
);
|
||||
var check = confirm(<?php echo "'".$p->t('testtool/okKlickenUmZuStarten')."'"?>+' '+stunde+'h '+minute+'m '+sekunde+'s');
|
||||
if (check == true) {
|
||||
var sprache_user = <?php echo "'".$sprache_user."'"?>;
|
||||
document.location.href = 'frage.php?gebiet_id='+gebiet_id+'&start=true';
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
$('#gebiet-dialog').dialog({
|
||||
modal: true,
|
||||
width: 400,
|
||||
resizable: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'OK',
|
||||
click: function() {
|
||||
$(this).dialog('close');
|
||||
document.location.href = 'frage.php?gebiet_id=' + gebiet_id + '&start=true';
|
||||
}
|
||||
},
|
||||
{
|
||||
text: abbrechen,
|
||||
click: function() {
|
||||
$(this).dialog('close');
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
let letzteFrageBestaetigt = false;
|
||||
|
||||
function letzteFrage()
|
||||
{
|
||||
if (letzteFrageBestaetigt)
|
||||
return true;
|
||||
|
||||
let message = <?php echo "'".$p->t("testtool/alleFragenBeantwortet")."'"?>;
|
||||
|
||||
if ($('#fertig-dialog').length === 0)
|
||||
{
|
||||
$('body').append(
|
||||
'<div id="fertig-dialog">' +
|
||||
'<p>' + message + '</p>' +
|
||||
'</div>'
|
||||
);
|
||||
}
|
||||
|
||||
$('#fertig-dialog').dialog({
|
||||
modal: true,
|
||||
width: 400,
|
||||
resizable: false,
|
||||
buttons: [
|
||||
{
|
||||
text: 'OK',
|
||||
click: function() {
|
||||
$(this).dialog('close');
|
||||
letzteFrageBestaetigt = true;
|
||||
$('[name="submitantwort"]').click();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
return false;
|
||||
alert(<?php echo "'".$p->t("testtool/alleFragenBeantwortet")."'"?>);
|
||||
return true;
|
||||
}
|
||||
|
||||
$(document).ready(function () {
|
||||
@@ -711,7 +647,7 @@ if($frage->frage_id!='')
|
||||
}
|
||||
|
||||
$letzte = $frage->getNextFrage($gebiet_id, $_SESSION['pruefling_id'], $frage_id, $demo);
|
||||
echo "<form action=\"$PHP_SELF?gebiet_id=$gebiet_id&frage_id=$frage->frage_id\" method=\"POST\" ".(!$letzte && !$levelgebiet?"onsubmit=\"return letzteFrage()\"":"").">";
|
||||
echo "<form action=\"$PHP_SELF?gebiet_id=$gebiet_id&frage_id=$frage->frage_id\" method=\"POST\" ".(!$letzte && !$levelgebiet?"onsubmit=\"letzteFrage()\"":"").">";
|
||||
echo '
|
||||
<div class="row text-center">
|
||||
<table class="table" style="width: 600px; margin-left: auto; margin-right: auto;">
|
||||
|
||||
@@ -44,27 +44,6 @@ if (isset($_GET['sprache_user']) && !empty($_GET['sprache_user']))
|
||||
$sprache_user = (isset($_SESSION['sprache_user']) && !empty($_SESSION['sprache_user'])) ? $_SESSION['sprache_user'] : DEFAULT_LANGUAGE;
|
||||
$p = new phrasen($sprache_user);
|
||||
|
||||
$showInfo = false;
|
||||
if (isset($_SESSION['alleGebiete']))
|
||||
{
|
||||
$alleGebiete = array_map('intval', $_SESSION['alleGebiete']);
|
||||
$pruefling_id = $_SESSION['pruefling_id'];
|
||||
|
||||
$qry = "SELECT COUNT(DISTINCT gebiet_id) as anzahl
|
||||
FROM testtool.tbl_pruefling_frage
|
||||
JOIN testtool.tbl_frage USING(frage_id)
|
||||
WHERE gebiet_id IN (". implode(',', $alleGebiete) .")
|
||||
AND pruefling_id = ". $pruefling_id ."
|
||||
";
|
||||
|
||||
$result = $db->db_query($qry);
|
||||
$anzahlGebiete = $db->db_fetch_object($result);
|
||||
|
||||
|
||||
if ((int)$anzahlGebiete->anzahl === count($alleGebiete))
|
||||
$showInfo = true;
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||
<html>
|
||||
@@ -90,7 +69,6 @@ if (isset($_SESSION['alleGebiete']))
|
||||
<body>
|
||||
<br><br><br><br><br>
|
||||
<center><h2><?php echo $p->t('testtool/zeitAbgelaufen');?></h2>
|
||||
<h3><?php echo ($showInfo ? ($p->t('testtool/alleGebietGestartet') . "<br />" . $p->t('testtool/alleGebieteGestartetInfo')) : ''); ?></h3>
|
||||
</center>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+2
-11
@@ -142,9 +142,7 @@ if (isset($_REQUEST['prestudent']))
|
||||
}
|
||||
if ($reihungstest_id != '' && $rt->load($reihungstest_id))
|
||||
{
|
||||
$pruefling_exist = new Pruefling();
|
||||
$alreadyInRT = $pruefling_exist->personAlreadyInRT($ps->person_id, $rt->reihungstest_id, $ps->prestudent_id);
|
||||
if ($rt->freigeschaltet && !$alreadyInRT)
|
||||
if ($rt->freigeschaltet)
|
||||
{
|
||||
// regenerate Session ID after Login
|
||||
session_regenerate_id();
|
||||
@@ -284,14 +282,7 @@ if (isset($_REQUEST['prestudent']))
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($alreadyInRT)
|
||||
{
|
||||
$alertmsg .= '<div class="alert alert-danger">'.$p->t('testtool/reihungstestNichtRegistriert').'</div>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$alertmsg .= '<div class="alert alert-danger">'.$p->t('testtool/reihungstestNichtFreigeschalten').'</div>';
|
||||
}
|
||||
$alertmsg .= '<div class="alert alert-danger">'.$p->t('testtool/reihungstestNichtFreigeschalten').'</div>';
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -187,7 +187,6 @@ else if (isset($_SESSION['pruefling_id']))
|
||||
}
|
||||
|
||||
$qry .= "
|
||||
AND ps_status.bewerbung_abgeschicktamum IS NOT NULL
|
||||
|
||||
/* Order to get last semester when using distinct on */
|
||||
ORDER BY
|
||||
@@ -406,29 +405,6 @@ else if (isset($_SESSION['pruefling_id']))
|
||||
echo '</table>';
|
||||
}
|
||||
|
||||
if (isset($_SESSION['pruefling_id']) && !empty($_SESSION['alleGebiete']))
|
||||
{
|
||||
$alleGebiete = array_map('intval', $_SESSION['alleGebiete']);
|
||||
$pruefling_id = (int)$_SESSION['pruefling_id'];
|
||||
|
||||
$qry = "SELECT COUNT(DISTINCT gebiet_id) AS anzahl
|
||||
FROM testtool.tbl_pruefling_frage
|
||||
JOIN testtool.tbl_frage USING(frage_id)
|
||||
WHERE gebiet_id IN (". implode(',', $alleGebiete) .")
|
||||
AND pruefling_id = ". $pruefling_id;
|
||||
|
||||
$result_check = $db->db_query($qry);
|
||||
$row_check = $db->db_fetch_object($result_check);
|
||||
|
||||
if ((int)$row_check->anzahl === count($alleGebiete))
|
||||
{
|
||||
echo '<tr><td>
|
||||
<div class="alert alert-success small" style="margin-left: 20px; width: 170px; margin-top: 3px;" role="alert">
|
||||
<strong>'.$p->t('testtool/alleGebietGestartet').'</strong>
|
||||
</div>
|
||||
</td></tr>';
|
||||
}
|
||||
}
|
||||
// Link zum Logout
|
||||
|
||||
echo '<tr><td class="ItemTesttool" style="margin-left: 20px;" nowrap>
|
||||
|
||||
@@ -95,37 +95,37 @@ foreach ($result_student as $row)
|
||||
if ($uids == '')
|
||||
die('Es befinden sich keine Studierende in diesem Semester');
|
||||
|
||||
$qry = "SELECT
|
||||
lehrveranstaltung_id, bezeichnung, studiengang_kz, semester, ects
|
||||
FROM
|
||||
lehre.tbl_lehrveranstaltung
|
||||
WHERE
|
||||
lehrveranstaltung_id IN (
|
||||
SELECT
|
||||
DISTINCT lehrveranstaltung_id
|
||||
FROM
|
||||
campus.vw_student_lehrveranstaltung
|
||||
JOIN public.tbl_studentlehrverband ON(student_uid = uid)
|
||||
WHERE
|
||||
tbl_studentlehrverband.studiengang_kz = ".$db->db_add_param($studiengang_kz, FHC_INTEGER)."
|
||||
AND tbl_studentlehrverband.semester = ".$db->db_add_param($semester, FHC_INTEGER)."
|
||||
AND vw_student_lehrveranstaltung.studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell)."
|
||||
AND vw_student_lehrveranstaltung.studiensemester_kurzbz = tbl_studentlehrverband.studiensemester_kurzbz
|
||||
$qry = "SELECT
|
||||
lehrveranstaltung_id, bezeichnung, studiengang_kz, semester, ects
|
||||
FROM
|
||||
lehre.tbl_lehrveranstaltung
|
||||
WHERE
|
||||
lehrveranstaltung_id IN
|
||||
(
|
||||
SELECT
|
||||
distinct lehrveranstaltung_id
|
||||
FROM
|
||||
campus.vw_student_lehrveranstaltung, public.tbl_studentlehrverband
|
||||
WHERE
|
||||
tbl_studentlehrverband.studiengang_kz=".$db->db_add_param($studiengang_kz, FHC_INTEGER)." AND
|
||||
tbl_studentlehrverband.semester=".$db->db_add_param($semester, FHC_INTEGER)." AND
|
||||
vw_student_lehrveranstaltung.studiensemester_kurzbz=".$db->db_add_param($semester_aktuell)." AND
|
||||
uid=student_uid AND
|
||||
vw_student_lehrveranstaltung.studiensemester_kurzbz=tbl_studentlehrverband.studiensemester_kurzbz
|
||||
)
|
||||
AND studiengang_kz != 0
|
||||
AND studiengang_kz<>0
|
||||
AND zeugnis
|
||||
UNION
|
||||
SELECT
|
||||
lehrveranstaltung_id, bezeichnung, studiengang_kz, semester, ects
|
||||
FROM
|
||||
lehre.tbl_lehrveranstaltung
|
||||
JOIN lehre.tbl_zeugnisnote USING(lehrveranstaltung_id)
|
||||
WHERE
|
||||
tbl_lehrveranstaltung.studiengang_kz = ".$db->db_add_param($studiengang_kz, FHC_INTEGER)."
|
||||
AND tbl_zeugnisnote.student_uid IN ($uids)
|
||||
AND tbl_zeugnisnote.studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell)."
|
||||
AND zeugnis
|
||||
ORDER BY bezeichnung";
|
||||
UNION
|
||||
SELECT
|
||||
lehrveranstaltung_id, bezeichnung, studiengang_kz, semester, ects
|
||||
FROM
|
||||
lehre.tbl_lehrveranstaltung JOIN lehre.tbl_zeugnisnote USING(lehrveranstaltung_id)
|
||||
WHERE
|
||||
tbl_lehrveranstaltung.studiengang_kz=".$db->db_add_param($studiengang_kz, FHC_INTEGER)." AND
|
||||
tbl_zeugnisnote.student_uid in($uids) AND
|
||||
tbl_zeugnisnote.studiensemester_kurzbz=".$db->db_add_param($semester_aktuell)." AND
|
||||
zeugnis
|
||||
ORDER BY bezeichnung";
|
||||
|
||||
if (!$result_lva = $db->db_query($qry))
|
||||
die('Fehler beim Ermitteln der Lehrveranstaltungen');
|
||||
@@ -338,10 +338,6 @@ if ($typ == 'xls')
|
||||
}
|
||||
$anzahl_lvspalten = $spalte - 2;
|
||||
|
||||
$worksheet->write($zeile, ++$spalte, 'ECTS Summe zugeteilt', $format_bold);
|
||||
$maxlength[$spalte] = 20;
|
||||
$worksheet->write($zeile, ++$spalte, 'ECTS Summe gewichtet', $format_bold);
|
||||
$maxlength[$spalte] = 20;
|
||||
$worksheet->write($zeile, ++$spalte, 'Notendurchschnitt', $format_bold);
|
||||
$maxlength[$spalte] = 15;
|
||||
$worksheet->write($zeile, ++$spalte, "Gewichteter\nNotendurchschnitt", $format_bold_wrap);
|
||||
@@ -376,12 +372,9 @@ if ($typ == 'xls')
|
||||
$worksheet->write($zeile, ++$spalte, $row_student->gruppe, $format_bold_left);
|
||||
$worksheet->write($zeile, ++$spalte, $row_student->matrikelnr, $format_bold);
|
||||
|
||||
// Alle Zeugnisnoten des Studierenden holen
|
||||
//Alle Zeugnisnoten des Studierenden holen
|
||||
$noten = array();
|
||||
$qry = "SELECT lehrveranstaltung_id, note
|
||||
FROM lehre.tbl_zeugnisnote
|
||||
WHERE student_uid = ".$db->db_add_param($row_student->uid)."
|
||||
AND studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell);
|
||||
$qry = "SELECT * FROM lehre.tbl_zeugnisnote WHERE student_uid=".$db->db_add_param($row_student->uid)." AND studiensemester_kurzbz=".$db->db_add_param($semester_aktuell);
|
||||
if ($result = $db->db_query($qry))
|
||||
while ($row = $db->db_fetch_object($result))
|
||||
$noten[$row->lehrveranstaltung_id] = $row->note;
|
||||
@@ -389,16 +382,15 @@ if ($typ == 'xls')
|
||||
//Zu jeder Lehrveranstaltungsnote Prüfungstyp (Anzahl der Antritte) holen
|
||||
$pruefungstypen = array();
|
||||
$qry = "SELECT tbl_lehrveranstaltung.lehrveranstaltung_id, pruefungstyp_kurzbz, sort, datum
|
||||
FROM
|
||||
lehre.tbl_pruefung
|
||||
JOIN
|
||||
lehre.tbl_lehreinheit USING(lehreinheit_id)
|
||||
JOIN
|
||||
lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
|
||||
WHERE
|
||||
student_uid = ".$db->db_add_param($row_student->uid)."
|
||||
AND studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell)."
|
||||
ORDER BY lehrveranstaltung_id, sort, datum";
|
||||
FROM
|
||||
lehre.tbl_pruefung
|
||||
JOIN
|
||||
lehre.tbl_lehreinheit using(lehreinheit_id)
|
||||
JOIN
|
||||
lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id)
|
||||
WHERE
|
||||
student_uid=".$db->db_add_param($row_student->uid)." AND studiensemester_kurzbz=".$db->db_add_param($semester_aktuell)."
|
||||
ORDER BY lehrveranstaltung_id, sort, datum";
|
||||
if ($result = $db->db_query($qry))
|
||||
{
|
||||
while ($row = $db->db_fetch_object($result))
|
||||
@@ -407,14 +399,15 @@ if ($typ == 'xls')
|
||||
}
|
||||
}
|
||||
|
||||
// Alle LVs holen zu denen der Studierende zugeteilt ist
|
||||
//Alle LVs holen zu denen der Studierende zugeteilt ist
|
||||
$zugeteilte_lvs = array();
|
||||
$qry = "SELECT DISTINCT lehrveranstaltung_id
|
||||
FROM
|
||||
campus.vw_student_lehrveranstaltung
|
||||
WHERE
|
||||
uid = ".$db->db_add_param($row_student->uid)."
|
||||
AND studiensemester_kurzbz = ".$db->db_add_param($semester_aktuell);
|
||||
$qry = "SELECT distinct lehrveranstaltung_id
|
||||
FROM
|
||||
campus.vw_student_lehrveranstaltung
|
||||
WHERE
|
||||
uid=".$db->db_add_param($row_student->uid)." AND
|
||||
studiensemester_kurzbz=".$db->db_add_param($semester_aktuell);
|
||||
|
||||
if ($result = $db->db_query($qry))
|
||||
while ($row = $db->db_fetch_object($result))
|
||||
$zugeteilte_lvs[] = $row->lehrveranstaltung_id;
|
||||
@@ -423,20 +416,17 @@ if ($typ == 'xls')
|
||||
$summe = 0;
|
||||
$rowcount = 0;
|
||||
$summeects = 0;
|
||||
$total_ects = 0;
|
||||
$gewichtetenote = 0;
|
||||
|
||||
while ($rowcount < $db->db_num_rows($result_lva))
|
||||
{
|
||||
$row_lva = $db->db_fetch_object($result_lva, $rowcount);
|
||||
$rowcount++;
|
||||
|
||||
//wenn es eine Note gibt
|
||||
if (isset($noten[$row_lva->lehrveranstaltung_id]))
|
||||
{
|
||||
$note = $noten[$row_lva->lehrveranstaltung_id];
|
||||
$format = 0;
|
||||
$total_ects += $row_lva->ects;
|
||||
|
||||
//wenn für die LV der Studierende eine Nachprüfung hat (z.B. 2 Termin, kommissionelle...)
|
||||
if (isset($pruefungstypen[$row_lva->lehrveranstaltung_id]))
|
||||
@@ -482,7 +472,6 @@ if ($typ == 'xls')
|
||||
//Keine Note fuer diese LV vorhanden
|
||||
if (in_array($row_lva->lehrveranstaltung_id, $zugeteilte_lvs))
|
||||
{
|
||||
$total_ects += $row_lva->ects;
|
||||
$worksheet->write($zeile, ++$spalte, '', $format_colored_nichteingetragen);
|
||||
}
|
||||
else
|
||||
@@ -500,8 +489,6 @@ if ($typ == 'xls')
|
||||
if ($summeects != 0)
|
||||
$gewichtetenote /= $summeects;
|
||||
|
||||
$worksheet->write($zeile, ++$spalte, sprintf("%.2f", $total_ects), $format_number);
|
||||
$worksheet->write($zeile, ++$spalte, sprintf("%.2f", $summeects), $format_number);
|
||||
$worksheet->write($zeile, ++$spalte, sprintf("%.2f", $schnitt), $format_number);
|
||||
$worksheet->write($zeile, ++$spalte, sprintf("%.2f", $gewichtetenote), $format_number);
|
||||
if ($gewichtetenote != 0)
|
||||
@@ -542,8 +529,6 @@ if ($typ == 'xls')
|
||||
$schnitt = $summe_schnitt / $anzahl_schnitt;
|
||||
else
|
||||
$schnitt = 0;
|
||||
$worksheet->write($zeile, ++$spalte, '-', $format_bold_center);
|
||||
$worksheet->write($zeile, ++$spalte, '-', $format_bold_center);
|
||||
$worksheet->write($zeile, ++$spalte, sprintf("%.2f", $schnitt), $format_number);
|
||||
if ($anzahlgewichtet != 0)
|
||||
$summegewichtet = $summegewichtet / $anzahlgewichtet;
|
||||
|
||||
+1
-49
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
require_once(dirname(__FILE__).'/basis_db.class.php');
|
||||
require_once(dirname(__FILE__).'/'.EXT_FKT_PATH.'/generateZahlungsreferenz.inc.php');
|
||||
require_once(dirname(__FILE__).'/variable.class.php');
|
||||
|
||||
class konto extends basis_db
|
||||
{
|
||||
@@ -433,8 +432,6 @@ class konto extends basis_db
|
||||
|
||||
$qry.=" ORDER BY beschreibung";
|
||||
|
||||
$oehBeitrag = $this->_getOEHBeitrag();
|
||||
|
||||
if($this->db_query($qry))
|
||||
{
|
||||
while($row = $this->db_fetch_object())
|
||||
@@ -443,15 +440,7 @@ class konto extends basis_db
|
||||
|
||||
$typ->buchungstyp_kurzbz = $row->buchungstyp_kurzbz;
|
||||
$typ->beschreibung = $row->beschreibung;
|
||||
if (strtolower($typ->buchungstyp_kurzbz) === 'oeh' && $oehBeitrag)
|
||||
{
|
||||
$typ->standardbetrag = $oehBeitrag;
|
||||
}
|
||||
else
|
||||
{
|
||||
$typ->standardbetrag = $row->standardbetrag;
|
||||
}
|
||||
|
||||
$typ->standardbetrag = $row->standardbetrag;
|
||||
$typ->standardtext = $row->standardtext;
|
||||
$typ->credit_points = $row->credit_points;
|
||||
$typ->aktiv = $this->db_parse_bool($row->aktiv);
|
||||
@@ -1001,43 +990,6 @@ class konto extends basis_db
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function _getOEHBeitrag()
|
||||
{
|
||||
if(!is_user_logged_in())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$variablen_obj = new variable();
|
||||
$variablen_obj->loadVariables(get_uid());
|
||||
|
||||
$qry = "WITH semstart AS (
|
||||
SELECT start FROM public.tbl_studiensemester
|
||||
WHERE studiensemester_kurzbz = '". $this->db_escape($variablen_obj->variable->semester_aktuell) . "'
|
||||
)
|
||||
SELECT * FROM bis.tbl_oehbeitrag oehb
|
||||
JOIN public.tbl_studiensemester semvon ON oehb.von_studiensemester_kurzbz = semvon.studiensemester_kurzbz
|
||||
LEFT JOIN public.tbl_studiensemester sembis ON oehb.bis_studiensemester_kurzbz = sembis.studiensemester_kurzbz
|
||||
JOIN semstart ON semstart.start::date >= semvon.start::date AND (sembis.studiensemester_kurzbz IS NULL OR semstart.start::date <= sembis.start::date)
|
||||
ORDER BY semvon.start
|
||||
LIMIT 1";
|
||||
|
||||
if ($this->db_query($qry))
|
||||
{
|
||||
if($row = $this->db_fetch_object())
|
||||
{
|
||||
$summe = ($row->studierendenbeitrag + $row->versicherung) * -1;
|
||||
return number_format((float)$summe, 2, '.', '');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errormsg = 'Fehler bei der Abfrage aufgetreten';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
@@ -584,32 +584,6 @@ class pruefling extends basis_db
|
||||
|
||||
$qry .= " LIMIT 1";
|
||||
|
||||
if($result = $this->db_query($qry))
|
||||
{
|
||||
if ($this->db_num_rows($result) == 0)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->errormsg = 'Fehler bei einer Abfrage';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public function personAlreadyInRT($person_id, $reihungstest_id, $prestudent_id)
|
||||
{
|
||||
$qry = "SELECT tbl_prestudent.prestudent_id
|
||||
FROM public.tbl_rt_person
|
||||
JOIN public.tbl_prestudent ON tbl_prestudent.person_id = tbl_rt_person.person_id
|
||||
JOIN public.tbl_prestudentstatus ON tbl_prestudent.prestudent_id = tbl_prestudentstatus.prestudent_id AND status_kurzbz = 'Bewerber'
|
||||
AND tbl_prestudentstatus.studienplan_id = tbl_rt_person.studienplan_id
|
||||
WHERE tbl_rt_person.person_id = " . $this->db_add_param($person_id) . "
|
||||
AND tbl_rt_person.rt_id = " . $this->db_add_param($reihungstest_id) . "
|
||||
AND tbl_prestudent.prestudent_id != " . $this->db_add_param($prestudent_id) . "
|
||||
AND get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) = 'Bewerber'
|
||||
LIMIT 1";
|
||||
|
||||
if($result = $this->db_query($qry))
|
||||
{
|
||||
if ($this->db_num_rows($result) == 0)
|
||||
|
||||
@@ -17,7 +17,6 @@ $this->phrasen['testtool/basic']='Basic';
|
||||
$this->phrasen['testtool/basisgebiete']='Basisgebiete';
|
||||
$this->phrasen['testtool/semester']='Semester';
|
||||
$this->phrasen['testtool/reihungstestNichtFreigeschalten']='Der zuteilte Reihungstest ist noch nicht freigeschaltet';
|
||||
$this->phrasen['testtool/reihungstestNichtRegistriert']='Sie sind für den Reihungstest nicht registriert';
|
||||
$this->phrasen['testtool/reihungstestKannNichtGeladenWerden']='Der Reihungstest dem Sie zugeteilt sind, kann nicht geladen werden. Melden Sie sich bitte bei der Reihungstestaufsicht.';
|
||||
$this->phrasen['testtool/geburtsdatumStimmtNichtUeberein']='Ihr Geburtsdatum stimmt nicht mit unseren Daten überein. Bitte wenden Sie sich an die Aufsichtsperson';
|
||||
$this->phrasen['testtool/home']='Home';
|
||||
@@ -32,14 +31,10 @@ $this->phrasen['testtool/keineAntwort']='Keine Antwort';
|
||||
$this->phrasen['testtool/speichernUndWeiter']='Speichern und weiter';
|
||||
$this->phrasen['testtool/alleFragenBeantwortet']='GLÜCKWUNSCH! \n\nSie haben alle Fragen in der zur Verfügung stehenden Zeit beantwortet. \nNutzen Sie die verbleibende Zeit, um Ihre Antworten zu kontrollieren oder fahren Sie mit dem nächsten Teilgebiet fort.';
|
||||
$this->phrasen['testtool/zeitAbgelaufen']='Die Maximalzeit für dieses Gebiet ist abgelaufen, oder alle Fragen wurden beantwortet';
|
||||
$this->phrasen['testtool/alleGebietGestartet']='Sie haben alle Gebiete bearbeitet.';
|
||||
$this->phrasen['testtool/alleGebieteGestartetInfo']='Sie können sich nun ausloggen und den Browser schließen.';
|
||||
$this->phrasen['testtool/spracheDerTestfragen']='Gewünschte Sprache der Testfragen';
|
||||
$this->phrasen['testtool/einleitung']='Einleitung';
|
||||
$this->phrasen['testtool/blaettern']='Blättern';
|
||||
$this->phrasen['testtool/demo']='Demobeispiel ansehen';
|
||||
$this->phrasen['testtool/abbrechen']='Abbrechen';
|
||||
$this->phrasen['testtool/startGebiet']='Gebiet starten';
|
||||
$this->phrasen['testtool/okKlickenUmZuStarten']='Klicken Sie OK um dieses Gebiet zu starten. \nSie haben für die Bearbeitung ein Zeitlimit von';
|
||||
$this->phrasen['testtool/bitteZuerstAnmelden']='Bitte zuerst anmelden!';
|
||||
$this->phrasen['testtool/fehlerBeimGenerierenDesFragenpools']='Fehler beim generieren des Fragenpools';
|
||||
|
||||
@@ -17,7 +17,6 @@ $this->phrasen['testtool/basic']='Basic';
|
||||
$this->phrasen['testtool/basisgebiete']='Basic test';
|
||||
$this->phrasen['testtool/semester']='Semester';
|
||||
$this->phrasen['testtool/reihungstestNichtFreigeschalten']='The entrance examination assigned has not yet been activated.';
|
||||
$this->phrasen['testtool/reihungstestNichtRegistriert']='You are not registered for the placement test.';
|
||||
$this->phrasen['testtool/reihungstestKannNichtGeladenWerden']='The placement test you are assigned to could not be loaded. Please contact the placement test supervisior.';
|
||||
$this->phrasen['testtool/geburtsdatumStimmtNichtUeberein']='Your date of birth does not correspond to the data we have. Please speak to the supervisor. ';
|
||||
$this->phrasen['testtool/home']='Home';
|
||||
@@ -32,14 +31,10 @@ $this->phrasen['testtool/keineAntwort']='No Answer';
|
||||
$this->phrasen['testtool/speichernUndWeiter']='Save and next';
|
||||
$this->phrasen['testtool/alleFragenBeantwortet']='CONGRATULATIONS!\n\nYou have answered all the questions in the time allowed.\n Use the remaining time to check your answers or continue to the next section.';
|
||||
$this->phrasen['testtool/zeitAbgelaufen']='The time for this part has expired or you have answered all the questions.';
|
||||
$this->phrasen['testtool/alleGebietGestartet']='You have worked on all sections.';
|
||||
$this->phrasen['testtool/alleGebieteGestartetInfo']='You can now log out and close the browser.';
|
||||
$this->phrasen['testtool/spracheDerTestfragen']='Desired language of questions';
|
||||
$this->phrasen['testtool/einleitung']='Introduction';
|
||||
$this->phrasen['testtool/blaettern']='Browse';
|
||||
$this->phrasen['testtool/demo']='See an example';
|
||||
$this->phrasen['testtool/abbrechen']='Cancel';
|
||||
$this->phrasen['testtool/startGebiet']='Start the section';
|
||||
$this->phrasen['testtool/okKlickenUmZuStarten']='Click OK to start this section. \nYou have a timelimit of';
|
||||
$this->phrasen['testtool/bitteZuerstAnmelden']='Please log in first!';
|
||||
$this->phrasen['testtool/fehlerBeimGenerierenDesFragenpools']='Error in generating the pool of questions.';
|
||||
|
||||
@@ -197,6 +197,10 @@ html.fs_huge {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
.tiny-90 div.tox.tox-tinymce {
|
||||
height: 90% !important;
|
||||
}
|
||||
|
||||
/* slim begin */
|
||||
.stv .form-label {
|
||||
margin-bottom: .15rem;
|
||||
@@ -277,3 +281,7 @@ html.fs_huge {
|
||||
}
|
||||
*/
|
||||
/* slim ende */
|
||||
|
||||
.fhc-xxl-modal {
|
||||
min-width: 80vw;
|
||||
}
|
||||
@@ -305,4 +305,94 @@
|
||||
/* If you use hover rows, you need to ensure the sticky cell matches the hover color */
|
||||
#abgabetable .tabulator-row:hover .tabulator-cell.sticky-col {
|
||||
background-color: #ccc; /* Match your existing hover color */
|
||||
}
|
||||
}
|
||||
|
||||
.tabulator-cell {
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
.tabulator-col-title {
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
@container (max-width: 100px) {
|
||||
.full-text {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.short-text {
|
||||
display: inline-block !important;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/*conditional tooltips fix*/
|
||||
.p-tooltip.custom-tooltip {
|
||||
z-index: 8001 !important;
|
||||
}
|
||||
|
||||
/* Shrinks font and table rows for desktop users who have zoomed in their browser (150%+).
|
||||
Does not affect mobile/touchscreen devices, which use touch input instead of a mouse. */
|
||||
@media (pointer: fine) and (min-resolution: 1.5dppx) {
|
||||
|
||||
html.abgabetool {
|
||||
font-size: 0.5rem;
|
||||
}
|
||||
|
||||
.abgabetool .tabulator-cell,
|
||||
.abgabetool .tabulator-row {
|
||||
height: 20px;
|
||||
max-height: 20px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*confetti celebration on endupload - impossible to miss*/
|
||||
#confetti-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
pointer-events: none;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.confetti-piece {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
will-change: top, transform, opacity;
|
||||
}
|
||||
|
||||
/* Background Rain */
|
||||
@keyframes fallAndSpin {
|
||||
0% {
|
||||
top: var(--start-y);
|
||||
transform: translate3d(0, 0, 0) rotateX(0deg) rotateY(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
top: 105vh;
|
||||
transform: translate3d(var(--drift), 0, 0) rotateX(720deg) rotateY(360deg);
|
||||
opacity: 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Corner Cannons*/
|
||||
@keyframes cannonBlast {
|
||||
0% {
|
||||
transform: translate3d(0, 0, 0) scale(0.3) rotate(0deg);
|
||||
opacity: 1;
|
||||
animation-timing-function: cubic-bezier(0.1, 0.8, 0.2, 1);
|
||||
}
|
||||
30% {
|
||||
transform: translate3d(var(--blast-x), var(--blast-y), 0) scale(1.2) rotate(270deg);
|
||||
opacity: 1;
|
||||
animation-timing-function: linear;
|
||||
}
|
||||
100% {
|
||||
transform: translate3d(calc(var(--blast-x) * 1.4), 15vh, 0) scale(0.4) rotate(630deg);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,6 +77,13 @@ export default {
|
||||
}
|
||||
};
|
||||
},
|
||||
patchProjektarbeitAbgabeMultiple(payload) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Abgabe/patchProjektarbeitAbgabeMultiple',
|
||||
params: payload
|
||||
};
|
||||
},
|
||||
deleteProjektarbeitAbgabe(paabgabe_id) {
|
||||
return {
|
||||
method: 'post',
|
||||
@@ -84,6 +91,13 @@ export default {
|
||||
params: { paabgabe_id }
|
||||
};
|
||||
},
|
||||
deleteProjektarbeitAbgabeMultiple(paabgabe_ids) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Abgabe/deleteProjektarbeitAbgabeMultiple',
|
||||
params: { paabgabe_ids }
|
||||
};
|
||||
},
|
||||
postSerientermin(datum, paabgabetyp_kurzbz, bezeichnung, kurzbz, upload_allowed, projektarbeit_ids, fixtermin) {
|
||||
return {
|
||||
method: 'post',
|
||||
@@ -139,6 +153,14 @@ export default {
|
||||
url: '/api/frontend/v1/Abgabe/getSignaturStatusForProjektarbeitAbgaben',
|
||||
params: {paabgabe_ids, student_uid},
|
||||
|
||||
};
|
||||
},
|
||||
postStudentProjektarbeitTitel(projektarbeit_id, titel) {
|
||||
return {
|
||||
method: 'post',
|
||||
url: '/api/frontend/v1/Abgabe/postStudentProjektarbeitTitel',
|
||||
params: {projektarbeit_id, titel},
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -38,10 +38,6 @@ export default {
|
||||
};
|
||||
},
|
||||
insert(params) {
|
||||
if(params.betrag)
|
||||
{
|
||||
params.betrag = params.betrag.replace(',', '.');
|
||||
}
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/konto/insert',
|
||||
@@ -56,10 +52,6 @@ export default {
|
||||
};
|
||||
},
|
||||
edit(params) {
|
||||
if(params.betrag)
|
||||
{
|
||||
params.betrag = params.betrag.replace(',', '.');
|
||||
}
|
||||
return {
|
||||
method: 'post',
|
||||
url: 'api/frontend/v1/stv/konto/update',
|
||||
@@ -73,14 +65,10 @@ export default {
|
||||
params: { buchungsnr }
|
||||
};
|
||||
},
|
||||
getBuchungstypen(studiensemester_kurzbz) {
|
||||
let url = 'api/frontend/v1/stv/konto/getBuchungstypen'
|
||||
if (!!studiensemester_kurzbz)
|
||||
url = url + '/' + encodeURIComponent(studiensemester_kurzbz);
|
||||
|
||||
getBuchungstypen() {
|
||||
return {
|
||||
method: 'get',
|
||||
url: url
|
||||
url: 'api/frontend/v1/stv/konto/getBuchungstypen'
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
@@ -4,7 +4,9 @@ export default {
|
||||
name: 'BootstrapModal',
|
||||
data: () => ({
|
||||
modal: null,
|
||||
fullscreen: false
|
||||
fullscreen: false,
|
||||
expandBtnHovered: false,
|
||||
expandBtnFocused: false,
|
||||
}),
|
||||
props: {
|
||||
backdrop: {
|
||||
@@ -70,6 +72,29 @@ export default {
|
||||
this.$emit('toggleFullscreen')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getExpandButtonStyles() {
|
||||
const hovered = this.expandBtnHovered;
|
||||
const focused = this.expandBtnFocused;
|
||||
return `display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
font-size: 1em;
|
||||
opacity: 0.5;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
line-height: 1;
|
||||
transition: opacity 0.15s ease;
|
||||
opacity: ${focused ? '1' : hovered ? '0.75' : '0.5'};
|
||||
outline: ${focused ? '1px solid currentColor' : 'none'};
|
||||
outline-offset: 2px;`
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.$refs.modal)
|
||||
this.modal = new bootstrap.Modal(this.$refs.modal, {
|
||||
@@ -140,9 +165,13 @@ export default {
|
||||
<div class="d-flex align-items-center ms-auto gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="btn mb-1"
|
||||
:style="getExpandButtonStyles"
|
||||
v-if="allowFullscreenExpand"
|
||||
@click="toggleFullscreen"
|
||||
@mouseenter="expandBtnHovered = true"
|
||||
@mouseleave="expandBtnHovered = false"
|
||||
@focusin="expandBtnFocused = true"
|
||||
@focusout="expandBtnFocused = false"
|
||||
:aria-label="fullscreen ? 'Exit Fullscreen' : 'Enter Fullscreen'"
|
||||
>
|
||||
<i v-if="!fullscreen" class="fa-solid fa-expand"></i>
|
||||
|
||||
@@ -2,6 +2,7 @@ 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";
|
||||
|
||||
export const AbgabeMitarbeiterDetail = {
|
||||
name: "AbgabeMitarbeiterDetail",
|
||||
@@ -46,12 +47,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
eidAkzeptiert: false,
|
||||
enduploadTermin: null,
|
||||
allActiveLanguages: FHC_JS_DATA_STORAGE_OBJECT.server_languages,
|
||||
speedDialItems: [{
|
||||
label: Vue.computed(() => this.$p.t('abgabetool/c4newAbgabetermin')),
|
||||
icon: "fa fa-plus",
|
||||
command: this.openCreateNewAbgabeModal,
|
||||
disabled: Vue.computed(() => !this.getAllowedToCreateNewTermin)
|
||||
},
|
||||
speedDialItems: [
|
||||
{
|
||||
label: Vue.computed(() => this.$p.t('abgabetool/c4benoten')),
|
||||
icon: "fa fa-user-check",
|
||||
@@ -81,6 +77,9 @@ export const AbgabeMitarbeiterDetail = {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
terminIsInvalid(termin) {
|
||||
return termin.note?.positiv == false && !termin.beurteilungsnotiz
|
||||
},
|
||||
getNoteBezeichnung(termin){
|
||||
if(termin.noteBackend?.bezeichnung) {
|
||||
return termin.noteBackend?.positiv ? this.$capitalize(this.$p.t('abgabetool/c4positivBenotet')) + ' ✅' : this.$capitalize(this.$p.t('abgabetool/c4negativBenotet')) + ' ❌'
|
||||
@@ -113,6 +112,8 @@ export const AbgabeMitarbeiterDetail = {
|
||||
if(newTerminRes.note) {
|
||||
newTerminRes.note = noteOpt
|
||||
newTerminRes.noteBackend = noteOpt // certain UI elements should only reflect persisted state
|
||||
termin.allowedToDelete = false
|
||||
newTerminRes.allowedToDelete = false
|
||||
}
|
||||
newTerminRes.invertedFixtermin = !newTerminRes.fixtermin
|
||||
const existingTerminRes = res.data[1]
|
||||
@@ -132,13 +133,13 @@ export const AbgabeMitarbeiterDetail = {
|
||||
} else {
|
||||
const noteOptExisting = this.allowedNotenOptions.find(opt => opt.note == existingTerminRes.note)
|
||||
existingTerminRes.note = noteOptExisting
|
||||
|
||||
|
||||
termin.paabgabetyp_kurzbz = newTerminRes.paabgabetyp_kurzbz
|
||||
termin.noteBackend = noteOpt // do NOT take noteOptExisting -> should reflect the "yes the qgate grade is confirmed in backend ux behaviour"
|
||||
termin.dateStyle = getDateStyleClass(termin, this.notenOptions)
|
||||
}
|
||||
|
||||
this.projektarbeit.abgabetermine.sort((a, b) =>new Date(a.datum) - new Date(b.datum))
|
||||
this.projektarbeit.abgabetermine.sort((a, b) => compareISODateValues(a.datum, b.datum))
|
||||
|
||||
const index = this.projektarbeit.abgabetermine.findIndex(t => termin.paabgabe_id == t.paabgabe_id)
|
||||
|
||||
@@ -159,7 +160,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
'fixtermin': false,
|
||||
'invertedFixtermin': true,
|
||||
'kurzbz': '', // todo kurzbz textfield value vorschlag für qualgates
|
||||
'datum': new Date().toISOString().split('T')[0],
|
||||
'datum': getViennaTodayISO(),
|
||||
'note': this.allowedNotenOptions.find(opt => opt.note == 9),
|
||||
'beurteilungsnotiz': '',
|
||||
'upload_allowed': false,
|
||||
@@ -337,16 +338,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
}
|
||||
},
|
||||
formatDate(dateParam) {
|
||||
// unsafe for datepickers, dont use there
|
||||
const date = new Date(dateParam)
|
||||
// handle missing leading 0
|
||||
const padZero = (num) => String(num).padStart(2, '0');
|
||||
|
||||
const month = padZero(date.getMonth() + 1); // Months are zero-based
|
||||
const day = padZero(date.getDate());
|
||||
const year = date.getFullYear();
|
||||
|
||||
return `${day}.${month}.${year}`
|
||||
return formatISODate(dateParam)
|
||||
},
|
||||
openCreateNewAbgabeModal() {
|
||||
if(this.projektarbeit?.betreuerart_kurzbz == 'Zweitbegutachter') {
|
||||
@@ -364,7 +356,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
'fixtermin': false,
|
||||
'invertedFixtermin': true,
|
||||
'kurzbz': '',
|
||||
'datum': new Date().toISOString().split('T')[0],
|
||||
'datum': getViennaTodayISO(),
|
||||
'note': this.allowedNotenOptions.find(opt => opt.note == 9),
|
||||
'beurteilungsnotiz': '',
|
||||
'upload_allowed': typ.upload_allowed_default,
|
||||
@@ -398,7 +390,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
'fixtermin': false,
|
||||
'invertedFixtermin': true,
|
||||
'kurzbz': '',
|
||||
'datum': new Date().toISOString().split('T')[0],
|
||||
'datum': getViennaTodayISO(),
|
||||
'note': this.allowedNotenOptions.find(opt => opt.note == 9),
|
||||
'beurteilungsnotiz': '',
|
||||
'upload_allowed': false,
|
||||
@@ -446,7 +438,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
}
|
||||
},
|
||||
getMessagePtStyle() {
|
||||
// adjust outer spacing and internal padding to appear similar to doenload button in size
|
||||
// adjust outer spacing and internal padding to appear similar to download button in size
|
||||
return {
|
||||
root: {
|
||||
style: {
|
||||
@@ -561,6 +553,12 @@ export const AbgabeMitarbeiterDetail = {
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
},
|
||||
getTooltipBeurteilungsnotiz() {
|
||||
return {
|
||||
value: this.$p.t('abgabetool/c4beurteilungsnotizBeiNegNote'),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
},
|
||||
getProjektarbeitTitel() {
|
||||
if(this.projektarbeit?.titel) return this.$capitalize(this.$p.t('abgabetool/c4titel')) + ': ' + this.projektarbeit.titel
|
||||
|
||||
@@ -591,7 +589,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
'fixtermin': false,
|
||||
'invertedFixtermin': true,
|
||||
'kurzbz': '',
|
||||
'datum': new Date().toISOString().split('T')[0],
|
||||
'datum': getViennaTodayISO(),
|
||||
'note': this.allowedNotenOptions.find(opt => opt.note == 9),
|
||||
'beurteilungsnotiz': '',
|
||||
'upload_allowed': typ.upload_allowed_default,
|
||||
@@ -656,6 +654,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
:enable-time-picker="false"
|
||||
locale="de"
|
||||
format="dd.MM.yyyy"
|
||||
model-type="yyyy-MM-dd"
|
||||
:text-input="true"
|
||||
auto-apply>
|
||||
</VueDatePicker>
|
||||
@@ -806,6 +805,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
:enable-time-picker="false"
|
||||
locale="de"
|
||||
format="dd.MM.yyyy"
|
||||
model-type="yyyy-MM-dd"
|
||||
:text-input="true"
|
||||
auto-apply>
|
||||
</VueDatePicker>
|
||||
@@ -851,8 +851,10 @@ export const AbgabeMitarbeiterDetail = {
|
||||
</div>
|
||||
<div class="row mt-2" v-if="termin.bezeichnung?.benotbar">
|
||||
<div class="col-12 col-md-3 fw-bold align-content-center">{{$capitalize( $p.t('abgabetool/c4notizQualGatev2') )}}</div>
|
||||
<div class="col-12 col-md-9">
|
||||
<Textarea style="margin-bottom: 4px;" v-model="termin.beurteilungsnotiz" rows="1" class="w-100" :disabled="!termin.allowedToSave"></Textarea>
|
||||
<div class="col-12 col-md-9" v-tooltip.right="terminIsInvalid(termin) && getTooltipBeurteilungsnotiz">
|
||||
<Textarea style="margin-bottom: 4px;" v-model="termin.beurteilungsnotiz"
|
||||
:class="{ 'p-invalid': terminIsInvalid(termin) }"
|
||||
rows="1" class="w-100" :disabled="!termin.allowedToSave"></Textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -874,6 +876,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
:disabled="true"
|
||||
locale="de"
|
||||
format="dd.MM.yyyy"
|
||||
model-type="yyyy-MM-dd"
|
||||
>
|
||||
</VueDatePicker>
|
||||
</div>
|
||||
@@ -907,7 +910,7 @@ export const AbgabeMitarbeiterDetail = {
|
||||
<div class="col-12 col-md-9">
|
||||
<div class="row">
|
||||
<div class="col-auto">
|
||||
<button v-if="termin.allowedToSave" style="max-height: 40px;" class="btn btn-primary border-0" @click="saveTermin(termin)">
|
||||
<button v-if="termin.allowedToSave && !terminIsInvalid(termin)" style="max-height: 40px;" class="btn btn-primary border-0" @click="saveTermin(termin)">
|
||||
{{ $capitalize( $p.t('abgabetool/c4save') )}}
|
||||
<i class="fa-solid fa-floppy-disk"></i>
|
||||
</button>
|
||||
|
||||
@@ -3,6 +3,7 @@ import BsModal from '../../Bootstrap/Modal.js';
|
||||
import VueDatePicker from '../../vueDatepicker.js.php';
|
||||
import ApiAbgabe from '../../../api/factory/abgabe.js'
|
||||
import FhcOverlay from "../../Overlay/FhcOverlay.js";
|
||||
import { formatISODate, getViennaTodayISO } from "./dateUtils.js";
|
||||
|
||||
export const AbgabeStudentDetail = {
|
||||
name: "AbgabeStudentDetail",
|
||||
@@ -20,7 +21,7 @@ export const AbgabeStudentDetail = {
|
||||
VueDatePicker,
|
||||
FhcOverlay
|
||||
},
|
||||
inject: ['notenOptions', 'isMobile', 'isViewMode', 'moodle_link'],
|
||||
inject: ['notenOptions', 'isMobile', 'isViewMode', 'moodle_link', 'confetti_on_endupload', 'title_edit_allowed'],
|
||||
props: {
|
||||
projektarbeit: {
|
||||
type: Object,
|
||||
@@ -31,12 +32,14 @@ export const AbgabeStudentDetail = {
|
||||
default: false
|
||||
}
|
||||
},
|
||||
emits: ['titel-updated'],
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
eidAkzeptiert: false,
|
||||
enduploadTermin: null,
|
||||
allActiveLanguages: FHC_JS_DATA_STORAGE_OBJECT.server_languages,
|
||||
editingTitel: '',
|
||||
form: Vue.reactive({
|
||||
sprache: '',
|
||||
abstract: '',
|
||||
@@ -49,9 +52,113 @@ export const AbgabeStudentDetail = {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
confettiCannons() {
|
||||
const container = document.getElementById('confetti-container');
|
||||
if (!container) return;
|
||||
|
||||
const colors = ['#FFC107', '#FF5722', '#E91E63', '#00BCD4', '#4CAF50', '#9C27B0'];
|
||||
const shapes = ['50%', '0%'];
|
||||
const fragment = document.createDocumentFragment();
|
||||
|
||||
// Corner Cannons - Slowed Down)
|
||||
const cannonCount = 150;
|
||||
|
||||
for (let i = 0; i < cannonCount; i++) {
|
||||
const leftConfetti = document.createElement('div');
|
||||
leftConfetti.classList.add('confetti-piece');
|
||||
leftConfetti.style.left = '0px';
|
||||
leftConfetti.style.top = '100%';
|
||||
|
||||
const rightConfetti = document.createElement('div');
|
||||
rightConfetti.classList.add('confetti-piece');
|
||||
rightConfetti.style.left = '100vw';
|
||||
rightConfetti.style.top = '100%';
|
||||
|
||||
const colorL = colors[Math.floor(Math.random() * colors.length)];
|
||||
const colorR = colors[Math.floor(Math.random() * colors.length)];
|
||||
const shapeL = shapes[Math.floor(Math.random() * shapes.length)];
|
||||
const shapeR = shapes[Math.floor(Math.random() * shapes.length)];
|
||||
|
||||
// Left Styles
|
||||
leftConfetti.style.background = colorL;
|
||||
leftConfetti.style.borderRadius = shapeL;
|
||||
leftConfetti.style.width = `${Math.random() * 10 + 6}px`;
|
||||
leftConfetti.style.height = `${Math.random() * 14 + 6}px`;
|
||||
leftConfetti.style.setProperty('--blast-x', `${Math.random() * 50 + 10}vw`);
|
||||
leftConfetti.style.setProperty('--blast-y', `-${Math.random() * 65 + 30}vh`);
|
||||
|
||||
// Right Styles
|
||||
rightConfetti.style.background = colorR;
|
||||
rightConfetti.style.borderRadius = shapeR;
|
||||
rightConfetti.style.width = `${Math.random() * 10 + 6}px`;
|
||||
rightConfetti.style.height = `${Math.random() * 14 + 6}px`;
|
||||
rightConfetti.style.setProperty('--blast-x', `-${Math.random() * 50 + 10}vw`);
|
||||
rightConfetti.style.setProperty('--blast-y', `-${Math.random() * 65 + 30}vh`);
|
||||
|
||||
// Increased durations to 3s - 5s for a floating gravity effect
|
||||
const durationL = Math.random() * 2 + 3;
|
||||
const durationR = Math.random() * 2 + 3;
|
||||
const delayL = Math.random() * 0.2;
|
||||
const delayR = Math.random() * 0.2;
|
||||
|
||||
leftConfetti.style.animation = `cannonBlast ${durationL}s linear ${delayL}s both`;
|
||||
rightConfetti.style.animation = `cannonBlast ${durationR}s linear ${delayR}s both`;
|
||||
|
||||
fragment.appendChild(leftConfetti);
|
||||
fragment.appendChild(rightConfetti);
|
||||
|
||||
setTimeout(() => leftConfetti.remove(), (delayL + durationL) * 1000);
|
||||
setTimeout(() => rightConfetti.remove(), (delayR + durationR) * 1000);
|
||||
}
|
||||
|
||||
container.appendChild(fragment);
|
||||
},
|
||||
openTitelEdit() {
|
||||
this.editingTitel = this.projektarbeit.titel ?? '';
|
||||
this.$refs.modalTitelEdit.show();
|
||||
},
|
||||
async saveTitel() {
|
||||
const trimmed = this.editingTitel.trim();
|
||||
if (!trimmed) {
|
||||
this.$fhcAlert.alertWarning(this.$capitalize(this.$p.t('global/warningEmptyField')));
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmed = await this.$fhcAlert.confirm({
|
||||
message: this.$p.t('abgabetool/c4confirmTitelSpeichern'),
|
||||
acceptLabel: this.$capitalize(this.$p.t('ui/speichern')),
|
||||
acceptClass: 'p-button-primary',
|
||||
rejectLabel: this.$capitalize(this.$p.t('abgabetool/c4Cancel')),
|
||||
rejectClass: 'p-button-secondary'
|
||||
});
|
||||
|
||||
if (confirmed === false) return;
|
||||
|
||||
this.loading = true;
|
||||
this.$api.call(
|
||||
ApiAbgabe.postStudentProjektarbeitTitel(
|
||||
this.projektarbeit.projektarbeit_id,
|
||||
trimmed
|
||||
)
|
||||
).then(res => {
|
||||
if (res.meta.status === 'success') {
|
||||
this.projektarbeit.titel = trimmed;
|
||||
this.$emit('titel-updated', {
|
||||
projektarbeit_id: this.projektarbeit.projektarbeit_id,
|
||||
titel: trimmed
|
||||
});
|
||||
this.$fhcAlert.alertSuccess(this.$capitalize(this.$p.t('abgabetool/c4titelSavedSuccess')));
|
||||
this.$refs.modalTitelEdit.hide();
|
||||
} else {
|
||||
this.$fhcAlert.alertError(this.$capitalize(this.$p.t('abgabetool/c4titelSaveError')));
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
getNoteBezeichnung(termin){
|
||||
const noteOpt = this.notenOptions.find(opt => opt.note == termin.note)
|
||||
|
||||
|
||||
if(noteOpt?.bezeichnung) {
|
||||
return noteOpt?.positiv ? this.$capitalize(this.$p.t('abgabetool/c4positivBenotet')) + ' ✅' : this.$capitalize(this.$p.t('abgabetool/c4negativBenotet')) + ' ❌'
|
||||
} else if(noteOpt?.benotbar === true && !termin.note) {
|
||||
@@ -65,7 +172,7 @@ export const AbgabeStudentDetail = {
|
||||
this.$fhcAlert.alertWarning(this.$capitalize(this.$p.t('global/warningChooseFile')));
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
if(endupload) {
|
||||
if(await this.$fhcAlert.confirm({
|
||||
message: this.$p.t('abgabetool/confirmEnduploadSpeichern'),
|
||||
@@ -77,16 +184,16 @@ export const AbgabeStudentDetail = {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
},
|
||||
async triggerEndupload() {
|
||||
|
||||
|
||||
if (!await this.validate(this.enduploadTermin, true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// post endabgabe
|
||||
const formData = new FormData();
|
||||
formData.append('paabgabetyp_kurzbz', this.enduploadTermin.paabgabetyp_kurzbz)
|
||||
@@ -94,14 +201,14 @@ export const AbgabeStudentDetail = {
|
||||
formData.append('paabgabe_id', this.enduploadTermin.paabgabe_id)
|
||||
formData.append('student_uid', this.projektarbeit.student_uid)
|
||||
formData.append('bperson_id', this.projektarbeit.bperson_id)
|
||||
|
||||
|
||||
formData.append('sprache', this.form['sprache'].sprache)
|
||||
formData.append('abstract', this.form['abstract'])
|
||||
formData.append('abstract_en', this.form['abstract_en'])
|
||||
formData.append('schlagwoerter', this.form['schlagwoerter'])
|
||||
formData.append('schlagwoerter_en', this.form['schlagwoerter_en'])
|
||||
formData.append('seitenanzahl', this.form['seitenanzahl'])
|
||||
|
||||
|
||||
for (let i = 0; i < this.enduploadTermin.file.length; i++) {
|
||||
formData.append('file', this.enduploadTermin.file[i]);
|
||||
}
|
||||
@@ -109,39 +216,31 @@ export const AbgabeStudentDetail = {
|
||||
this.$api.call(ApiAbgabe.postStudentProjektarbeitEndupload(formData))
|
||||
.then(res => {
|
||||
this.handleUploadRes(res, this.enduploadTermin)
|
||||
if(this.confetti_on_endupload && res.meta.status == "success") {
|
||||
this.confettiCannons()
|
||||
}
|
||||
}).finally(()=> {
|
||||
this.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
|
||||
|
||||
this.$refs.modalContainerEnduploadZusatzdaten.hide()
|
||||
},
|
||||
downloadAbgabe(termin) {
|
||||
const url = `/api/frontend/v1/Abgabe/getStudentProjektarbeitAbgabeFile?paabgabe_id=${termin.paabgabe_id}&student_uid=${this.projektarbeit.student_uid}&projektarbeit_id=${this.projektarbeit.projektarbeit_id}`;
|
||||
|
||||
window.open(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + url)
|
||||
// this.$api.call(ApiAbgabe.getStudentProjektarbeitAbgabeFile(termin.paabgabe_id, this.projektarbeit.student_uid))
|
||||
},
|
||||
formatDate(dateParam) {
|
||||
const date = new Date(dateParam)
|
||||
// handle missing leading 0
|
||||
const padZero = (num) => String(num).padStart(2, '0');
|
||||
|
||||
const month = padZero(date.getMonth() + 1); // Months are zero-based
|
||||
const day = padZero(date.getDate());
|
||||
const year = date.getFullYear();
|
||||
|
||||
return `${day}.${month}.${year}`
|
||||
return formatISODate(dateParam)
|
||||
},
|
||||
async upload(termin) {
|
||||
|
||||
// only do this on endupload
|
||||
if (! await this.validate(termin))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if(termin.bezeichnung?.paabgabetyp_kurzbz === 'end') {
|
||||
// open endupload form modal for further inputs
|
||||
this.enduploadTermin = termin
|
||||
this.$refs.modalContainerEnduploadZusatzdaten.show()
|
||||
} else {
|
||||
@@ -151,7 +250,7 @@ export const AbgabeStudentDetail = {
|
||||
formData.append('paabgabe_id', termin.paabgabe_id)
|
||||
formData.append('student_uid', this.projektarbeit.student_uid)
|
||||
formData.append('bperson_id', this.projektarbeit.bperson_id)
|
||||
|
||||
|
||||
for (let i = 0; i < termin.file.length; i++) {
|
||||
formData.append('file', termin.file[i]);
|
||||
}
|
||||
@@ -161,7 +260,7 @@ export const AbgabeStudentDetail = {
|
||||
.then(res => {
|
||||
this.handleUploadRes(res, termin)
|
||||
}).finally(()=> {
|
||||
this.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -169,21 +268,18 @@ export const AbgabeStudentDetail = {
|
||||
if(res.meta.status == "success") {
|
||||
this.$fhcAlert.alertSuccess(this.$capitalize(this.$p.t('abgabetool/c4fileUploadSuccessv3')))
|
||||
|
||||
// update 'abgabedatum' for successful upload -> shows the pdf icon and date once set
|
||||
termin.abgabedatum = new Date().toISOString().split('T')[0];
|
||||
termin.abgabedatum = getViennaTodayISO();
|
||||
if(res?.data?.signatur !== undefined) {
|
||||
termin.signatur = res.data.signatur
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
this.$fhcAlert.alertError(this.$capitalize(this.$p.t('abgabetool/c4fileUploadErrorv3')))
|
||||
}
|
||||
|
||||
|
||||
if(res.meta.signaturInfo) {
|
||||
this.$fhcAlert.alertInfo(res.meta.signaturInfo)
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
getOptionLabel(option) {
|
||||
return option.sprache
|
||||
@@ -195,7 +291,6 @@ export const AbgabeStudentDetail = {
|
||||
},
|
||||
watch: {
|
||||
projektarbeit(newVal) {
|
||||
// default select german if projektarbeit sprache was null
|
||||
this.form.sprache = newVal.sprache ? this.allActiveLanguages.find(lang => lang.sprache == newVal.sprache) : this.allActiveLanguages.find(lang => lang.sprache == 'German')
|
||||
this.form.abstract = newVal.abstract ?? ''
|
||||
this.form.abstract_en = newVal.abstract_en ?? ''
|
||||
@@ -203,15 +298,13 @@ export const AbgabeStudentDetail = {
|
||||
this.form.schlagwoerter_en = newVal.schlagwoerter_en ?? ''
|
||||
this.form.kontrollschlagwoerter = newVal.kontrollschlagwoerter ?? ''
|
||||
this.form.seitenanzahl = newVal.seitenanzahl ?? 1
|
||||
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getMoodleLink() {
|
||||
return this.moodle_link + this.projektarbeit.studiengang_kz
|
||||
return this.moodle_link + this.projektarbeit.studiengang_kz
|
||||
},
|
||||
getMessagePtStyle() {
|
||||
// adjust outer spacing and internal padding to appear similar to doenload button in size
|
||||
return {
|
||||
root: {
|
||||
style: {
|
||||
@@ -244,85 +337,46 @@ export const AbgabeStudentDetail = {
|
||||
})
|
||||
return qgatefound
|
||||
},
|
||||
isTitelEditAllowed() {
|
||||
return this.title_edit_allowed && !this.isViewMode && !this.projektarbeit?.note;
|
||||
},
|
||||
getTooltipVerspaetet() {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4tooltipVerspaetet')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4tooltipVerspaetet')), class: "custom-tooltip" }
|
||||
},
|
||||
getTooltipVerpasst() {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4tooltipVerpasst')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4tooltipVerpasst')), class: "custom-tooltip" }
|
||||
},
|
||||
getTooltipAbzugeben() {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4tooltipAbzugeben')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4tooltipAbzugeben')), class: "custom-tooltip" }
|
||||
},
|
||||
getTooltipStandard() {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4tooltipStandardv2')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4tooltipStandardv2')), class: "custom-tooltip" }
|
||||
},
|
||||
getTooltipAbgegeben() {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4tooltipAbgegeben')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4tooltipAbgegeben')), class: "custom-tooltip" }
|
||||
},
|
||||
getTooltipFixtermin() {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4tooltipFixtermin')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4tooltipFixtermin')), class: "custom-tooltip" }
|
||||
},
|
||||
getTooltipAbgabeDetected() {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4tooltipAbgabeDetected')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4tooltipAbgabeDetected')), class: "custom-tooltip" }
|
||||
},
|
||||
getTooltipNotAllowedToUpload() {
|
||||
if(this.isViewMode) {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4studentAbgabeNotAllowedInViewMode')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4studentAbgabeNotAllowedInViewMode')), class: "custom-tooltip" }
|
||||
} else {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4studentAbgabeNotAllowedRegular')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4studentAbgabeNotAllowedRegular')), class: "custom-tooltip" }
|
||||
}
|
||||
},
|
||||
getTooltipBeurteilungerforderlich() {
|
||||
return {
|
||||
value: this.$capitalize(this.$p.t('abgabetool/c4tooltipBeurteilungerforderlich')),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$capitalize(this.$p.t('abgabetool/c4tooltipBeurteilungerforderlich')), class: "custom-tooltip" }
|
||||
},
|
||||
getTooltipBestanden() {
|
||||
return {
|
||||
value: this.$p.t('abgabetool/c4tooltipBestanden'),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$p.t('abgabetool/c4tooltipBestanden'), class: "custom-tooltip" }
|
||||
},
|
||||
getTooltipNichtBestanden() {
|
||||
return {
|
||||
value: this.$p.t('abgabetool/c4tooltipNichtBestanden'),
|
||||
class: "custom-tooltip"
|
||||
}
|
||||
return { value: this.$p.t('abgabetool/c4tooltipNichtBestanden'), class: "custom-tooltip" }
|
||||
},
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
|
||||
},
|
||||
template: `
|
||||
<FhcOverlay :active="loading"></FhcOverlay>
|
||||
@@ -332,9 +386,24 @@ export const AbgabeStudentDetail = {
|
||||
<h5>{{$capitalize( $p.t('abgabetool/c4abgabeStudentenbereich') )}}</h5>
|
||||
<div class="row">
|
||||
<div class="col-8">
|
||||
<p> {{$capitalize( $p.t('person/student') ) }}: {{projektarbeit?.student}}</p>
|
||||
<p> {{$capitalize( $p.t('abgabetool/c4titel') ) }}: {{projektarbeit?.titel}}</p>
|
||||
<p> {{$capitalize( $p.t('abgabetool/c4betreuerv2') ) }}: {{projektarbeit ? $p.t('abgabetool/c4betrart' + projektarbeit.betreuerart_kurzbz) + ' ' + projektarbeit.betreuer : ''}}</p>
|
||||
<p>{{$capitalize( $p.t('person/student') ) }}: {{projektarbeit?.student}}</p>
|
||||
|
||||
<p class="d-flex align-items-center gap-2 mb-2" style="min-width: 0;">
|
||||
<span
|
||||
:title="projektarbeit.titel"
|
||||
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 480px;"
|
||||
>{{$capitalize( $p.t('abgabetool/c4titel') ) }}: {{projektarbeit?.titel}}</span>
|
||||
<button
|
||||
v-if="isTitelEditAllowed"
|
||||
class="btn btn-sm btn-outline-secondary border-0 p-1"
|
||||
v-tooltip.right="{ value: $capitalize($p.t('abgabetool/c4titelBearbeiten')), class: 'custom-tooltip' }"
|
||||
@click="openTitelEdit"
|
||||
>
|
||||
<i class="fa-solid fa-pen"></i>
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<p>{{$capitalize( $p.t('abgabetool/c4betreuerv2') ) }}: {{projektarbeit ? $p.t('abgabetool/c4betrart' + projektarbeit.betreuerart_kurzbz) + ' ' + projektarbeit.betreuer : ''}}</p>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<p>{{ $p.t('abgabetool/c4checkoutStgMoodleInfos') }}
|
||||
@@ -357,7 +426,6 @@ export const AbgabeStudentDetail = {
|
||||
<i v-else-if="termin.dateStyle == 'beurteilungerforderlich'" v-tooltip.right="getTooltipBeurteilungerforderlich" class="fa-solid fa-list-check"></i>
|
||||
<i v-else-if="termin.dateStyle == 'bestanden'" v-tooltip.right="getTooltipBestanden" class="fa-solid fa-check"></i>
|
||||
<i v-else-if="termin.dateStyle == 'nichtbestanden'" v-tooltip.right="getTooltipNichtBestanden" class="fa-solid fa-circle-exclamation"></i>
|
||||
|
||||
</div>
|
||||
<div class="text-start px-2" style="min-width: 150px; max-width: 300px; margin-left: 40px">
|
||||
<span>{{ termin ? $p.t('abgabetool/c4paatyp' + termin.paabgabetyp_kurzbz) : '' }}</span>
|
||||
@@ -408,8 +476,6 @@ export const AbgabeStudentDetail = {
|
||||
</div>
|
||||
</template>
|
||||
</Inplace>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
@@ -430,7 +496,7 @@ export const AbgabeStudentDetail = {
|
||||
</VueDatePicker>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="col-12 col-md-3 fw-bold align-content-center">{{$capitalize( $p.t('abgabetool/c4abgabetyp') )}}</div>
|
||||
<div class="col-12 col-md-9">
|
||||
@@ -481,9 +547,6 @@ export const AbgabeStudentDetail = {
|
||||
<Message v-else-if="termin?.signatur == false" severity="error" :closable="false" :pt="getMessagePtStyle"> {{ $p.t('abgabetool/c4keineSignatur') }} </Message>
|
||||
<Message v-else-if="termin?.signatur == 'error'" severity="warn" :closable="false" :pt="getMessagePtStyle"> {{ $p.t('abgabetool/c4signaturServerError') }} </Message>
|
||||
</div>
|
||||
<!-- <div v-else class="col-auto">-->
|
||||
<!-- <Message severity="info" :closable="false" :pt="getMessagePtStyle"> {{ $p.t('abgabetool/c4noFileFound') }} </Message>-->
|
||||
<!-- </div>-->
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
@@ -542,8 +605,51 @@ export const AbgabeStudentDetail = {
|
||||
<h5>{{ $capitalize( $p.t('abgabetool/c4keineAbgabetermineGefunden') )}}</h5>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div v-if="confetti_on_endupload" id="confetti-container"></div>
|
||||
|
||||
<bs-modal
|
||||
ref="modalTitelEdit"
|
||||
class="bootstrap-prompt"
|
||||
dialogClass="bordered-modal"
|
||||
>
|
||||
<template v-slot:title>
|
||||
{{$capitalize( $p.t('abgabetool/c4titelBearbeiten') )}}
|
||||
</template>
|
||||
<template v-slot:default>
|
||||
<div class="mb-2">
|
||||
<label class="form-label fw-bold">
|
||||
{{$capitalize( $p.t('abgabetool/c4titel') )}}
|
||||
</label>
|
||||
<Textarea
|
||||
v-model="editingTitel"
|
||||
rows="10"
|
||||
maxlength="1024"
|
||||
class="form-control w-100"
|
||||
@keydown.enter.prevent="saveTitel"
|
||||
/>
|
||||
<div class="form-text text-end">{{ editingTitel.length }} / 1024</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
@click="$refs.modalTitelEdit.hide()"
|
||||
>
|
||||
{{$capitalize( $p.t('abgabetool/c4Cancel') )}}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
:disabled="!editingTitel.trim()"
|
||||
@click="saveTitel"
|
||||
>
|
||||
<i class="fa-solid fa-floppy-disk me-1"></i>
|
||||
{{$capitalize( $p.t('ui/speichern') )}}
|
||||
</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
|
||||
<bs-modal
|
||||
ref="modalContainerEnduploadZusatzdaten"
|
||||
class="bootstrap-prompt"
|
||||
@@ -553,14 +659,10 @@ export const AbgabeStudentDetail = {
|
||||
{{$capitalize( $p.t('abgabetool/c4enduploadZusatzdaten') )}}
|
||||
</div>
|
||||
<div class="row mb-3 align-items-start">
|
||||
|
||||
<p class="ml-4 mr-4">Student UID: {{ projektarbeit?.student_uid}}</p>
|
||||
|
||||
</div>
|
||||
<div class="row mb-3 align-items-start">
|
||||
|
||||
<p class="ml-4 mr-4">{{$capitalize( $p.t('abgabetool/c4titel') )}}: {{ projektarbeit?.titel }}</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:default>
|
||||
@@ -576,15 +678,6 @@ export const AbgabeStudentDetail = {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- lektor fills these out-->
|
||||
<!-- <div class="row mb-3 align-items-start">-->
|
||||
<!-- <div class="row">Kontrollierte Schlagwörter</div>-->
|
||||
<!-- <div class="row">-->
|
||||
<!-- <Textarea v-model="form.kontrollschlagwoerter"></Textarea>-->
|
||||
<!-- </div>-->
|
||||
<!-- -->
|
||||
<!-- -->
|
||||
<!-- </div>-->
|
||||
<div class="row mb-3 align-items-start">
|
||||
<div class="row">{{$capitalize( $p.t('abgabetool/c4schlagwoerterGer') )}}</div>
|
||||
<div class="row">
|
||||
@@ -631,7 +724,6 @@ export const AbgabeStudentDetail = {
|
||||
<div class="col-9"></div>
|
||||
<div class="col-2"><p>{{$capitalize( $p.t('abgabetool/c4gelesenUndAkzeptiert') )}}</p></div>
|
||||
<div class="col-1">
|
||||
|
||||
<Checkbox
|
||||
v-model="eidAkzeptiert"
|
||||
:binary="true"
|
||||
@@ -647,8 +739,8 @@ export const AbgabeStudentDetail = {
|
||||
<div v-show="!allowedToSaveZusatzdaten">{{ $p.t('abgabetool/c4zusatzdatenausfuellen') }}</div>
|
||||
<button class="btn btn-primary" :disabled="!getAllowedToSendEndupload" @click="triggerEndupload">{{$capitalize( $p.t('ui/hochladen') )}}</button>
|
||||
</template>
|
||||
|
||||
</bs-modal>
|
||||
|
||||
`,
|
||||
};
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,6 +7,7 @@ import FhcOverlay from "../../Overlay/FhcOverlay.js";
|
||||
import { getDateStyleClass } from "./getDateStyleClass.js";
|
||||
import { dateFilter } from '../../../tabulator/filters/Dates.js';
|
||||
import {splitMailsHelper} from "../../../helpers/EmailHelpers.js";
|
||||
import { formatISODate, getViennaTodayISO, toViennaDate } from "./dateUtils.js";
|
||||
|
||||
export const AbgabetoolMitarbeiter = {
|
||||
name: "AbgabetoolMitarbeiter",
|
||||
@@ -43,7 +44,12 @@ export const AbgabetoolMitarbeiter = {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableData: null,
|
||||
filteredRows: null,
|
||||
count: 0,
|
||||
filteredcount: 0,
|
||||
selectedcount: 0,
|
||||
qgate1FilterSelected: [],
|
||||
qgate2FilterSelected: [],
|
||||
abgabetypenBetreuer: null,
|
||||
detailIsFullscreen: false,
|
||||
phrasenPromise: null,
|
||||
@@ -58,7 +64,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
allowedNotenOptions: null,
|
||||
notenOptionsNonFinal: null,
|
||||
serienTermin: Vue.reactive({
|
||||
datum: new Date(),
|
||||
datum: getViennaTodayISO(),
|
||||
bezeichnung: {
|
||||
paabgabetyp_kurzbz: 'zwischen',
|
||||
bezeichnung: 'Zwischenabgabe'
|
||||
@@ -80,7 +86,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
abgabeTableOptions: {
|
||||
minHeight: 250,
|
||||
index: 'projektarbeit_id',
|
||||
layout: 'fitDataStretch',
|
||||
layout: 'fitData',
|
||||
placeholder: Vue.computed(() => this.$p.t('global/noDataAvailable')),
|
||||
selectable: true,
|
||||
selectableCheck: this.selectionCheck,
|
||||
@@ -138,38 +144,65 @@ export const AbgabetoolMitarbeiter = {
|
||||
handleClick: this.selectAllHandler
|
||||
},
|
||||
width: 50,
|
||||
cssClass: 'sticky-col'
|
||||
cssClass: 'sticky-col',
|
||||
visible: true
|
||||
},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.detailFormatter, headerFilter: false, headerSort: false, widthGrow: 1, tooltip: false, cssClass: 'sticky-col'},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4personenkennzeichen'))), headerFilter: true, field: 'pkz', formatter: this.pkzTextFormatter, widthGrow: 1, tooltip: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4vorname'))), field: 'vorname', headerFilter: true, formatter: this.centeredTextFormatter,widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nachname'))), field: 'nachname', headerFilter: true, formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4projekttyp'))), field: 'projekttyp_kurzbz', formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4stg'))), field: 'stg', headerFilter: true, formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4sem'))), field: 'studiensemester_kurzbz', headerFilter: true, formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4titel'))), field: 'titel', headerFilter: true, formatter: this.centeredTextFormatter, maxWidth: 500, widthGrow: 8},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4betreuerartv2'))), field: 'betreuerart_beschreibung',formatter: this.centeredTextFormatter, widthGrow: 1},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4prevAbgabetermin'))), field: 'prevTermin',
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4details'))), field: 'details', formatter: this.detailFormatter, headerFilter: false, headerSort: false, minWidth: 50, 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/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/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/c4prevAbgabetermin'))),
|
||||
headerFilter: dateFilter,
|
||||
headerFilterFunc: this.headerFilterTerminCol,
|
||||
sorter: this.sortFuncTerminCol,
|
||||
formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false},
|
||||
tooltip: this.toolTipFuncPrevTermin,
|
||||
field: 'prevTermin', formatter: this.abgabterminFormatter, width: 250, visible: false},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4nextAbgabetermin'))), field: 'nextTermin',
|
||||
headerFilter: dateFilter,
|
||||
headerFilterFunc: this.headerFilterTerminCol,
|
||||
sorter: this.sortFuncTerminCol,
|
||||
formatter: this.abgabterminFormatter, widthGrow: 1, width: 250, tooltip: false},
|
||||
tooltip: this.toolTipFuncNextTermin,
|
||||
formatter: this.abgabterminFormatter, width: 250, visible: true},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4qgate1Status'))),
|
||||
headerFilter: 'list',
|
||||
headerFilterParams: { valuesLookup: this.getQGateStatusList },
|
||||
field: 'qgate1Status', formatter: this.centeredTextFormatter, widthGrow: 1, width: 220, tooltip: false},
|
||||
headerFilter: this.qgateHeaderFilterEditor,
|
||||
headerFilterFunc: this.qgateHeaderFilterFunc,
|
||||
headerFilterParams: {},
|
||||
field: 'qgate1Status',
|
||||
formatter: this.centeredTextFormatter,
|
||||
titleFormatter: this.shortLongTitleFormatter,
|
||||
titleFormatterParams: {
|
||||
shortForm: 'QG1'
|
||||
},
|
||||
width: 50,
|
||||
tooltip: (e, cell) => {
|
||||
const data = cell.getData();
|
||||
return data.qgate1Status
|
||||
}
|
||||
},
|
||||
{title: Vue.computed(() => this.$capitalize(this.$p.t('abgabetool/c4qgate2Status'))),
|
||||
headerFilter: 'list',
|
||||
headerFilterParams: { valuesLookup: this.getQGateStatusList },
|
||||
field: 'qgate2Status', formatter: this.centeredTextFormatter, widthGrow: 1, width: 220, tooltip: false}
|
||||
headerFilter: this.qgateHeaderFilterEditor,
|
||||
headerFilterFunc: this.qgateHeaderFilterFunc,
|
||||
headerFilterParams: {},
|
||||
field: 'qgate2Status',
|
||||
formatter: this.centeredTextFormatter,
|
||||
titleFormatter: this.shortLongTitleFormatter,
|
||||
titleFormatterParams: {
|
||||
shortForm: 'QG2'
|
||||
},
|
||||
width: 50,
|
||||
tooltip: (e, cell) => {
|
||||
const data = cell.getData();
|
||||
return data.qgate2Status
|
||||
}
|
||||
}
|
||||
],
|
||||
persistence: false,
|
||||
persistenceID: 'abgabeTableBetreuer2026-02-26'
|
||||
persistenceID: 'abgabeTableBetreuer2026-05-26'
|
||||
},
|
||||
abgabeTableEventHandlers: [{
|
||||
event: "tableBuilt",
|
||||
@@ -200,11 +233,293 @@ export const AbgabetoolMitarbeiter = {
|
||||
})
|
||||
|
||||
this.selectedData = data
|
||||
this.selectedcount = data.length;
|
||||
}
|
||||
},
|
||||
{
|
||||
event: 'dataFiltered',
|
||||
handler: (filters, rows) => {
|
||||
this.filteredRows = rows;
|
||||
this.filteredcount = rows.length;
|
||||
|
||||
if (!this.selectedData.length) return;
|
||||
|
||||
const visibleData = new Set(rows.map(r => r.getData()));
|
||||
const filteredOut = this.selectedData.filter(sd => !visibleData.has(sd));
|
||||
|
||||
if (!filteredOut.length) return;
|
||||
|
||||
const filteredOutSet = new Set(filteredOut);
|
||||
this.$refs.abgabeTable.tabulator.getSelectedRows()
|
||||
.filter(r => filteredOutSet.has(r.getData()))
|
||||
.forEach(r => r.deselect());
|
||||
}
|
||||
}
|
||||
]};
|
||||
},
|
||||
methods: {
|
||||
getDateStyleHtml(dateStyle) {
|
||||
const iconMap = {
|
||||
'verspaetet': '<i class="fa-solid fa-triangle-exclamation"></i>',
|
||||
'verpasst': '<i class="fa-solid fa-calendar-xmark"></i>',
|
||||
'abzugeben': '<i class="fa-solid fa-hourglass-half"></i>',
|
||||
'standard': '<i class="fa-solid fa-clock"></i>',
|
||||
'abgegeben': '<i class="fa-solid fa-paperclip"></i>',
|
||||
'beurteilungerforderlich': '<i class="fa-solid fa-list-check"></i>',
|
||||
'bestanden': '<i class="fa-solid fa-check"></i>',
|
||||
'nichtbestanden': '<i class="fa-solid fa-circle-exclamation"></i>',
|
||||
};
|
||||
return iconMap[dateStyle] ?? '';
|
||||
},
|
||||
statusHeaderFilterEditor(cell, onRendered, success, cancel, editorParams) {
|
||||
const options = [
|
||||
{ label: this.$p.t('abgabetool/c4positivBenotet'), value: 'bestanden', dateStyle: 'bestanden' },
|
||||
{ label: this.$p.t('abgabetool/c4negativBenotet'), value: 'nichtbestanden', dateStyle: 'nichtbestanden' },
|
||||
{ label: this.$p.t('abgabetool/c4tooltipVerspaetet'), value: 'verspaetet', dateStyle: 'verspaetet' },
|
||||
{ label: this.$p.t('abgabetool/c4tooltipVerpasst'), value: 'verpasst', dateStyle: 'verpasst' },
|
||||
{ label: this.$p.t('abgabetool/c4tooltipAbzugeben'), value: 'abzugeben', dateStyle: 'abzugeben' },
|
||||
{ label: this.$p.t('abgabetool/c4tooltipAbgegeben'), value: 'abgegeben', dateStyle: 'abgegeben' },
|
||||
{ label: this.$p.t('abgabetool/c4tooltipBeurteilungerforderlich'), value: 'beurteilungerforderlich', dateStyle: 'beurteilungerforderlich' },
|
||||
{ label: this.$p.t('abgabetool/c4tooltipStandardv2'), value: 'standard', dateStyle: 'standard' },
|
||||
];
|
||||
|
||||
const field = cell.getField();
|
||||
const stateKey = field + 'FilterSelected'; // e.g. dateStyleFilterSelected
|
||||
let selected = [...(this[stateKey] || [])];
|
||||
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.style.cssText = 'position: relative; width: 100%;';
|
||||
|
||||
const display = document.createElement('input');
|
||||
display.readOnly = true;
|
||||
display.placeholder = '';
|
||||
display.style.cssText = 'padding: 4px; width: 100%; box-sizing: border-box; cursor: default; border: 1px solid; outline: none; background: #fff; appearance: none; caret-color: transparent;';
|
||||
|
||||
const dropdown = document.createElement('div');
|
||||
dropdown.style.cssText = 'display: none; position: fixed; background: #fff; border: 1px solid; z-index: 9999; min-width: 220px; box-shadow: 0 2px 6px rgba(0,0,0,0.15);';
|
||||
|
||||
const updateDisplay = () => {
|
||||
display.value = options
|
||||
.filter(o => selected.includes(o.value))
|
||||
.map(o => o.label)
|
||||
.join(', ');
|
||||
};
|
||||
|
||||
options.forEach(opt => {
|
||||
const row = document.createElement('label');
|
||||
row.style.cssText = 'display: flex; align-items: center; gap: 0; cursor: pointer; white-space: nowrap; padding-right: 8px;';
|
||||
row.addEventListener('mousedown', e => e.preventDefault());
|
||||
|
||||
const cb = document.createElement('input');
|
||||
cb.type = 'checkbox';
|
||||
cb.value = opt.value;
|
||||
cb.checked = selected.includes(opt.value);
|
||||
cb.style.cssText = 'margin: 0 6px;';
|
||||
cb.addEventListener('change', () => {
|
||||
selected = cb.checked
|
||||
? [...selected, opt.value]
|
||||
: selected.filter(v => v !== opt.value);
|
||||
this[stateKey] = [...selected];
|
||||
updateDisplay();
|
||||
success([...selected]);
|
||||
});
|
||||
|
||||
// icon badge — same look as cell
|
||||
const badge = document.createElement('div');
|
||||
badge.className = opt.dateStyle + '-header';
|
||||
badge.style.cssText = `min-width: 36px; height: 36px; display: flex; align-items: center;
|
||||
justify-content: center; flex-shrink: 0; padding: 0px 17px 0px 17px;`;
|
||||
badge.innerHTML = this.getDateStyleHtml(opt.dateStyle);
|
||||
|
||||
const labelText = document.createElement('span');
|
||||
labelText.textContent = opt.label;
|
||||
labelText.style.cssText = 'margin-left: 6px;';
|
||||
|
||||
row.appendChild(cb);
|
||||
row.appendChild(badge);
|
||||
row.appendChild(labelText);
|
||||
dropdown.appendChild(row);
|
||||
});
|
||||
|
||||
updateDisplay();
|
||||
|
||||
display.addEventListener('click', () => {
|
||||
if (dropdown.style.display === 'none') {
|
||||
const rect = display.getBoundingClientRect();
|
||||
dropdown.style.top = rect.bottom + 'px';
|
||||
dropdown.style.left = rect.left + 'px';
|
||||
dropdown.style.display = 'block';
|
||||
} else {
|
||||
dropdown.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
display.addEventListener('blur', () => {
|
||||
setTimeout(() => { dropdown.style.display = 'none'; }, 150);
|
||||
});
|
||||
|
||||
document.body.appendChild(dropdown);
|
||||
wrapper.appendChild(display);
|
||||
cell.getElement().addEventListener('remove', () => dropdown.remove());
|
||||
onRendered(() => display.focus());
|
||||
|
||||
return wrapper;
|
||||
},
|
||||
statusHeaderFilterFunc(filterVal, rowVal, rowData, filterParams) {
|
||||
if (!filterVal || !filterVal.length) return true;
|
||||
// rowVal is the raw dateStyle string on the flat table
|
||||
return filterVal.some(val => val === rowVal);
|
||||
},
|
||||
qgateHeaderFilterEditor(cell, onRendered, success, cancel, editorParams) {
|
||||
|
||||
const options = [
|
||||
{ label: '[+] ' + this.$p.t('abgabetool/c4positivBenotet'), value: 'positive' },
|
||||
{ label: '[-] ' + this.$p.t('abgabetool/c4negativBenotet'), value: 'negative' },
|
||||
{ label: '[~] ' + this.$p.t('abgabetool/c4notYetGraded'), value: 'not_graded' },
|
||||
{ label: '[?] ' + this.$p.t('abgabetool/c4notSubmitted'), value: 'not_submitted' },
|
||||
{ label: '[o] ' + this.$p.t('abgabetool/c4notHappenedYet'), value: 'not_happened' },
|
||||
{ label: '[--] ' + this.$p.t('abgabetool/c4keinTerminVorhanden'), value: 'no_termin' },
|
||||
];
|
||||
|
||||
const field = cell.getField();
|
||||
const stateKey = field === 'qgate1Status' ? 'qgate1FilterSelected' : 'qgate2FilterSelected';
|
||||
let selected = [...(this[stateKey] || [])]; // restore persistence state
|
||||
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.style.cssText = 'position: relative; width: 100%;';
|
||||
|
||||
const display = document.createElement('input');
|
||||
display.readOnly = true;
|
||||
display.placeholder = '';
|
||||
display.style.cssText = 'padding: 4px; width: 100%; box-sizing: border-box; cursor: default; border: 1px solid; outline: none; background: #fff; appearance: none; caret-color: transparent;';
|
||||
|
||||
const dropdown = document.createElement('div');
|
||||
dropdown.style.cssText = 'display: none; position: fixed; background: #fff; border: 1px solid; z-index: 9999; min-width: 180px; box-shadow: 0 2px 6px rgba(0,0,0,0.15);';
|
||||
|
||||
options.forEach(opt => {
|
||||
const row = document.createElement('label');
|
||||
row.style.cssText = 'display: flex; align-items: center; gap: 6px; padding: 4px 8px; cursor: pointer; white-space: nowrap;';
|
||||
row.addEventListener('mousedown', e => e.preventDefault());
|
||||
|
||||
const cb = document.createElement('input');
|
||||
cb.type = 'checkbox';
|
||||
cb.value = opt.value;
|
||||
cb.checked = selected.includes(opt.value); // sync with persistence
|
||||
cb.addEventListener('change', () => {
|
||||
if (cb.checked) {
|
||||
selected.push(opt.value);
|
||||
} else {
|
||||
selected = selected.filter(v => v !== opt.value);
|
||||
}
|
||||
this[stateKey] = [...selected]; // sync with persistence
|
||||
display.value = options.filter(o => selected.includes(o.value)).map(o => o.label).join(', ');
|
||||
success([...selected]);
|
||||
});
|
||||
|
||||
row.appendChild(cb);
|
||||
row.appendChild(document.createTextNode(opt.label));
|
||||
dropdown.appendChild(row);
|
||||
});
|
||||
|
||||
display.value = options.filter(o => selected.includes(o.value)).map(o => o.label).join(', ');
|
||||
|
||||
display.addEventListener('click', () => {
|
||||
if (dropdown.style.display === 'none') {
|
||||
const rect = display.getBoundingClientRect();
|
||||
dropdown.style.top = rect.bottom + 'px';
|
||||
dropdown.style.left = rect.left + 'px';
|
||||
dropdown.style.display = 'block';
|
||||
} else {
|
||||
dropdown.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
display.addEventListener('blur', () => {
|
||||
setTimeout(() => { dropdown.style.display = 'none'; }, 150);
|
||||
});
|
||||
|
||||
document.body.appendChild(dropdown);
|
||||
wrapper.appendChild(display);
|
||||
|
||||
cell.getElement().addEventListener('remove', () => dropdown.remove());
|
||||
|
||||
onRendered(() => display.focus());
|
||||
|
||||
return wrapper;
|
||||
},
|
||||
qgateHeaderFilterFunc(filterVal, rowVal, rowData, filterParams) {
|
||||
if (!filterVal || !filterVal.length) return true;
|
||||
|
||||
const matches = (val) => {
|
||||
switch (val) {
|
||||
case 'positive': return rowVal === this.$p.t('abgabetool/c4positivBenotet');
|
||||
case 'negative': return rowVal === this.$p.t('abgabetool/c4negativBenotet');
|
||||
case 'not_graded': return rowVal === this.$p.t('abgabetool/c4notYetGraded');
|
||||
case 'not_submitted':return rowVal === this.$p.t('abgabetool/c4notSubmitted');
|
||||
case 'not_happened': return rowVal === this.$p.t('abgabetool/c4notHappenedYet');
|
||||
case 'no_termin': return rowVal === this.$p.t('abgabetool/c4keinTerminVorhanden');
|
||||
default: return true;
|
||||
}
|
||||
};
|
||||
|
||||
// OR logic — row passes if it matches any selected filter
|
||||
return filterVal.some(val => matches(val));
|
||||
},
|
||||
shortLongTitleFormatter(cell, formatterParams, onRendered) {
|
||||
const longForm = cell.getValue()
|
||||
const shortForm = formatterParams?.shortForm
|
||||
|
||||
if(longForm && shortForm) {
|
||||
return `<span class="full-text" style="max-width: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; margin: 0px;">
|
||||
${longForm}
|
||||
</span>
|
||||
<span class="short-text" style="font-weight: bold; display: none;">
|
||||
${shortForm}
|
||||
</span>`
|
||||
} else {
|
||||
return `<span class="full-text" style="max-width: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; margin: 0px;">
|
||||
${longForm}
|
||||
</span>`
|
||||
}
|
||||
|
||||
},
|
||||
toolTipFuncPrevTermin(e, cell, onRendered) {
|
||||
const data = cell.getData();
|
||||
return this.mapDateStyleToTabulatorTooltip(data.prevTermin.dateStyle);
|
||||
},
|
||||
toolTipFuncNextTermin(e, cell, onRendered) {
|
||||
const data = cell.getData();
|
||||
return this.mapDateStyleToTabulatorTooltip(data.nextTermin.dateStyle);
|
||||
},
|
||||
mapDateStyleToTabulatorTooltip(dateStyleString) {
|
||||
switch(dateStyleString) {
|
||||
case 'bestanden':
|
||||
return this.$p.t('abgabetool/c4tooltipBestanden')
|
||||
break;
|
||||
case 'nichtbestanden':
|
||||
return this.$p.t('abgabetool/c4tooltipNichtBestanden')
|
||||
break;
|
||||
case 'beurteilungerforderlich':
|
||||
return this.$p.t('abgabetool/c4tooltipBeurteilungerforderlich')
|
||||
break;
|
||||
case 'verspaetet':
|
||||
return this.$p.t('abgabetool/c4tooltipVerspaetet')
|
||||
break;
|
||||
case 'abgegeben':
|
||||
return this.$p.t('abgabetool/c4tooltipAbgegeben')
|
||||
break;
|
||||
case 'verpasst':
|
||||
return this.$p.t('abgabetool/c4tooltipVerpasst')
|
||||
break;
|
||||
case 'abzugeben':
|
||||
return this.$p.t('abgabetool/c4tooltipAbzugeben')
|
||||
break;
|
||||
case 'standard':
|
||||
return this.$p.t('abgabetool/c4tooltipStandardv2')
|
||||
break;
|
||||
default: return ''
|
||||
}
|
||||
},
|
||||
handlePaUpdated(projektarbeit) {
|
||||
this.checkAbgabetermineProjektarbeit(projektarbeit)
|
||||
this.$refs.abgabeTable.tabulator.redraw(true)
|
||||
@@ -217,7 +532,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
})
|
||||
const uniqueRecipients = [...new Set(recipientList)];
|
||||
const subject = ""; // empty subject line
|
||||
splitMailsHelper(uniqueRecipients, param.originalEvent, subject, this.$fhcAlert, this.$p)
|
||||
splitMailsHelper(uniqueRecipients, param.originalEvent, subject, null, this.$fhcAlert, this.$p)
|
||||
},
|
||||
getQGateStatusList() {
|
||||
return [
|
||||
@@ -257,7 +572,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
if (val instanceof Date) {
|
||||
dt = luxon.DateTime.fromJSDate(val);
|
||||
} else if (typeof val === "string") {
|
||||
dt = luxon.DateTime.fromISO(val);
|
||||
dt = toViennaDate(val);
|
||||
} else { // fallback
|
||||
dt = luxon.DateTime.fromMillis(Number(val));
|
||||
}
|
||||
@@ -386,6 +701,9 @@ export const AbgabetoolMitarbeiter = {
|
||||
}
|
||||
this.stateRestored = true
|
||||
|
||||
// ensure that the filterCollapseables thingy has the correct values
|
||||
this.$refs.abgabeTable.setSelectedFields();
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
@@ -451,6 +769,32 @@ export const AbgabetoolMitarbeiter = {
|
||||
projekt.qgate2StatusRank = 1
|
||||
}
|
||||
})
|
||||
|
||||
// set shorthand statuscode once real status has been determined
|
||||
projekt.qgate1StatusShort = this.mapRankToShortStatus(projekt.qgate1StatusRank)
|
||||
projekt.qgate2StatusShort = this.mapRankToShortStatus(projekt.qgate2StatusRank)
|
||||
},
|
||||
mapRankToShortStatus(rank) {
|
||||
switch(rank){
|
||||
case 0: // kein termin vorhanden
|
||||
return '--'
|
||||
break;
|
||||
case 1: // noch nicht stattgefunden
|
||||
return 'o'
|
||||
break;
|
||||
case 2: // noch nicht abgegeben
|
||||
return '?'
|
||||
break;
|
||||
case 3: // noch nicht benotet
|
||||
return '~'
|
||||
break;
|
||||
case 4: // negativ benotet
|
||||
return '-'
|
||||
break;
|
||||
case 5: // positiv benotet
|
||||
return '+'
|
||||
break;
|
||||
}
|
||||
},
|
||||
checkAbgabetermineProjektarbeit(projekt) {
|
||||
const now = luxon.DateTime.now()
|
||||
@@ -460,7 +804,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
// while already looping through each termin, calculate datestyle beforehand
|
||||
termin.dateStyle = getDateStyleClass(termin, this.notenOptions)
|
||||
|
||||
const date = luxon.DateTime.fromISO(termin.datum).endOf('day')
|
||||
const date = toViennaDate(termin.datum).endOf('day')
|
||||
termin.luxonDate = date
|
||||
termin.diffMs = date.toMillis() - now.toMillis(); // positive = future, negative = past
|
||||
|
||||
@@ -517,11 +861,11 @@ export const AbgabetoolMitarbeiter = {
|
||||
const bezeichnung = val.bezeichnung?.bezeichnung ?? val.bezeichnung
|
||||
|
||||
return '<div style="display: flex; height: 100%">' +
|
||||
'<div class=' + val.dateStyle + "-header" + ' style="width:48px; height: 100%; padding: 0px; display: flex; align-items: center; justify-content: center;">' +
|
||||
icon +
|
||||
'<div class=' + val.dateStyle + "-header" + ' style="min-width:48px; height: 100%; padding: 0px; display: flex; align-items: center; justify-content: center;">' +
|
||||
icon +
|
||||
'</div>' +
|
||||
'<div style="margin-left: 4px;">' +
|
||||
'<p style="max-width: 100%; word-wrap: break-word; white-space: normal;">'+bezeichnung+' - '+ this.formatDate(val.datum)+'</p>' +
|
||||
'<p style="max-width: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;">'+bezeichnung+' - '+ this.formatDate(val.datum)+'</p>' +
|
||||
'</div>'+
|
||||
'</div>'
|
||||
|
||||
@@ -545,16 +889,19 @@ export const AbgabetoolMitarbeiter = {
|
||||
},
|
||||
selectAllHandler(e, cell) {
|
||||
const table = cell.getTable();
|
||||
const rows = table.getRows();
|
||||
const rows = this.filteredRows ?? table.getRows();
|
||||
|
||||
// custom select all logic
|
||||
const allowed = rows.filter(r => r.getData().selectable);
|
||||
// since betreuerpage acctually has logic behind selectable flag, it is important to go over allowed only here
|
||||
const selected = allowed.every(r => r.isSelected());
|
||||
|
||||
if(selected) {
|
||||
if(selected){
|
||||
allowed.forEach(r => r.deselect());
|
||||
e.target.checked = false;
|
||||
} else {
|
||||
allowed.forEach(r => r.select());
|
||||
e.target.checked = true;
|
||||
}
|
||||
|
||||
// stop built-in handler
|
||||
@@ -568,15 +915,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
return option.bezeichnung
|
||||
},
|
||||
formatDate(dateParam) {
|
||||
const date = new Date(dateParam)
|
||||
// handle missing leading 0
|
||||
const padZero = (num) => String(num).padStart(2, '0');
|
||||
|
||||
const month = padZero(date.getMonth() + 1); // Months are zero-based
|
||||
const day = padZero(date.getDate());
|
||||
const year = date.getFullYear();
|
||||
|
||||
return `${day}.${month}.${year}`;
|
||||
return formatISODate(dateParam);
|
||||
},
|
||||
undoSelection(cell) {
|
||||
// checks if cells row is selected and unselects -> imitates columns which dont trigger row selection
|
||||
@@ -589,6 +928,8 @@ export const AbgabetoolMitarbeiter = {
|
||||
},
|
||||
selectionCheck(row) {
|
||||
const data = row.getData()
|
||||
|
||||
// zweitbetreuer cant select projektarbeiten for serientermine
|
||||
if(data?.betreuerart_kurzbz == 'Zweitbegutachter') return false
|
||||
return true
|
||||
},
|
||||
@@ -612,7 +953,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
addSeries() {
|
||||
this.saving = true
|
||||
this.$api.call(ApiAbgabe.postSerientermin(
|
||||
this.serienTermin.datum.toISOString(),
|
||||
this.serienTermin.datum,
|
||||
this.serienTermin.bezeichnung.paabgabetyp_kurzbz,
|
||||
this.serienTermin.bezeichnung.bezeichnung,
|
||||
this.serienTermin.kurzbz,
|
||||
@@ -710,7 +1051,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
termin.allowedToSave = paIsBenotet ? false : true
|
||||
|
||||
// lektoren are not allowed to delete deadlines with existing submissions
|
||||
termin.allowedToDelete = termin.allowedToSave && !termin.abgabedatum
|
||||
termin.allowedToDelete = termin.allowedToSave && !termin.abgabedatum && !termin.note
|
||||
|
||||
termin.bezeichnung = this.abgabeTypeOptions.find(opt => opt.paabgabetyp_kurzbz === termin.paabgabetyp_kurzbz)
|
||||
|
||||
@@ -727,28 +1068,37 @@ export const AbgabetoolMitarbeiter = {
|
||||
|
||||
},
|
||||
centeredTextFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
if(!val) return
|
||||
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<p style="max-width: 100%; width: 100%; overflow-wrap: break-word; word-break: break-word; white-space: normal; margin: 0px; text-align: center">'+val+'</p></div>'
|
||||
const longForm = cell.getValue()
|
||||
if(!longForm) return
|
||||
const data = cell.getData()
|
||||
const entry = Object.entries(data).find(entry => entry[1] == longForm)
|
||||
|
||||
// shortFormKey must have same keyname as longForm but with 'Short' appended
|
||||
const shortForm = data[entry[0]+'Short']
|
||||
|
||||
if(shortForm && longForm) {
|
||||
return `<div style="display: flex; justify-content: start; align-items: center; height: 100%; width: 100%;">
|
||||
<span class="full-text" style="max-width: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; margin: 0px;">
|
||||
${longForm}
|
||||
</span>
|
||||
<span class="short-text" style="font-weight: bold; display: none;">
|
||||
${shortForm}
|
||||
</span>
|
||||
</div>`;
|
||||
} else {
|
||||
return '<div style="display: flex; justify-content: start; align-items: center; height: 100%">' +
|
||||
'<p style="max-width: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; margin: 0px;">'+longForm+'</p></div>'
|
||||
}
|
||||
},
|
||||
detailFormatter(cell) {
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
return '<div style="display: flex; justify-content: start; align-items: center; height: 100%">' +
|
||||
'<a><i class="fa fa-folder-open" style="color:#00649C"></i></a></div>'
|
||||
},
|
||||
beurteilungFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
if(val) {
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<a><i class="fa fa-file-pdf" style="color:#00649C"></i></a></div>'
|
||||
} else return '-'
|
||||
},
|
||||
pkzTextFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%">' +
|
||||
'<a style="max-width: 100%; word-wrap: break-word; white-space: normal;">'+val+'</a></div>'
|
||||
return '<div style="display: flex; justify-content: start; align-items: center; height: 100%">' +
|
||||
'<a style="max-width: 100%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap;">'+val+'</a></div>'
|
||||
},
|
||||
tableResolve(resolve) {
|
||||
this.tableBuiltResolve = resolve
|
||||
@@ -765,10 +1115,9 @@ export const AbgabetoolMitarbeiter = {
|
||||
setupData(data){
|
||||
|
||||
|
||||
this.projektarbeiten = data[0]
|
||||
this.domain = data[1]
|
||||
|
||||
this.tableData = data[0]?.retval?.map(projekt => {
|
||||
this.projektarbeiten = data[0]?.retval?.map(projekt => {
|
||||
this.checkAbgabetermineProjektarbeit(projekt)
|
||||
projekt.selectable = projekt.betreuerart_kurzbz !== 'Zweitbegutachter'
|
||||
|
||||
@@ -787,9 +1136,10 @@ export const AbgabetoolMitarbeiter = {
|
||||
titel: projekt.titel
|
||||
}
|
||||
})
|
||||
this.count = this.projektarbeiten.length
|
||||
|
||||
this.$refs.abgabeTable.tabulator.setColumns(this.abgabeTableOptions.columns)
|
||||
this.$refs.abgabeTable.tabulator.setData(this.tableData);
|
||||
this.$refs.abgabeTable.tabulator.setData(this.projektarbeiten);
|
||||
},
|
||||
loadProjektarbeiten(all = false, callback) {
|
||||
this.$api.call(ApiAbgabe.getMitarbeiterProjektarbeiten(all))
|
||||
@@ -841,6 +1191,17 @@ export const AbgabetoolMitarbeiter = {
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
countsToHTML() {
|
||||
return this.$p.t('global/ausgewaehlt')
|
||||
+ ': <strong>' + (this.selectedcount || 0) + '</strong>'
|
||||
+ ' | '
|
||||
+ this.$p.t('global/gefiltert')
|
||||
+ ': '
|
||||
+ '<strong>' + (this.filteredcount || 0) + '</strong>'
|
||||
+ ' | '
|
||||
+ this.$p.t('global/gesamt')
|
||||
+ ': <strong>' + (this.count || 0) + '</strong>';
|
||||
},
|
||||
emailItems() {
|
||||
const menu = []
|
||||
|
||||
@@ -869,6 +1230,8 @@ export const AbgabetoolMitarbeiter = {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
document.documentElement.classList.add('abgabetool');
|
||||
|
||||
this.phrasenPromise = this.$p.loadCategory(['abgabetool', 'global'])
|
||||
this.phrasenPromise.then(()=> {this.phrasenResolved = true})
|
||||
// fetch config to avoid hard coded links
|
||||
@@ -910,6 +1273,9 @@ export const AbgabetoolMitarbeiter = {
|
||||
mounted() {
|
||||
this.setupMounted()
|
||||
},
|
||||
beforeUnmount() {
|
||||
document.documentElement.classList.remove('abgabetool');
|
||||
},
|
||||
template: `
|
||||
<template v-if="phrasenResolved">
|
||||
<FhcOverlay :active="loading || saving"></FhcOverlay>
|
||||
@@ -935,6 +1301,7 @@ export const AbgabetoolMitarbeiter = {
|
||||
:enable-time-picker="false"
|
||||
locale="de"
|
||||
format="dd.MM.yyyy"
|
||||
model-type="yyyy-MM-dd"
|
||||
:text-input="true"
|
||||
auto-apply>
|
||||
</VueDatePicker>
|
||||
@@ -1001,12 +1368,13 @@ export const AbgabetoolMitarbeiter = {
|
||||
<!-- low max height on this vsplit wrapper to avoid padding scrolls, elements have their inherent height anyways -->
|
||||
<div id="abgabetable" style="max-height:40vw;">
|
||||
|
||||
<h2>{{$p.t('abgabetool/abgabetoolTitle')}}</h2>
|
||||
<h2>{{$p.t('abgabetool/abgabetoolTitleBetreuer')}}</h2>
|
||||
<hr>
|
||||
<core-filter-cmpt
|
||||
:title="''"
|
||||
@uuidDefined="handleUuidDefined"
|
||||
ref="abgabeTable"
|
||||
:description="countsToHTML"
|
||||
:newBtnShow="true"
|
||||
:newBtnLabel="$p.t('abgabetool/neueTerminserie')"
|
||||
:newBtnDisabled="!selectedData.length"
|
||||
|
||||
@@ -9,6 +9,7 @@ export const AbgabetoolStudent = {
|
||||
components: {
|
||||
Accordion: primevue.accordion,
|
||||
AccordionTab: primevue.accordiontab,
|
||||
Textarea: primevue.textarea,
|
||||
BsModal,
|
||||
AbgabeDetail,
|
||||
FhcOverlay
|
||||
@@ -17,7 +18,9 @@ export const AbgabetoolStudent = {
|
||||
return {
|
||||
notenOptions: Vue.computed(() => this.notenOptions),
|
||||
isViewMode: Vue.computed(() => this.isViewMode),
|
||||
moodle_link: Vue.computed(() => this.moodle_link)
|
||||
moodle_link: Vue.computed(() => this.moodle_link),
|
||||
title_edit_allowed: Vue.computed(() => this.title_edit_allowed),
|
||||
confetti_on_endupload: Vue.computed(() => this.confetti_on_endupload)
|
||||
}
|
||||
},
|
||||
props: {
|
||||
@@ -44,14 +47,69 @@ export const AbgabetoolStudent = {
|
||||
detail: null,
|
||||
projektarbeiten: null,
|
||||
selectedProjektarbeit: null,
|
||||
moodle_link: null
|
||||
moodle_link: null,
|
||||
title_edit_allowed: null,
|
||||
confetti_on_endupload: null,
|
||||
editingTitel: '',
|
||||
editingProjektarbeit: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openTitelEdit(projektarbeit, event) {
|
||||
// stop the click from toggling the accordion tab
|
||||
event.stopPropagation();
|
||||
this.editingProjektarbeit = projektarbeit;
|
||||
this.editingTitel = projektarbeit.titel ?? '';
|
||||
this.$refs.modalTitelEdit.show();
|
||||
},
|
||||
async saveTitel() {
|
||||
const trimmed = this.editingTitel.trim();
|
||||
if (!trimmed) {
|
||||
this.$fhcAlert.alertWarning(this.$capitalize(this.$p.t('global/warningEmptyField')));
|
||||
return;
|
||||
}
|
||||
|
||||
const confirmed = await this.$fhcAlert.confirm({
|
||||
message: this.$p.t('abgabetool/c4confirmTitelSpeichern'),
|
||||
acceptLabel: this.$capitalize(this.$p.t('ui/speichern')),
|
||||
acceptClass: 'p-button-primary',
|
||||
rejectLabel: this.$capitalize(this.$p.t('abgabetool/c4Cancel')),
|
||||
rejectClass: 'p-button-secondary'
|
||||
});
|
||||
|
||||
if (confirmed === false) return;
|
||||
|
||||
this.loading = true;
|
||||
this.$api.call(
|
||||
ApiAbgabe.postStudentProjektarbeitTitel(
|
||||
this.editingProjektarbeit.projektarbeit_id,
|
||||
trimmed
|
||||
)
|
||||
).then(res => {
|
||||
if (res.meta.status === 'success') {
|
||||
// update the local list entry in-place so the accordion header reflects it immediately
|
||||
this.editingProjektarbeit.titel = trimmed;
|
||||
// keep the open detail modal in sync if it happens to be showing this projektarbeit
|
||||
if (this.selectedProjektarbeit?.projektarbeit_id === this.editingProjektarbeit.projektarbeit_id) {
|
||||
this.selectedProjektarbeit.titel = trimmed;
|
||||
}
|
||||
this.$fhcAlert.alertSuccess(this.$capitalize(this.$p.t('abgabetool/c4titelSavedSuccess')));
|
||||
this.$refs.modalTitelEdit.hide();
|
||||
} else {
|
||||
this.$fhcAlert.alertError(this.$capitalize(this.$p.t('abgabetool/c4titelSaveError')));
|
||||
}
|
||||
}).finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handleTitelUpdated(projektarbeit_id, titel) {
|
||||
const pa = this.projektarbeiten?.find(p => p.projektarbeit_id === projektarbeit_id);
|
||||
if (pa) pa.titel = titel;
|
||||
},
|
||||
checkQualityGatesStrict(termine) {
|
||||
let qgate1Passed = false
|
||||
let qgate2Passed = false
|
||||
|
||||
|
||||
termine.forEach(t => {
|
||||
const noteOption = this.notenOptions?.find(opt => opt.note == t.note)
|
||||
if(noteOption && noteOption.positiv) {
|
||||
@@ -68,7 +126,7 @@ export const AbgabetoolStudent = {
|
||||
checkQualityGatesOptional(termine) {
|
||||
const qgate1found = termine.find(t => t.paabgabetyp_kurzbz == 'qualgate1')
|
||||
const qgate2found = termine.find(t => t.paabgabetyp_kurzbz == 'qualgate2')
|
||||
|
||||
|
||||
let qgate1positiv = true
|
||||
if(qgate1found) {
|
||||
qgate1positiv = false
|
||||
@@ -109,47 +167,35 @@ export const AbgabetoolStudent = {
|
||||
this.loadAbgaben(details).then((res)=> {
|
||||
const pa = this.projektarbeiten?.find(projekarbeit => projekarbeit.projektarbeit_id == details.projektarbeit_id)
|
||||
pa.abgabetermine = res.data[0].retval
|
||||
|
||||
|
||||
const paIsBenotet = pa.note !== null
|
||||
|
||||
|
||||
pa.abgabetermine.forEach(termin => {
|
||||
termin.file = []
|
||||
termin.allowedToUpload = false
|
||||
|
||||
|
||||
if(termin.paabgabetyp_kurzbz == 'end') {
|
||||
// old assumed production logic when qgates are required
|
||||
// termin.allowedToUpload = !this.isPastDate(termin.datum) && this.checkQualityGatesStrict(pa.abgabetermine)
|
||||
|
||||
const inTime = termin.fixtermin ? !this.isPastDate(termin.datum) : true
|
||||
termin.allowedToUpload = inTime && this.checkQualityGatesOptional(pa.abgabetermine)
|
||||
|
||||
|
||||
// development purposes
|
||||
// termin.allowedToUpload = this.checkQualityGatesStrict(pa.abgabetermine)
|
||||
// termin.allowedToUpload = true
|
||||
|
||||
} else if(termin.fixtermin) {
|
||||
termin.allowedToUpload = !this.isPastDate(termin.datum)
|
||||
} else {
|
||||
// this could confuse people since we should dont show people this flag
|
||||
termin.allowedToUpload = termin.upload_allowed
|
||||
termin.allowedToUpload = termin.upload_allowed
|
||||
}
|
||||
|
||||
// blocks client upload button if projektarbeitet is already beurteilt und thus further abgaben on any termin should be blocked
|
||||
if(paIsBenotet) termin.allowedToUpload = false
|
||||
|
||||
|
||||
|
||||
termin.bezeichnung = this.abgabeTypeOptions.find(opt => opt.paabgabetyp_kurzbz === termin.paabgabetyp_kurzbz)
|
||||
termin.dateStyle = getDateStyleClass(termin, this.notenOptions)
|
||||
})
|
||||
|
||||
|
||||
pa.betreuer = this.buildBetreuer(pa)
|
||||
pa.student_uid = this.student_uid
|
||||
|
||||
|
||||
this.selectedProjektarbeit = pa
|
||||
|
||||
this.$refs.modalContainerAbgabeDetail.show()
|
||||
|
||||
|
||||
}).finally(()=>{this.loading=false})
|
||||
},
|
||||
centeredTextFormatter(cell) {
|
||||
@@ -171,8 +217,8 @@ export const AbgabetoolStudent = {
|
||||
},
|
||||
mailFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%;">' +
|
||||
'<a href='+val+'><i class="fa fa-envelope" style="color:#00649C"></i></a></div>'
|
||||
return '<div style="display: flex; justify-content: center; align-items: center; height: 100%;">' +
|
||||
'<a href='+val+'><i class="fa fa-envelope" style="color:#00649C"></i></a></div>'
|
||||
},
|
||||
beurteilungFormatter(cell) {
|
||||
const val = cell.getValue()
|
||||
@@ -182,19 +228,17 @@ export const AbgabetoolStudent = {
|
||||
} else return '-'
|
||||
},
|
||||
buildMailToLink(projekt) {
|
||||
// should always be "projekt.mitarbeiter_uid +'@'+ this.domain", built in backend
|
||||
return 'mailto:' + projekt.email
|
||||
},
|
||||
buildBetreuer(abgabe) {
|
||||
return (abgabe.btitelpre ? abgabe.btitelpre + ' ' : '') + abgabe.bvorname + ' ' + abgabe.bnachname + (abgabe.btitelpost ? ' ' + abgabe.btitelpost : '')
|
||||
},
|
||||
async setupData(data){
|
||||
// this.projektarbeiten = data[0]
|
||||
const projektarbeiten = data[0] ?? null
|
||||
if(!projektarbeiten) return
|
||||
this.projektarbeiten = projektarbeiten.map(projekt => {
|
||||
let mode = 'detailTermine'
|
||||
|
||||
|
||||
return {
|
||||
...projekt,
|
||||
details: {
|
||||
@@ -228,16 +272,14 @@ export const AbgabetoolStudent = {
|
||||
.then(res => {
|
||||
resolve(res)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
async setupMounted() {
|
||||
this.loadProjektarbeiten()
|
||||
},
|
||||
getAccTabHeaderForProjektarbeit(projektarbeit) {
|
||||
let title = ''
|
||||
|
||||
title += projektarbeit.titel ?? this.$p.t('abgabetool/keinTitel')
|
||||
|
||||
return title
|
||||
},
|
||||
getMailLink(projektarbeit) {
|
||||
@@ -260,9 +302,7 @@ export const AbgabetoolStudent = {
|
||||
window.open(projektarbeit.beurteilung2)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
watch: {},
|
||||
computed: {
|
||||
isViewMode() {
|
||||
return this.student_uid !== this.viewData.uid
|
||||
@@ -272,11 +312,13 @@ export const AbgabetoolStudent = {
|
||||
}
|
||||
},
|
||||
async created() {
|
||||
// make sure zoom media query doesnt spill ever to other CIS4 sites
|
||||
document.documentElement.classList.add('abgabetool');
|
||||
|
||||
this.phrasenPromise = this.$p.loadCategory(['abgabetool', 'global'])
|
||||
this.phrasenPromise.then(()=> {this.phrasenResolved = true})
|
||||
|
||||
|
||||
this.loading = true
|
||||
//TODO: SWITCH TO NOTEN API ONCE NOTENTOOL IS IN MASTER TO AVOID DUPLICATE API
|
||||
await this.$api.call(ApiAbgabe.getNoten()).then(res => {
|
||||
if(res.meta.status == 'success') {
|
||||
this.notenOptions = res.data[0]
|
||||
@@ -289,16 +331,16 @@ export const AbgabetoolStudent = {
|
||||
this.loading = false
|
||||
})
|
||||
|
||||
// fetch abgabetypen options
|
||||
this.$api.call(ApiAbgabe.getPaAbgabetypen()).then(res => {
|
||||
this.abgabeTypeOptions = res.data
|
||||
}).catch(e => {
|
||||
this.loading = false
|
||||
})
|
||||
|
||||
// fetch config to avoid hard coded links
|
||||
this.$api.call(ApiAbgabe.getConfigStudent()).then(res => {
|
||||
this.moodle_link = res.data?.moodle_link
|
||||
this.title_edit_allowed = res.data?.title_edit_allowed
|
||||
this.confetti_on_endupload = res.data?.confetti_on_endupload
|
||||
}).catch(e => {
|
||||
this.loading = false
|
||||
})
|
||||
@@ -306,6 +348,9 @@ export const AbgabetoolStudent = {
|
||||
mounted() {
|
||||
this.setupMounted()
|
||||
},
|
||||
beforeUnmount() {
|
||||
document.documentElement.classList.remove('abgabetool');
|
||||
},
|
||||
template: `
|
||||
<template v-if="phrasenResolved">
|
||||
<FhcOverlay :active="loading"></FhcOverlay>
|
||||
@@ -318,14 +363,57 @@ export const AbgabetoolStudent = {
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:default>
|
||||
<AbgabeDetail :projektarbeit="selectedProjektarbeit"></AbgabeDetail>
|
||||
<AbgabeDetail
|
||||
:projektarbeit="selectedProjektarbeit"
|
||||
@titel-updated="handleTitelUpdated"
|
||||
></AbgabeDetail>
|
||||
</template>
|
||||
</bs-modal>
|
||||
<bs-modal
|
||||
ref="modalTitelEdit"
|
||||
class="bootstrap-prompt"
|
||||
dialogClass="bordered-modal"
|
||||
>
|
||||
<template v-slot:title>
|
||||
{{$capitalize( $p.t('abgabetool/c4titelBearbeiten') )}}
|
||||
</template>
|
||||
<template v-slot:default>
|
||||
<div class="mb-2">
|
||||
<label class="form-label fw-bold">
|
||||
{{$capitalize( $p.t('abgabetool/c4titel') )}}
|
||||
</label>
|
||||
<Textarea
|
||||
v-model="editingTitel"
|
||||
rows="10"
|
||||
maxlength="1024"
|
||||
class="form-control w-100"
|
||||
@keydown.enter.prevent="saveTitel"
|
||||
/>
|
||||
<div class="form-text text-end">{{ editingTitel.length }} / 1024</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-slot:footer>
|
||||
<button
|
||||
class="btn btn-secondary"
|
||||
@click="$refs.modalTitelEdit.hide()"
|
||||
>
|
||||
{{$capitalize( $p.t('abgabetool/c4Cancel') )}}
|
||||
</button>
|
||||
<button
|
||||
class="btn btn-primary"
|
||||
:disabled="!editingTitel.trim()"
|
||||
@click="saveTitel"
|
||||
>
|
||||
<i class="fa-solid fa-floppy-disk me-1"></i>
|
||||
{{$capitalize( $p.t('ui/speichern') )}}
|
||||
</button>
|
||||
</template>
|
||||
</bs-modal>
|
||||
|
||||
<h2>{{$capitalize( $p.t('abgabetool/abgabetoolTitle') )}}</h2>
|
||||
<hr>
|
||||
|
||||
<div v-if="projektarbeiten === null">
|
||||
<div v-if="projektarbeiten === null || projektarbeiten?.length == 0">
|
||||
{{$capitalize( $p.t('abgabetool/c4abgabeStudentNoProjectsFound') )}}
|
||||
</div>
|
||||
|
||||
@@ -335,8 +423,12 @@ export const AbgabetoolStudent = {
|
||||
|
||||
<template #header>
|
||||
<div class="d-flex row w-100">
|
||||
<div class="text-start" :class="projektarbeit.note != null ? 'col-6' : 'col-12'">
|
||||
<span>{{getAccTabHeaderForProjektarbeit(projektarbeit)}}</span>
|
||||
<div class="text-start" :class="projektarbeit.note != null ? 'col-6' : 'col-12'"
|
||||
style="min-width: 0;">
|
||||
<span
|
||||
:title="getAccTabHeaderForProjektarbeit(projektarbeit)"
|
||||
style="display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 600px;"
|
||||
>{{getAccTabHeaderForProjektarbeit(projektarbeit)}}</span>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<span>{{getNoteBezeichnung(projektarbeit)}}</span>
|
||||
@@ -402,10 +494,22 @@ export const AbgabetoolStudent = {
|
||||
{{ projektarbeit.projekttypbezeichnung }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row mt-2">
|
||||
<div class="col-4 col-md-3 fw-bold">{{$capitalize( $p.t('abgabetool/c4titel') )}}</div>
|
||||
<div class="col-8 col-md-9">
|
||||
{{ projektarbeit.titel }}
|
||||
<div class="col-8 col-md-9 d-flex align-items-center gap-2" style="min-width: 0;">
|
||||
<span
|
||||
:title="projektarbeit.titel"
|
||||
style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap;"
|
||||
>{{ projektarbeit.titel }}</span>
|
||||
<button
|
||||
v-if="title_edit_allowed && !isViewMode && projektarbeit.note == null"
|
||||
class="btn btn-sm btn-outline-secondary border-0 p-1"
|
||||
v-tooltip.right="{ value: $capitalize($p.t('abgabetool/c4titelBearbeiten')), class: 'custom-tooltip' }"
|
||||
@click="openTitelEdit(projektarbeit, $event)"
|
||||
>
|
||||
<i class="fa-solid fa-pen"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</AccordionTab>
|
||||
@@ -415,4 +519,4 @@ export const AbgabetoolStudent = {
|
||||
`,
|
||||
};
|
||||
|
||||
export default AbgabetoolStudent;
|
||||
export default AbgabetoolStudent;
|
||||
@@ -0,0 +1,26 @@
|
||||
const zone = 'Europe/Vienna';
|
||||
|
||||
export function getViennaTodayISO() {
|
||||
return luxon.DateTime.now().setZone(zone).toISODate();
|
||||
}
|
||||
|
||||
export function formatISODate(dateParam) {
|
||||
if (!dateParam) return '';
|
||||
|
||||
const date = luxon.DateTime.fromISO(String(dateParam), { zone });
|
||||
return date.isValid ? date.toFormat('dd.MM.yyyy') : '';
|
||||
}
|
||||
|
||||
export function toViennaDate(dateParam) {
|
||||
if (!dateParam) return null;
|
||||
|
||||
return luxon.DateTime.fromISO(String(dateParam), { zone });
|
||||
}
|
||||
|
||||
export function compareISODateValues(a, b) {
|
||||
if (!a && !b) return 0;
|
||||
if (!a) return 1;
|
||||
if (!b) return -1;
|
||||
|
||||
return String(a).localeCompare(String(b));
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
const zone = 'Europe/Vienna';
|
||||
const today = luxon.DateTime.now().setZone(zone);
|
||||
|
||||
export function getDateStyleClass(termin, notenOptions) {
|
||||
const today = luxon.DateTime.now().setZone(zone);
|
||||
const datum = luxon.DateTime.fromISO(termin.datum, { zone }).endOf('day');
|
||||
const abgabedatum = termin.abgabedatum ? luxon.DateTime.fromISO(termin.abgabedatum, { zone }) : null;
|
||||
termin.diffindays = datum.diff(today, 'days').days;
|
||||
@@ -28,10 +28,11 @@ export function getDateStyleClass(termin, notenOptions) {
|
||||
|
||||
// no submission yet
|
||||
if (datum < today) return 'verpasst';
|
||||
if (termin.diffindays <= 12) return 'abzugeben';
|
||||
return 'standard';
|
||||
|
||||
}
|
||||
|
||||
// GENERIC STATUS
|
||||
return datum < today ? 'verpasst' : 'standard';
|
||||
}
|
||||
// GENERIC STATUS — applies to all termine
|
||||
if (datum < today) return 'verpasst';
|
||||
if (termin.diffindays <= 12) return 'abzugeben';
|
||||
return 'standard';
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ export default {
|
||||
const vm = this;
|
||||
tinymce.init({
|
||||
target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component
|
||||
min_height: 300,
|
||||
//height: 800,
|
||||
//plugins: ['lists'],
|
||||
toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify | link',
|
||||
plugins: 'link',
|
||||
@@ -313,7 +313,7 @@ export default {
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-8">
|
||||
<form-form class="row g-3 mt-2 align-content-start" ref="formMessage">
|
||||
<form-form class="row g-3 mt-2 h-100" ref="formMessage">
|
||||
|
||||
<div class="row mb-3">
|
||||
|
||||
@@ -338,7 +338,7 @@ export default {
|
||||
</div>
|
||||
|
||||
<!--Tiny MCE-->
|
||||
<div class="row mb-3 tiny-90">
|
||||
<div class="row mb-3 h-100 tiny-90">
|
||||
<form-input
|
||||
ref="editor"
|
||||
:label="$p.t('global','nachricht') + ' *'"
|
||||
|
||||
@@ -62,7 +62,7 @@ export default {
|
||||
const vm = this;
|
||||
tinymce.init({
|
||||
target: this.$refs.editor.$refs.input, //Important: not selector: to enable multiple import of component
|
||||
min_height: 300,
|
||||
//height: 800,
|
||||
//plugins: ['lists'],
|
||||
toolbar: 'styleselect | bold italic underline | alignleft aligncenter alignright alignjustify | link',
|
||||
plugins: 'link',
|
||||
|
||||
@@ -30,7 +30,6 @@ export default {
|
||||
personId: null,
|
||||
layoutColumnsOnNewData: false,
|
||||
height: '400',
|
||||
arePhrasesLoaded: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -196,7 +195,7 @@ export default {
|
||||
],
|
||||
formatter: (cell, formatterParams) => {
|
||||
const key = formatterParams[cell.getValue()];
|
||||
return this.$p?.t?.('messages', key) || key;
|
||||
return this.$p.t('messages', key);
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -306,6 +305,8 @@ export default {
|
||||
{
|
||||
event: 'tableBuilt',
|
||||
handler: async() => {
|
||||
await this.$p.loadCategory(['global', 'person', 'stv', 'messages', 'ui', 'notiz']);
|
||||
|
||||
const setHeader = (field, text) => {
|
||||
const col = this.$refs.table.tabulator.getColumn(field);
|
||||
if (!col) return;
|
||||
@@ -356,12 +357,6 @@ export default {
|
||||
});*/
|
||||
},
|
||||
created(){
|
||||
this.$p
|
||||
.loadCategory(['global', 'person', 'stv', 'messages', 'ui', 'notiz'])
|
||||
.then(() => {
|
||||
this.arePhrasesLoaded = true;
|
||||
});
|
||||
|
||||
if(this.typeId != 'person_id' && Array.isArray(this.id) && this.id.length === 1) {
|
||||
const params = {
|
||||
id: this.id,
|
||||
@@ -386,7 +381,6 @@ export default {
|
||||
<!--table-->
|
||||
<div class="col-sm-6 pt-1">
|
||||
<core-filter-cmpt
|
||||
v-if="arePhrasesLoaded"
|
||||
ref="table"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="tabulatorEvents"
|
||||
@@ -419,7 +413,6 @@ export default {
|
||||
<div class="col-sm-12 pt-6">
|
||||
<core-filter-cmpt
|
||||
ref="table"
|
||||
v-if="arePhrasesLoaded"
|
||||
:tabulator-options="tabulatorOptions"
|
||||
:tabulator-events="tabulatorEvents"
|
||||
table-only
|
||||
|
||||
@@ -26,13 +26,13 @@ export default {
|
||||
internMail(event) {
|
||||
if (this.internMails.length)
|
||||
{
|
||||
splitMailsHelper(this.internMails, event, null, this.$fhcAlert, this.$p)
|
||||
splitMailsHelper(this.internMails, event, null, null, this.$fhcAlert, this.$p)
|
||||
}
|
||||
},
|
||||
privateMail(event) {
|
||||
if (this.privateMails.length)
|
||||
{
|
||||
splitMailsHelper(this.privateMails, event, null, this.$fhcAlert, this.$p)
|
||||
splitMailsHelper(this.privateMails, event, null,null, this.$fhcAlert, this.$p)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -83,8 +83,6 @@ export default {
|
||||
});
|
||||
},
|
||||
open() {
|
||||
|
||||
this.getBuchungstypen(this.currentSemester);
|
||||
this.data = {
|
||||
buchungstyp_kurzbz: '',
|
||||
betrag: '-0.00',
|
||||
@@ -107,7 +105,7 @@ export default {
|
||||
const text = typ.standardtext || '';
|
||||
const creditpoints = typ.credit_points || '';
|
||||
|
||||
if (!this.data.betrag || this.data.betrag == '-0.00' || this.data.betrag !== amount)
|
||||
if (!this.data.betrag || this.data.betrag == '-0.00')
|
||||
this.data.betrag = amount;
|
||||
|
||||
if (!this.data.buchungstext)
|
||||
@@ -115,18 +113,7 @@ export default {
|
||||
|
||||
if (this.config.showCreditpoints && (this.data.credit_points == '0.00' || this.data.credit_points === null))
|
||||
this.data.credit_points = creditpoints;
|
||||
},
|
||||
getBuchungstypen(studiensemester_kurzbz)
|
||||
{
|
||||
this.$api
|
||||
.call(ApiKonto.getBuchungstypen(studiensemester_kurzbz))
|
||||
.then(result => {
|
||||
this.lists.buchungstypen = result.data;
|
||||
if (this.data.buchungstyp_kurzbz)
|
||||
this.checkDefaultBetrag(this.data.buchungstyp_kurzbz);
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<core-form ref="form" class="stv-details-konto-edit" @submit.prevent="save">
|
||||
@@ -179,7 +166,6 @@ export default {
|
||||
<form-input
|
||||
type="select"
|
||||
v-model="data.studiensemester_kurzbz"
|
||||
@change="getBuchungstypen(data.studiensemester_kurzbz)"
|
||||
name="studiensemester_kurzbz"
|
||||
:label="$p.t('lehre/studiensemester')"
|
||||
>
|
||||
|
||||
@@ -5,6 +5,7 @@ import PvAutoComplete from "../../../../../../../index.ci.php/public/js/componen
|
||||
import ApiStvProjektarbeit from '../../../../../api/factory/stv/projektarbeit.js';
|
||||
|
||||
export default {
|
||||
name: 'ProjektarbeitDetails',
|
||||
components: {
|
||||
FormForm,
|
||||
FormInput,
|
||||
@@ -110,6 +111,10 @@ export default {
|
||||
this.formData.anmerkung = null;
|
||||
this.$refs.formDetails.clearValidation();
|
||||
},
|
||||
setFormData(projektarbeit) {
|
||||
this.formData = projektarbeit;
|
||||
if (this.formData.firma_id) this.formData.firma = {firma_id: this.formData.firma_id, name: this.formData.firma_name};
|
||||
},
|
||||
getFormData(newProjektarbeit, studiensemester_kurzbz, additional_lehrveranstaltung_id) {
|
||||
|
||||
this.additional_lehrveranstaltung_id = additional_lehrveranstaltung_id;
|
||||
@@ -148,8 +153,7 @@ export default {
|
||||
return this.$api
|
||||
.call(ApiStvProjektarbeit.loadProjektarbeit(projektarbeit_id))
|
||||
.then(result => {
|
||||
this.formData = result.data;
|
||||
if (this.formData.firma_id) this.formData.firma = {firma_id: this.formData.firma_id, name: this.formData.firma_name};
|
||||
this.setFormData(result.data)
|
||||
return result;
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError)
|
||||
|
||||
+40
-56
@@ -9,6 +9,7 @@ import ProjektarbeitDetails from "./Details.js";
|
||||
import Projektbetreuer from "./Projektbetreuer.js";
|
||||
|
||||
export default {
|
||||
name: 'Projektarbeit',
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
BsModal,
|
||||
@@ -213,17 +214,6 @@ export default {
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-users"></i>';
|
||||
button.title = this.$p.t('projektarbeit', 'betreuerBearbeiten');
|
||||
button.addEventListener('click', (event) => {
|
||||
let data = cell.getData();
|
||||
this.editedProjektarbeit = data;
|
||||
this.actionEditBetreuer();
|
||||
});
|
||||
container.append(button);
|
||||
|
||||
button = document.createElement('button');
|
||||
button.className = 'btn btn-outline-secondary btn-action';
|
||||
button.innerHTML = '<i class="fa fa-xmark"></i>';
|
||||
@@ -264,6 +254,7 @@ export default {
|
||||
actionEditProjektarbeit() {
|
||||
this.statusNew = false;
|
||||
this.toggleMenu('details');
|
||||
this.$refs.projektbetreuer.getProjektbetreuer(this.editedProjektarbeit?.projektarbeit_id, this.editedProjektarbeit?.studiensemester_kurzbz);
|
||||
this.$refs.projektarbeitModal.show();
|
||||
},
|
||||
actionEditBetreuer() {
|
||||
@@ -280,9 +271,18 @@ export default {
|
||||
.then(this.deleteProjektarbeit)
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
},
|
||||
saveProjektarbeit() {
|
||||
if(this.statusNew) this.addNewProjektarbeit()
|
||||
else this.updateProjektarbeit()
|
||||
},
|
||||
addNewProjektarbeit() {
|
||||
this.$refs.projektarbeitDetails.addNewProjektarbeit()
|
||||
.then((result) => {
|
||||
if(result?.data?.length) {
|
||||
this.editedProjektarbeit = result.data[0]
|
||||
this.$refs.projektarbeitDetails.setFormData(this.editedProjektarbeit)
|
||||
this.toggleMenu('betreuer');
|
||||
}
|
||||
this.projektarbeitSaved();
|
||||
})
|
||||
.catch(this.$fhcAlert.handleSystemError);
|
||||
@@ -308,7 +308,8 @@ export default {
|
||||
projektarbeitSaved() {
|
||||
this.reload();
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave'));
|
||||
this.hideModal('projektarbeitModal');
|
||||
if(!this.statusNew) this.hideModal('projektarbeitModal');
|
||||
else this.statusNew = false
|
||||
},
|
||||
setDefaultStunden(projekttyp_kurzbz) {
|
||||
this.$refs.projektbetreuer.setDefaultStunden(projekttyp_kurzbz);
|
||||
@@ -321,22 +322,22 @@ export default {
|
||||
},
|
||||
toggleMenu(tabId) {
|
||||
this.activeTab = tabId;
|
||||
if (this.statusNew == false) {
|
||||
switch(tabId) {
|
||||
case 'details':
|
||||
this.$refs.projektarbeitDetails.getFormData(
|
||||
this.statusNew, this.editedProjektarbeit?.studiensemester_kurzbz, this.editedProjektarbeit?.lehrveranstaltung_id
|
||||
);
|
||||
this.$refs.projektarbeitDetails.loadProjektarbeit(this.editedProjektarbeit?.projektarbeit_id);
|
||||
break;
|
||||
case 'betreuer':
|
||||
this.$refs.projektbetreuer.getFormData(
|
||||
this.editedProjektarbeit ? this.editedProjektarbeit.projekttyp_kurzbz : null
|
||||
);
|
||||
this.$refs.projektbetreuer.getProjektbetreuer(this.editedProjektarbeit?.projektarbeit_id, this.editedProjektarbeit?.studiensemester_kurzbz);
|
||||
break;
|
||||
}
|
||||
if (this.statusNew == false && tabId == 'details') {
|
||||
|
||||
this.$refs.projektarbeitDetails.getFormData(
|
||||
this.statusNew, this.editedProjektarbeit?.studiensemester_kurzbz, this.editedProjektarbeit?.lehrveranstaltung_id
|
||||
);
|
||||
this.$refs.projektarbeitDetails.loadProjektarbeit(this.editedProjektarbeit?.projektarbeit_id);
|
||||
} else if(tabId == 'betreuer') {
|
||||
this.$refs.projektbetreuer.getFormData(
|
||||
this.editedProjektarbeit ? this.editedProjektarbeit.projekttyp_kurzbz : null
|
||||
);
|
||||
this.$refs.projektbetreuer.getProjektbetreuer(this.editedProjektarbeit?.projektarbeit_id, this.editedProjektarbeit?.studiensemester_kurzbz);
|
||||
}
|
||||
},
|
||||
resetFormData() {
|
||||
this.$refs.projektarbeitDetails.resetForm()
|
||||
this.$refs.projektbetreuer.resetForm()
|
||||
}
|
||||
},
|
||||
template: `
|
||||
@@ -358,46 +359,29 @@ export default {
|
||||
</core-filter-cmpt>
|
||||
|
||||
<!--Modal: projektarbeitModal-->
|
||||
<bs-modal ref="projektarbeitModal" dialog-class="modal-xl modal-dialog-scrollable" header-class="flex-wrap pb-0">
|
||||
<bs-modal ref="projektarbeitModal" :dialog-class="(statusNew ? 'modal-xl ' : 'fhc-xxl-modal ' ) + 'modal-dialog-scrollable'"
|
||||
header-class="flex-wrap pb-0"
|
||||
@hideBsModal="resetFormData"
|
||||
>
|
||||
<template #title>
|
||||
<p v-if="statusNew" class="fw-bold mt-3">{{$p.t('projektarbeit', 'projektarbeitAnlegen')}}</p>
|
||||
<p v-else class="fw-bold mt-3">{{$p.t('projektarbeit', 'projektarbeitBearbeiten')}}</p>
|
||||
</template>
|
||||
|
||||
<template #modal-header-content v-if="!statusNew">
|
||||
<ul class="nav nav-tabs w-100 mt-3 msg_preview" id="pa_tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" :class="activeTab == 'details' ? 'active' : ''" id="details-tab" data-bs-toggle="tab" data-bs-target="#details" type="button" role="tab" aria-controls="details" aria-selected="true" @click="toggleMenu('details')">Details</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" :class="activeTab == 'betreuer' ? 'active' : ''" id="betreuer-tab" data-bs-toggle="tab" data-bs-target="#betreuer" type="button" role="tab" aria-controls="betreuer" aria-selected="false" @click="toggleMenu('betreuer')">{{$p.t('projektarbeit', 'betreuerGross')}}</button>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<div class="tab-content" id="pa_content">
|
||||
<div class="tab-pane fade show" :class="activeTab == 'details' ? 'active' : ''" id="details" role="tabpanel" aria-labelledby="details-tab">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<projektarbeit-details ref="projektarbeitDetails" :student="student" @projekttyp-changed="setDefaultStunden">
|
||||
</projektarbeit-details>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row" >
|
||||
<div :class="statusNew ? 'col-12' : 'col-6'">
|
||||
<projektarbeit-details ref="projektarbeitDetails" :student="student" @projekttyp-changed="setDefaultStunden">
|
||||
</projektarbeit-details>
|
||||
</div>
|
||||
|
||||
<div class="tab-pane fade show" :class="activeTab == 'betreuer' ? 'active' : ''" id="betreuer" role="tabpanel" aria-labelledby="betreuer-tab">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<projektbetreuer ref="projektbetreuer" :config="config" @betreuer-saved="reload"></projektbetreuer>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="statusNew ? '' : 'col-6'" :style="statusNew ? 'display: none' : ''">
|
||||
<projektbetreuer ref="projektbetreuer" :config="config" @betreuer-saved="reload"></projektbetreuer>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template #footer>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{$p.t('ui', 'abbrechen')}}</button>
|
||||
<button v-if="statusNew" class="btn btn-primary" @click="addNewProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
<button v-if="!statusNew && activeTab == 'details'" class="btn btn-primary" @click="updateProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
<button type="button" class="btn btn-secondary" @click="resetFormData" data-bs-dismiss="modal">{{$p.t('ui', 'abbrechen')}}</button>
|
||||
<button class="btn btn-primary" @click="saveProjektarbeit()"> {{$p.t('ui', 'speichern')}}</button>
|
||||
</template>
|
||||
|
||||
</bs-modal>
|
||||
|
||||
@@ -10,6 +10,7 @@ import Vertrag from "./Vertrag.js";
|
||||
import ApiStvProjektbetreuer from '../../../../../api/factory/stv/projektbetreuer.js';
|
||||
|
||||
export default {
|
||||
name: 'Projektbetreuer',
|
||||
components: {
|
||||
CoreFilterCmpt,
|
||||
BsModal,
|
||||
|
||||
@@ -41,8 +41,8 @@ export default {
|
||||
),
|
||||
ajaxResponse: (url, params, response) => response.data,
|
||||
columns: [
|
||||
{title: "Typ", field: "type", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title: "Betrag", field: "betrag", headerFilter: true,
|
||||
{title: "Typ", field: "type"},
|
||||
{title: "Betrag", field: "betrag",
|
||||
formatter: function(cell) {
|
||||
let value = cell.getValue();
|
||||
if (value == null) {
|
||||
@@ -51,14 +51,14 @@ export default {
|
||||
return parseFloat(value).toFixed(2);
|
||||
}
|
||||
},
|
||||
{title: "Bezeichnung", field: "bezeichnung", headerFilter: true},
|
||||
{title: "Studiensemester", field: "studiensemester_kurzbz", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title: "Pruefung_id", field: "pruefung_id", visible: false, headerFilter: true},
|
||||
{title: "mitarbeiter_uid", field: "mitarbeiter_uid", visible: false, headerFilter: true},
|
||||
{title: "projektarbeit_id", field: "projektarbeit_id", visible: false, headerFilter: true},
|
||||
{title: "lehreinheit_id", field: "lehreinheit_id", visible: true, headerFilter: true},
|
||||
{title: "betreuerart_kurzbz", field: "betreuerart_kurzbz", visible: false, headerFilter: true},
|
||||
{title: "vertrag_id", field: "vertrag_id", visible: false, headerFilter: true}, //just for testing
|
||||
{title: "Bezeichnung", field: "bezeichnung"},
|
||||
{title: "Studiensemester", field: "studiensemester_kurzbz"},
|
||||
{title: "Pruefung_id", field: "pruefung_id", visible: false},
|
||||
{title: "mitarbeiter_uid", field: "mitarbeiter_uid", visible: false},
|
||||
{title: "projektarbeit_id", field: "projektarbeit_id", visible: false},
|
||||
{title: "lehreinheit_id", field: "lehreinheit_id", visible: true},
|
||||
{title: "betreuerart_kurzbz", field: "betreuerart_kurzbz", visible: false},
|
||||
{title: "vertrag_id", field: "vertrag_id", visible: false}, //just for testing
|
||||
{
|
||||
title: 'Aktionen', field: 'actions',
|
||||
minWidth: 50,
|
||||
@@ -110,10 +110,10 @@ export default {
|
||||
],
|
||||
layout: 'fitColumns',
|
||||
layoutColumnsOnNewData: false,
|
||||
height: '250',
|
||||
height: '200',
|
||||
selectableRowsRangeMode: 'click',
|
||||
selectableRows: true,
|
||||
persistenceID: 'core-contracts-details-2026050501'
|
||||
persistenceID: 'core-contracts-details-2026021701'
|
||||
},
|
||||
tabulatorEvents: [
|
||||
{
|
||||
@@ -137,7 +137,7 @@ export default {
|
||||
|
||||
setHeader('type', this.$p.t('global', 'typ'));
|
||||
setHeader('bezeichnung', this.$p.t('ui', 'bezeichnung'));
|
||||
setHeader('lehreinheit_id', this.$p.t('lehre', 'lehreinheit_id'));
|
||||
setHeader('lehreinheit_id', this.$p.t('ui', 'lehreinheit_id'));
|
||||
setHeader('betrag', this.$p.t('ui', 'betrag'));
|
||||
setHeader('studiensemester_kurzbz', this.$p.t('lehre', 'studiensemester'));
|
||||
setHeader('mitarbeiter_uid', this.$p.t('ui', 'mitarbeiter_uid'));
|
||||
|
||||
@@ -47,13 +47,12 @@ export default {
|
||||
this.endpoint.getStatiOfContract(this.person_id, this.vertrag_id)
|
||||
),
|
||||
ajaxResponse: (url, params, response) => response.data,
|
||||
persistenceID: 'core-contracts-status-2026050501',
|
||||
persistenceID: 'core-contracts-status-2026021701',
|
||||
columns: [
|
||||
{title: "Status", field: "bezeichnung", headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title: "Status", field: "bezeichnung"},
|
||||
{
|
||||
title: "Datum",
|
||||
field: "datum",
|
||||
headerFilter: true,
|
||||
formatter: function (cell) {
|
||||
const dateStr = cell.getValue();
|
||||
const date = new Date(dateStr); // Convert to Date object
|
||||
@@ -67,15 +66,14 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
{title: "vertrag_id", field: "vertrag_id", visible: false, headerFilter: true},
|
||||
{title: "Vertragsstatus", field: "vertragsstatus_kurzbz", visible: false, headerFilter: true},
|
||||
{title: "User", field: "mitarbeiter_uid", visible: false, headerFilter: true},
|
||||
{title: "insertvon", field: "insertvon", visible: false, headerFilter: true},
|
||||
{title: "vertrag_id", field: "vertrag_id", visible: false},
|
||||
{title: "Vertragsstatus", field: "vertragsstatus_kurzbz", visible: false},
|
||||
{title: "User", field: "mitarbeiter_uid", visible: false},
|
||||
{title: "insertvon", field: "insertvon", visible: false},
|
||||
{
|
||||
title: "insertamum",
|
||||
field: "insertamum",
|
||||
visible: false,
|
||||
headerFilter: true,
|
||||
formatter: function (cell) {
|
||||
const dateStr = cell.getValue();
|
||||
const date = new Date(dateStr);
|
||||
@@ -89,12 +87,11 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
{title: "updatevon", field: "updatevon", visible: false, headerFilter: true},
|
||||
{title: "updatevon", field: "updatevon", visible: false},
|
||||
{
|
||||
title: "updateamum",
|
||||
field: "updateamum",
|
||||
visible: false,
|
||||
headerFilter: true,
|
||||
formatter: function (cell) {
|
||||
const dateStr = cell.getValue();
|
||||
const date = new Date(dateStr);
|
||||
@@ -151,7 +148,7 @@ export default {
|
||||
],
|
||||
layout: 'fitColumns',
|
||||
layoutColumnsOnNewData: false,
|
||||
height: '250',
|
||||
height: '200',
|
||||
selectableRowsRangeMode: 'click',
|
||||
selectableRows: true,
|
||||
},
|
||||
|
||||
@@ -30,11 +30,10 @@ export default {
|
||||
),
|
||||
ajaxResponse: (url, params, response) => response.data,
|
||||
columns: [
|
||||
{title: "Typ", field: "type", width: 100, headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title: "Typ", field: "type", width: 100},
|
||||
{
|
||||
title: "Betrag",
|
||||
field: "betrag1",
|
||||
headerFilter: true,
|
||||
formatter: function(cell) {
|
||||
let value = cell.getValue();
|
||||
if (value == null) {
|
||||
@@ -42,29 +41,28 @@ export default {
|
||||
}
|
||||
return parseFloat(value).toFixed(2);
|
||||
}},
|
||||
{title: "Bezeichnung", field: "bezeichnung", width: 150, headerFilter: true},
|
||||
{title: "Studiensemester", field: "studiensemester_kurzbz", width: 160, headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title: "mitarbeiter_uid", field: "mitarbeiter_uid", visible: false, headerFilter: true},
|
||||
{title: "projektarbeit_id", field: "projektarbeit_id", visible: false, headerFilter: true},
|
||||
{title: "lehreinheit_id", field: "lehreinheit_id", visible: true, headerFilter: true},
|
||||
{title: "betreuerart_kurzbz", field: "betreuerart_kurzbz", visible: false, headerFilter: true},
|
||||
{title: "Vertragsstunden", field: "vertragsstunden", visible: false, headerFilter: true},
|
||||
{title: "vertrag_id", field: "vertrag_id", visible: false, headerFilter: true}, //just for testing
|
||||
{title: "Bezeichnung", field: "bezeichnung", width: 150},
|
||||
{title: "Studiensemester", field: "studiensemester_kurzbz", width: 160},
|
||||
{title: "mitarbeiter_uid", field: "mitarbeiter_uid", visible: false},
|
||||
{title: "projektarbeit_id", field: "projektarbeit_id", visible: false},
|
||||
{title: "lehreinheit_id", field: "lehreinheit_id", visible: true},
|
||||
{title: "betreuerart_kurzbz", field: "betreuerart_kurzbz", visible: false},
|
||||
{title: "Vertragsstunden", field: "vertragsstunden", visible: false},
|
||||
{title: "vertrag_id", field: "vertrag_id", visible: false}, //just for testing
|
||||
{
|
||||
title: "VertragsstundenStudiensemester",
|
||||
field: "vertragsstunden_studiensemester_kurzbz",
|
||||
visible: false,
|
||||
headerFilter: true
|
||||
visible: false
|
||||
},
|
||||
],
|
||||
layout: 'fitColumns',
|
||||
layoutColumnsOnNewData: false,
|
||||
height: 250,
|
||||
height: 150,
|
||||
selectableRowsRangeMode: 'click',
|
||||
selectableRows: true,
|
||||
selectableRowsRollingSelection: false, //only allow multiselect with STRG
|
||||
index: "lehreinheit_id",
|
||||
persistenceID: 'core-contracts-unassigned-2026050501'
|
||||
persistenceID: 'core-contracts-unassigned-2026021701'
|
||||
},
|
||||
tabulatorEvents: [
|
||||
{
|
||||
@@ -102,7 +100,7 @@ export default {
|
||||
|
||||
setHeader('type', this.$p.t('global', 'typ'));
|
||||
setHeader('bezeichnung', this.$p.t('ui', 'bezeichnung'));
|
||||
setHeader('lehreinheit_id', this.$p.t('lehre', 'lehreinheit_id'));
|
||||
setHeader('lehreinheit_id', this.$p.t('ui', 'lehreinheit_id'));
|
||||
setHeader('betrag1', this.$p.t('ui', 'betrag'));
|
||||
setHeader('studiensemester_kurzbz', this.$p.t('lehre', 'studiensemester'));
|
||||
setHeader('mitarbeiter_uid', this.$p.t('ui', 'mitarbeiter_uid'));
|
||||
|
||||
@@ -20,6 +20,9 @@ export default {
|
||||
ContractStati
|
||||
},
|
||||
inject: {
|
||||
/* cisRoot: {
|
||||
from: 'cisRoot'
|
||||
},*/
|
||||
hasSchreibrechte: {
|
||||
from: 'hasSchreibrechte',
|
||||
default: false
|
||||
@@ -51,9 +54,9 @@ export default {
|
||||
),
|
||||
ajaxResponse: (url, params, response) => response.data,
|
||||
columns: [
|
||||
{title: "Bezeichnung", field: "bezeichnung", width: 300, headerFilter: true},
|
||||
{title: "Bezeichnung", field: "bezeichnung", width: 300},
|
||||
{
|
||||
title: "Betrag", field: "betrag", width: 100, headerFilter: true,
|
||||
title: "Betrag", field: "betrag", width: 100,
|
||||
formatter: function (cell) {
|
||||
let value = cell.getValue();
|
||||
|
||||
@@ -63,13 +66,12 @@ export default {
|
||||
return parseFloat(value).toFixed(2);
|
||||
}
|
||||
},
|
||||
{title: "Vertragstyp", field: "vertragstyp_bezeichnung", width: 125, headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title: "Status", field: "status", width: 100, headerFilter: "list", headerFilterParams: {valuesLookup:true, listOnEmpty:true, autocomplete:true, sort:"asc"}},
|
||||
{title: "Vertragstyp", field: "vertragstyp_bezeichnung", width: 125},
|
||||
{title: "Status", field: "status", width: 100},
|
||||
{
|
||||
title: "Vertragsdatum",
|
||||
field: "vertragsdatum",
|
||||
width: 128,
|
||||
headerFilter: true,
|
||||
formatter: function (cell) {
|
||||
const dateStr = cell.getValue();
|
||||
const date = new Date(dateStr);
|
||||
@@ -80,11 +82,11 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
{title: "VertragId", field: "vertrag_id", visible: false, headerFilter: true},
|
||||
{title: "Vertragsstunden", field: "vertragsstunden", visible: false, headerFilter: true},
|
||||
{title: "VertragsstundenStudiensemester", field: "vertragsstunden_studiensemester_kurzbz", visible: false, headerFilter: true},
|
||||
{title: "Anmerkung", field: "anmerkung", visible: false, headerFilter: true},
|
||||
{title: "isAbgerechnet", field: "isabgerechnet", visible: false, headerFilter: true},
|
||||
{title: "VertragId", field: "vertrag_id", visible: false},
|
||||
{title: "Vertragsstunden", field: "vertragsstunden", visible: false},
|
||||
{title: "VertragsstundenStudiensemester", field: "vertragsstunden_studiensemester_kurzbz", visible: false},
|
||||
{title: "Anmerkung", field: "anmerkung", visible: false},
|
||||
{title: "isAbgerechnet", field: "isabgerechnet", visible: false},
|
||||
{
|
||||
title: 'Aktionen', field: 'actions',
|
||||
minWidth: 150,
|
||||
@@ -138,13 +140,11 @@ export default {
|
||||
columns: true,
|
||||
filter: false //to avoids js errors
|
||||
},
|
||||
persistenceID: 'core-contracts-2026050501',
|
||||
persistenceID: 'core-contracts-2026021701',
|
||||
};
|
||||
return options;
|
||||
},
|
||||
tabulatorEvents() {
|
||||
const vm = this;
|
||||
|
||||
const events = [
|
||||
{
|
||||
event: 'tableBuilt',
|
||||
@@ -177,11 +177,28 @@ export default {
|
||||
setHeader('actions', this.$p.t('global', 'aktionen'));
|
||||
}
|
||||
},
|
||||
/* {
|
||||
//is just enabled for ADDON Injection KU: MultiprintHonorarvertrag
|
||||
//(maybe enable also for ADDON FH Burgenland: MultiAccept later)
|
||||
event: 'rowClick',
|
||||
handler: (e, row) => {
|
||||
if (this.dataPrintHonorar != null && this.dataPrintHonorar.multiselect != null) {
|
||||
const selectedContract = row.getData().vertrag_id;
|
||||
const status = row.getData().status;
|
||||
const bezeichnung = row.getData().bezeichnung;
|
||||
|
||||
this.toggleRowClick(selectedContract, status, bezeichnung);
|
||||
}
|
||||
}
|
||||
},*/
|
||||
{
|
||||
event: 'rowClick',
|
||||
handler: function (e, row) {
|
||||
handler: (e, row) => {
|
||||
if (!this.dataPrintHonorar?.multiselect) return;
|
||||
|
||||
const { vertrag_id, status, bezeichnung, vertragstyp_bezeichnung } = row.getData();
|
||||
vm.toggleRowClick(e, vertrag_id, status, bezeichnung, vertragstyp_bezeichnung);
|
||||
|
||||
this.toggleRowClick(e, vertrag_id, status, bezeichnung, vertragstyp_bezeichnung);
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -225,6 +242,8 @@ export default {
|
||||
person_id() {
|
||||
this.$refs.table.reloadTable();
|
||||
this.arraySelectedContracts = [];
|
||||
/* if(this.dataPrintHonorar?.multiselect)
|
||||
this.dataPrintHonorar.multiselect = [];*/
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
@@ -251,6 +270,7 @@ export default {
|
||||
)
|
||||
.then(result => {
|
||||
this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete'));
|
||||
//window.scrollTo(0, 0);
|
||||
this.reload();
|
||||
this.contractSelected.vertrag_id = null;
|
||||
})
|
||||
@@ -498,9 +518,19 @@ export default {
|
||||
'content/pdfExport.php?xml=' + this.dataPrintHonorar.xml + '&xsl=' + this.dataPrintHonorar.xsl + '&mitarbeiter_uid=' + this.mitarbeiter_uid + vertragString + '&output=pdf&uid=' + this.mitarbeiter_uid;
|
||||
window.open(linkToPdf, '_blank');
|
||||
},
|
||||
/* toggleRowClick(contractId, status, bezeichnung) {
|
||||
const index = this.arraySelectedContracts.findIndex(
|
||||
([id]) => id === contractId
|
||||
);
|
||||
if (index !== -1) {
|
||||
this.arraySelectedContracts.splice(index, 1);
|
||||
} else {
|
||||
this.arraySelectedContracts.push([contractId, status, bezeichnung]);
|
||||
}
|
||||
},*/
|
||||
toggleRowClick(event, vertrag_id, status, bezeichnung, vertragstyp_bezeichnung) {
|
||||
if (!this.dataPrintHonorar?.multiselect) return;
|
||||
|
||||
const isMulti = this.dataPrintHonorar?.multiselect === true;
|
||||
const isCtrl = event.ctrlKey || event.metaKey;
|
||||
|
||||
const entry = {
|
||||
@@ -510,29 +540,28 @@ export default {
|
||||
vertragstyp_bezeichnung
|
||||
};
|
||||
|
||||
// allow MultiSelect just in case event multiActionPrintHonorarvertrag
|
||||
const allowMultiClick = isMulti && isCtrl;
|
||||
|
||||
if (!allowMultiClick) {
|
||||
// Single click
|
||||
if (!isCtrl) {
|
||||
this.arraySelectedContracts = [entry];
|
||||
|
||||
//just mark last selected row as selected
|
||||
this.$refs.table.tabulator.deselectRow();
|
||||
this.$refs.table.tabulator.selectRow(vertrag_id);
|
||||
return;
|
||||
}
|
||||
|
||||
// CTRL / CMD → toggle
|
||||
const index = this.arraySelectedContracts.findIndex(
|
||||
e => e.vertrag_id === vertrag_id
|
||||
);
|
||||
|
||||
if (index === -1) {
|
||||
this.arraySelectedContracts.push(entry);
|
||||
//this.arraySelectedContracts.push([entry.vertrag_id, entry.status, entry.bezeichnung, entry.vertragstyp_bezeichnung]);
|
||||
} else {
|
||||
this.arraySelectedContracts.splice(index, 1);
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
/* clearSelection(){
|
||||
this.arraySelectedContracts = [];
|
||||
this.$refs.table.tabulator.deselectRow();
|
||||
}*/
|
||||
},
|
||||
created() {
|
||||
Promise.all([
|
||||
@@ -558,6 +587,88 @@ export default {
|
||||
});
|
||||
this.getFormattedDate();
|
||||
},
|
||||
/*
|
||||
TODO(Manu) delete after check
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="DatePicker"
|
||||
:label="$p.t('vertrag/datum_vertrag')"
|
||||
name="vertragsdatum"
|
||||
v-model="formData.vertragsdatum"
|
||||
auto-apply
|
||||
:enable-time-picker="false"
|
||||
format="dd.MM.yyyy"
|
||||
preview-format="dd.MM.yyyy"
|
||||
:teleport="true"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="text"
|
||||
:label="$p.t('ui/bezeichnung')"
|
||||
name="bezeichnung"
|
||||
v-model="formData.bezeichnung"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="select"
|
||||
:label="$p.t('global/typ')"
|
||||
v-model="formData.vertragstyp_kurzbz"
|
||||
name="vertragstyp_kurzbz"
|
||||
>
|
||||
<option :value="null">-- {{$p.t('fehlermonitoring', 'keineAuswahl')}} --</option>
|
||||
<option
|
||||
v-for="entry in listContractTypes"
|
||||
:key="entry.vertragstyp_kurzbz"
|
||||
:value="entry.vertragstyp_kurzbz"
|
||||
>
|
||||
{{entry.bezeichnung}}
|
||||
</option>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
:label="$p.t('ui/betrag')"
|
||||
name="betrag"
|
||||
v-model="formData.betrag"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3" v-if="!statusNew">
|
||||
<form-input
|
||||
type="text"
|
||||
:label="$p.t('ui/stunden') + ' (' + $p.t('vertrag/vertrag_urfassung')+ ')'"
|
||||
name="vertragsstunden"
|
||||
v-model="formData.vertragsstunden"
|
||||
disabled
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3" v-if="!statusNew">
|
||||
<form-input
|
||||
type="text"
|
||||
:label="$p.t('lehre/studiensemester') + ' (' + $p.t('vertrag/vertrag_urfassung')+ ')'"
|
||||
name="vertragsstunden_studiensemester_kurzbz"
|
||||
v-model="formData.vertragsstunden_studiensemester_kurzbz"
|
||||
disabled
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
<div class="row mb-3">
|
||||
<form-input
|
||||
type="textarea"
|
||||
:label="$p.t('global/anmerkung')"
|
||||
name="anmerkung"
|
||||
v-model="formData.anmerkung"
|
||||
>
|
||||
</form-input>
|
||||
</div>
|
||||
*/
|
||||
template: `
|
||||
<div class="core-contracts h-100 d-flex flex-column">
|
||||
|
||||
|
||||
@@ -220,6 +220,10 @@ export const CoreFilterCmpt = {
|
||||
else
|
||||
this.getFilter();
|
||||
},
|
||||
setSelectedFields() {
|
||||
const cols = this.tabulator.getColumns();
|
||||
this.selectedFields = cols.filter(col => col.isVisible()).map(col => col.getField());
|
||||
},
|
||||
async initTabulator() {
|
||||
let placeholder = '< Phrasen Plugin not loaded! >';
|
||||
if (this.$p) {
|
||||
@@ -337,7 +341,7 @@ export const CoreFilterCmpt = {
|
||||
this.tabulator.on('tableBuilt', () => {
|
||||
const cols = this.tabulator.getColumns();
|
||||
this.fields = cols.map(col => col.getField());
|
||||
this.selectedFields = cols.filter(col => col.isVisible()).map(col => col.getField());
|
||||
this.setSelectedFields();
|
||||
if (this.tabulator.options.persistence.headerFilter)
|
||||
this._setHeaderFilter();
|
||||
});
|
||||
@@ -371,6 +375,7 @@ export const CoreFilterCmpt = {
|
||||
});
|
||||
this.tabulator.clearFilter();
|
||||
this.filterActive = false;
|
||||
this.$emit('headerFilterOn', this.filterActive)
|
||||
},
|
||||
_setHeaderFilter()
|
||||
{
|
||||
|
||||
@@ -1,45 +1,67 @@
|
||||
export async function splitMailsHelper(mails, event, subject, alertPluginRef, phrasenPluginRef) {
|
||||
export async function splitMailsHelper(mails, event, subject, body, alertPluginRef, phrasenPluginRef) {
|
||||
await phrasenPluginRef.loadCategory('ui');
|
||||
debugger
|
||||
let splititem = ",";
|
||||
let maillist = mails.join(splititem);
|
||||
let mailto = "";
|
||||
// take subject line length + '?subject=' length into account
|
||||
const subjectlength = subject && typeof subject === 'string' ? subject.length + 9 : 0
|
||||
if (maillist.length > 2024)
|
||||
{
|
||||
if (await alertPluginRef.confirm({message: phrasenPluginRef.t('stv', 'zuvieleEMails') }) === false)
|
||||
return;
|
||||
let useBcc = event?.ctrlKey || event?.metaKey;
|
||||
|
||||
// build query parameters using URLSearchParams to get encoding
|
||||
const urlParams = new URLSearchParams();
|
||||
if (subject && typeof subject === 'string') {
|
||||
urlParams.append('subject', subject);
|
||||
}
|
||||
if (body && typeof body === 'string') {
|
||||
urlParams.append('body', body);
|
||||
}
|
||||
|
||||
// initial overhead: "mailto:?bcc=" -> 12 chars, "mailto:" -> 7 chars
|
||||
const baseOverhead = useBcc ? 12 : 7;
|
||||
let queryString = urlParams.toString().replace(/\+/g, '%20');;
|
||||
let overhead = baseOverhead + (queryString ? 1 + queryString.length : 0); // +1 accounts for '?' or '&'
|
||||
|
||||
// calculate overhead with body to exceed the limit
|
||||
if (overhead > 2024) {
|
||||
await alertPluginRef.alertWarning(phrasenPluginRef.t('ui', 'bodyZuLang'));
|
||||
urlParams.delete('body').replace(/\+/g, '%20');;
|
||||
queryString = urlParams.toString();
|
||||
overhead = baseOverhead + (queryString ? 1 + queryString.length : 0);
|
||||
}
|
||||
|
||||
let firstrun = true;
|
||||
let useBcc = event?.ctrlKey || event?.metaKey;
|
||||
while (maillist.length > 0)
|
||||
{
|
||||
if (maillist.length + subjectlength > 2024)
|
||||
{
|
||||
let splitposition = maillist.lastIndexOf(splititem, 1900);
|
||||
while (maillist.length > 0) {
|
||||
let mailto = "";
|
||||
if (maillist.length + overhead > 2024) {
|
||||
let splitposition = maillist.lastIndexOf(splititem, 2024 - overhead);
|
||||
|
||||
// Fallback guard: if a single email address is somehow longer than the remaining space
|
||||
if (splitposition === -1) {
|
||||
splitposition = maillist.indexOf(splititem);
|
||||
if (splitposition === -1) splitposition = maillist.length;
|
||||
}
|
||||
|
||||
mailto = maillist.substring(0, splitposition);
|
||||
maillist = maillist.substring(splitposition + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
mailto = maillist;
|
||||
maillist = "";
|
||||
}
|
||||
|
||||
// construct the clean mailLink
|
||||
let mailLink = useBcc ? `mailto:?bcc=${mailto}` : `mailto:${mailto}`;
|
||||
if(subject && typeof subject === 'string') mailLink += `?subject=${subject}`
|
||||
if (firstrun)
|
||||
{
|
||||
window.location.href = mailLink;
|
||||
firstrun = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (await alertPluginRef.confirm({message: phrasenPluginRef.t('stv', 'weitereEMail')}) === true)
|
||||
{
|
||||
window.location.href = mailLink;
|
||||
}
|
||||
if (queryString) {
|
||||
// If using BCC, the string already has a '?', so append with '&'. Otherwise, start with '?'
|
||||
mailLink += useBcc ? `&${queryString}` : `?${queryString}`;
|
||||
}
|
||||
|
||||
if (firstrun) {
|
||||
window.location.href = mailLink;
|
||||
firstrun = false;
|
||||
} else {
|
||||
if (await alertPluginRef.confirm({message: phrasenPluginRef.t('ui', 'weitereEMail')}) === true) {
|
||||
window.location.href = mailLink;
|
||||
} else {
|
||||
break; // Stop processing further batches if the user cancels
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -705,72 +705,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
}
|
||||
echo ' </anrechnungen>';
|
||||
|
||||
//Berufliche Kompetenzen
|
||||
$studienplan = new studienplan();
|
||||
$studienplan->loadStudienplan($studienplan_id);
|
||||
$regelstudiendauer = $studienplan->regelstudiendauer;
|
||||
$studienplan_ects = $studienplan->ects_stpl;
|
||||
$ects_berufliche_kompetenzen = 0;
|
||||
|
||||
//bei masterlehrgängen und $studienplan_ects >= 120 ECTS: Andruck der beruflichen Kompetenzen, wenn die Lv angerechnet wurde
|
||||
//TODO(Manu) check if rule still valid
|
||||
if ($row->typ == 'l' && $regelstudiendauer >= 4)
|
||||
{
|
||||
$ects_berufliche_kompetenzen = 0;
|
||||
echo '<berufliche_kompetenzen>';
|
||||
echo '<header_berufliche_kompetenz>Validierung von beruflich erworbenen Kompetenzen</header_berufliche_kompetenz>';
|
||||
|
||||
$qry_sem_0="
|
||||
SELECT
|
||||
lehrveranstaltung_id,
|
||||
lehrform_kurzbz,
|
||||
sws,
|
||||
lehre.tbl_lehrveranstaltung.bezeichnung,
|
||||
bezeichnung_english,
|
||||
ects,
|
||||
benotungsdatum,
|
||||
note,
|
||||
positiv,
|
||||
offiziell,
|
||||
note.anmerkung
|
||||
FROM
|
||||
lehre.tbl_zeugnisnote zeugnis
|
||||
JOIN lehre.tbl_note note USING(note)
|
||||
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
|
||||
JOIN public.tbl_student student USING(student_uid)
|
||||
WHERE
|
||||
student_uid =".$db->db_add_param($uid_arr[$i])."
|
||||
AND
|
||||
lehre.tbl_lehrveranstaltung.semester = '0'
|
||||
";
|
||||
|
||||
if($result_sem_0 = $db->db_query($qry_sem_0))
|
||||
{
|
||||
while ($row_sem_0 = $db->db_fetch_object($result_sem_0))
|
||||
{
|
||||
$benotungsdatum = $datum->formatDatum($row_sem_0->benotungsdatum, 'd/m/Y');
|
||||
$note = $db->db_parse_bool($row_sem_0->offiziell) ? $row_sem_0->anmerkung : $row_sem_0->note;
|
||||
$ects_berufliche_kompetenzen += $row_sem_0->ects;
|
||||
|
||||
echo '<lv_sem0>
|
||||
<lv_id>' . $row_sem_0->lehrveranstaltung_id . '</lv_id>
|
||||
<lehrform_kurzbz>' . $row_sem_0->lehrform_kurzbz . '</lehrform_kurzbz>
|
||||
<bezeichnung><![CDATA[' . $row_sem_0->bezeichnung . ']]></bezeichnung>
|
||||
<bezeichnung_englisch><![CDATA[' . $row_sem_0->bezeichnung_english . ']]></bezeichnung_englisch>
|
||||
<sws_lv>'.$row_sem_0->sws.'</sws_lv>
|
||||
<ects>'.$row_sem_0->ects.'</ects>
|
||||
<note_positiv>'.$db->db_parse_bool($row_sem_0->positiv).'</note_positiv>
|
||||
<note>'.$note.'</note>
|
||||
<benotungsdatum>'.$benotungsdatum.'</benotungsdatum>
|
||||
</lv_sem0>';
|
||||
}
|
||||
}
|
||||
echo '<ects_berufliche_kompetenz>'.$ects_berufliche_kompetenzen.'</ects_berufliche_kompetenz>';
|
||||
echo '</berufliche_kompetenzen>';
|
||||
}
|
||||
|
||||
echo "<studiensemester>";
|
||||
|
||||
for($start = $semesterNumberStart; $start <= $semesterNumberEnd; $start++)
|
||||
{
|
||||
$semester_ects = 0;
|
||||
@@ -793,7 +728,6 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
AND zeugnis = true
|
||||
AND status.ausbildungssemester = ".$db->db_add_param($start)."
|
||||
AND status.status_kurzbz NOT IN('Unterbrecher', 'Interessent','Bewerber','Aufgenommener','Abgewiesener','Wartender')
|
||||
--AND lehre.tbl_lehrveranstaltung.semester != '0'
|
||||
ORDER BY datum ASC";
|
||||
|
||||
$semester_kurzbz = array();
|
||||
@@ -842,7 +776,6 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
WHERE
|
||||
student_uid = ".$db->db_add_param($uid_arr[$i])."
|
||||
AND zeugnis = true
|
||||
AND lehre.tbl_lehrveranstaltung.semester != '0'
|
||||
AND studiensemester_kurzbz in (".$sqlStudent->implode4SQL($aktuellesSemester).")";
|
||||
|
||||
if (defined('ZEUGNISNOTE_NICHT_ANZEIGEN'))
|
||||
@@ -1201,19 +1134,10 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo '<ects_gesamt>'.$semester_ects.'</ects_gesamt>';
|
||||
echo '<ects_gesamt_positiv>'.$semester_ects_positiv.'</ects_gesamt_positiv>';
|
||||
echo "</semesters>";
|
||||
}
|
||||
|
||||
//TODO(Manu) check if rule still valid
|
||||
if ($row->typ == 'l' && $regelstudiendauer >= 4)
|
||||
{
|
||||
$ects_total += $ects_berufliche_kompetenzen;
|
||||
$ects_total_positiv += $ects_berufliche_kompetenzen;
|
||||
}
|
||||
|
||||
echo "</studiensemester>";
|
||||
echo " <ects_total>$ects_total</ects_total>";
|
||||
echo " <ects_total_positiv>$ects_total_positiv</ects_total_positiv>";
|
||||
|
||||
@@ -94,7 +94,6 @@ require_once('dbupdate_3.4/71399_dashboard_update_widget_paths.php');
|
||||
require_once('dbupdate_3.4/71645_studvw_messagetab_ladezeit.php');
|
||||
require_once('dbupdate_3.4/71566_studienordnungsdokument_neuer_organisationseinheitstyp_programm.php');
|
||||
require_once('dbupdate_3.4/70376_lohnguide.php');
|
||||
require_once('dbupdate_3.4/75888_reihungstest_mehrfachdurchfuehrung.php');
|
||||
|
||||
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
|
||||
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
|
||||
|
||||
@@ -264,8 +264,8 @@ CREATE TABLE IF NOT EXISTS hr.tbl_vertragsbestandteil_lohnguide (
|
||||
stellenbezeichnung varchar(255),
|
||||
fachrichtung_kurzbz character varying(32) NOT NULL,
|
||||
modellstelle_kurzbz character varying(32) NOT NULL,
|
||||
kommentar_person text,
|
||||
kommentar_modellstelle text,
|
||||
kommentar_person varchar(255),
|
||||
kommentar_modellstelle varchar(255),
|
||||
CONSTRAINT tbl_vertragsbestandteil_lohnguide_pk PRIMARY KEY (vertragsbestandteil_id),
|
||||
CONSTRAINT tbl_vertragsbestandteil_fk FOREIGN KEY (vertragsbestandteil_id) REFERENCES hr.tbl_vertragsbestandteil (vertragsbestandteil_id) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
CONSTRAINT tbl_vertragsbestandteil_lohnguide_fachrichtung_fk FOREIGN KEY (fachrichtung_kurzbz) REFERENCES hr.tbl_lohnguide_fachrichtung (fachrichtung_kurzbz) MATCH FULL ON DELETE RESTRICT ON UPDATE CASCADE,
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
<?php
|
||||
if (! defined('DB_NAME')) exit('No direct script access allowed');
|
||||
|
||||
if ($result = $db->db_query("SELECT * FROM pg_class WHERE relname='idx_tbl_benutzerfunktion_uid'"))
|
||||
{
|
||||
if ($db->db_num_rows($result) == 0)
|
||||
{
|
||||
$qry = "CREATE INDEX idx_tbl_benutzerfunktion_uid ON public.tbl_benutzerfunktion USING btree (uid)";
|
||||
|
||||
if (! $db->db_query($qry))
|
||||
echo '<strong>idx_tbl_benutzerfunktion_uid: ' . $db->db_last_error() . '</strong><br>';
|
||||
else
|
||||
echo 'Index idx_tbl_benutzerfunktion_uid angelegt<br>';
|
||||
}
|
||||
}
|
||||
+367
-7
@@ -34342,7 +34342,7 @@ array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Sie können eine Entschuldigung für einen Zeitraum von bis zu {0} Tagen in die Vergangenheit und bis zum Ende des aktuellen Semesters hochladen. Die erlaubten Dateitypen für das Dokument sind .pdf, .png und .jpg.
|
||||
|
||||
Sobald Sie eine Entschuldigung hochladen wird die zugehörige Studiengangsassistenz informiert und Ihr Anliegen überprüft. Solange Ihre Entschuldigung noch keinen akzeptierten oder abgelehnten Status erhalten hat, steht es Ihnen frei diese inklusive Datei zu löschen. Sobald sie entweder akzeptiert oder abgelehnt wurde können Sie den Eintrag nichtmehr löschen.
|
||||
Sobald Sie eine Entschuldigung hochladen wird die zugehörige Studiengangsassistenz informiert und Ihr Anliegen überprüft. Solange Ihre Entschuldigung noch keinen akzeptierten oder abgelehnten Status erhalten hat, steht es Ihnen frei diese inklusive Datei zu löschen. Sobald sie entweder akzeptiert oder abgelehnt wurde können Sie den Eintrag nicht mehr löschen.
|
||||
|
||||
Bei einer akzeptierten Entschuldigung werden sämtliche digitalen Anwesenheiten in diesem Zeitraum als positiv gewertet. Eine abgelehnte Entschuldigung hat keine Auswirkungen auf ihre Anwesenheitsquote.',
|
||||
'description' => '',
|
||||
@@ -41761,12 +41761,12 @@ array(
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4fehlerAktualitaetProjektarbeit',
|
||||
'phrase' => 'c4fehlerAktualitaetProjektarbeitv2',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Projektarbeit ist nichtmehr aktuell",
|
||||
'text' => "Projektarbeit ist nicht mehr aktuell",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
@@ -43544,6 +43544,46 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'abgabetoolTitleBetreuer',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Bachelor-/Masterarbeiten Betreuungen",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "Supervision of Bachelor's/Master's theses",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'abgabetoolTitleAdmin',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Bachelor-/Masterarbeiten Administration",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "Administration of Bachelor's/Master's theses",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
@@ -43724,6 +43764,26 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4abgaben_n',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "{0} Abgaben",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "{0} Dates",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
@@ -43767,18 +43827,18 @@ array(
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4orgform',
|
||||
'phrase' => 'c4orgformv2',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Organisationseinheit",
|
||||
'text' => "Organisationsform",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "organization unit",
|
||||
'text' => "organization form",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
@@ -44144,6 +44204,26 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4edit',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Bearbeiten",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => "Edit",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
@@ -44564,6 +44644,46 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4notetermin',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Terminnote",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Date grade',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4noteprojektarbeit',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Projektarbeitnote",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Project work grade',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
@@ -44929,6 +45049,26 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4beurteilungsnotizBeiNegNote',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Wenn Sie eine negative Note erteilen, müssen Sie eine Beurteilungsnotiz ausfüllen!",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'If you give a failing grade, you must fill out an evaluation form!',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
@@ -45140,6 +45280,26 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4confirm_delete_n_termine',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => "Möchten Sie wirklich {0} Termine Löschen?",
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Do you really want to delete {0} dates?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
@@ -46921,6 +47081,206 @@ array(
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4projektansicht',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Projektarbeitansicht',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Projectwork mode',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4terminansicht',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Terminansicht',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Deadline mode',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4editTerminserie',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Mehrfachbearbeitung Termine',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Multiedit Deadlines',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4nSelected',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => '{0} Termine zur Bearbeitung ausgewählt.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => '{0} Deadlines selected for editing.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4confirm_edit_n_termine',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Möchten sie wirklich {0} Termine bearbeiten?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Do you really want to edit {0} Deadlines?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4titelBearbeiten',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Titel bearbeiten',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Edit title',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4confirmTitelSpeichern',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Möchten Sie den Titel wirklich bearbeiten?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Do you really want to edit the title?',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4PATitleChanged',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Titel einer Projektarbeit wurde geändert.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Title of a project work has been changed',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'abgabetool',
|
||||
'phrase' => 'c4studentEditNotAllowed',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Editieren des Titels ist für Studierende nicht erlaubt.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'Editing of thesis title is not allowed for students.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'bodyZuLang',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
array(
|
||||
'sprache' => 'German',
|
||||
'text' => 'Der Emailtext ist zu lange um kopiert zu werden.',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
),
|
||||
array(
|
||||
'sprache' => 'English',
|
||||
'text' => 'The Emailbody is too long to be copied',
|
||||
'description' => '',
|
||||
'insertvon' => 'system'
|
||||
)
|
||||
)
|
||||
),
|
||||
// ABGABETOOL PHRASEN END
|
||||
array(
|
||||
'app' => 'core',
|
||||
@@ -47590,7 +47950,7 @@ array(
|
||||
),
|
||||
array(
|
||||
'app' => 'core',
|
||||
'category' => 'stv',
|
||||
'category' => 'ui',
|
||||
'phrase' => 'weitereEMail',
|
||||
'insertvon' => 'system',
|
||||
'phrases' => array(
|
||||
|
||||
Reference in New Issue
Block a user