From cc302ed5a1d4749976961b881c9f8277fa6bfc0f Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Wed, 4 Feb 2026 17:32:17 +0100 Subject: [PATCH 1/6] lazyload signatur status for assistenz view to avoid worst case loading times due to 50 x 30mb signatur server payload --- .../controllers/api/frontend/v1/Abgabe.php | 44 ++++++++++++++----- .../models/education/Paabgabe_model.php | 6 +++ public/js/api/factory/abgabe.js | 8 ++++ .../Cis/Abgabetool/AbgabetoolAssistenz.js | 13 +++++- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/application/controllers/api/frontend/v1/Abgabe.php b/application/controllers/api/frontend/v1/Abgabe.php index 5a6331584..1ff4fd13d 100644 --- a/application/controllers/api/frontend/v1/Abgabe.php +++ b/application/controllers/api/frontend/v1/Abgabe.php @@ -45,8 +45,9 @@ class Abgabe extends FHCAPI_Controller 'getProjektarbeitenForStudiengang' =>array('basis/abgabe_assistenz:rw'), 'getStudiengaenge' => array('basis/abgabe_assistenz:rw'), 'getStudentProjektarbeitAbgabeFile' => array('basis/abgabe_student:rw', 'basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'), - 'postStudentProjektarbeitZusatzdaten' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw') - ]); + 'postStudentProjektarbeitZusatzdaten' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'), + 'getSignaturStatusForProjektarbeitAbgaben' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw') + ]); $this->load->library('PhrasesLib'); $this->load->library('SignatureLib'); @@ -151,7 +152,7 @@ class Abgabe extends FHCAPI_Controller $ret = $this->ProjektarbeitModel->getProjektarbeitAbgabetermine($projektarbeit_id); foreach ($ret->retval as $termin) { - $this->checkAbgabeSignatur($termin, $projektarbeit); + $this->checkAbgabeSignatur($termin, $projektarbeit->student_uid); } $this->terminateWithSuccess(array($ret, $projektarbeitIsCurrent)); @@ -398,7 +399,7 @@ class Abgabe extends FHCAPI_Controller $this->terminateWithError($this->p->t('abgabetool', 'c4projektabgabeNichtGefunden'), 'general'); } - $this->checkAbgabeSignatur($paabgabe, $projektarbeit); + $this->checkAbgabeSignatur($paabgabe, $projektarbeit->student_uid); $signaturstatus = $paabgabe->signatur; // update projektarbeit cols @@ -892,10 +893,10 @@ class Abgabe extends FHCAPI_Controller $projektarbeit->abgabetermine = array_values(array_filter($projektabgaben, $filterFunc)); - // check the signature status for enduploads - foreach($projektarbeit->abgabetermine as $abgabe) { - $this->checkAbgabeSignatur($abgabe, $projektarbeit); - } +// // check the signature status for enduploads +// foreach($projektarbeit->abgabetermine as $abgabe) { +// $this->checkAbgabeSignatur($abgabe, $projektarbeit); +// } } $this->terminateWithSuccess(array($projektarbeiten, DOMAIN)); @@ -1021,10 +1022,33 @@ class Abgabe extends FHCAPI_Controller $this->terminateWithSuccess($result); } + // used to lazy load signatur status for assistenzen, since they could run into very long fetch times + // since they fetch the projektarbeiten with paabgaben included and could have a lot of huge endupload files + // in their stg resulting in huge loading times -> use this api call on opening detail component instead + public function getSignaturStatusForProjektarbeitAbgaben() { + $paabgabe_ids = $this->input->post('paabgabe_ids'); + $student_uid = $this->input->post('student_uid'); + + if ($paabgabe_ids === NULL || $student_uid === NULL || trim((string)$student_uid) === '') { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + + $result = $this->PaabgabeModel->loadByIDs($paabgabe_ids); + $data = $this->getDataOrTerminateWithError($result); + + foreach($data as $paabgabetermin) { + $this->checkAbgabeSignatur($paabgabetermin, $student_uid); + } + + $this->terminateWithSuccess($data); + } + /** * helper function to check the signature status of uploaded files for zwischenabgabe & endupload */ - private function checkAbgabeSignatur($abgabe, $projektarbeit) { + private function checkAbgabeSignatur($abgabe, $student_uid) { $paabgabetypenToCheck = $this->config->item('SIGNATUR_CHECK_PAABGABETYPEN'); if(!in_array($abgabe->paabgabetyp_kurzbz, $paabgabetypenToCheck)) { @@ -1036,7 +1060,7 @@ class Abgabe extends FHCAPI_Controller return; } - $path = PAABGABE_PATH.$abgabe->paabgabe_id.'_'.$projektarbeit->student_uid.'.pdf'; + $path = PAABGABE_PATH.$abgabe->paabgabe_id.'_'.$student_uid.'.pdf'; $signaturVorhanden = null; // if frontend receives null -> indicates no file found at path if(file_exists($path)) { diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index aa61bbaae..a883043d3 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -108,4 +108,10 @@ class Paabgabe_model extends DB_Model return $this->execQuery($query, [$interval]); } + + public function loadByIDs($paabgabe_ids) { + $qry = "SELECT * FROM campus.tbl_paabgabe WHERE paabgabe_id IN ?"; + + return $this->execReadOnlyQuery($qry, [$paabgabe_ids]); + } } diff --git a/public/js/api/factory/abgabe.js b/public/js/api/factory/abgabe.js index f5659f3a0..c6f229973 100644 --- a/public/js/api/factory/abgabe.js +++ b/public/js/api/factory/abgabe.js @@ -132,5 +132,13 @@ export default { params: formData, config: {Headers: { "Content-Type": "multipart/form-data" }} }; + }, + getSignaturStatusForProjektarbeitAbgaben(paabgabe_ids, student_uid) { + return { + method: 'post', + url: '/api/frontend/v1/Abgabe/getSignaturStatusForProjektarbeitAbgaben', + params: {paabgabe_ids, student_uid}, + + }; } }; \ No newline at end of file diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js index 7345b14e0..4c4485fb4 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js @@ -684,7 +684,18 @@ export const AbgabetoolAssistenz = { const pa = this.projektarbeiten.find(projektarbeit => projektarbeit.projektarbeit_id == details.projektarbeit_id) - // pa.isCurrent = res.data[1] + if(pa?.abgabetermine?.length) { + this.$api.call(ApiAbgabe.getSignaturStatusForProjektarbeitAbgaben(pa.abgabetermine.map(termin => termin.paabgabe_id), pa.student_uid)) + .then(res => { + if(res.meta.status === 'success') { + res.data.forEach(paabgabe => { + const termin = pa.abgabetermine.find(abgabe => abgabe.paabgabe_id == paabgabe.paabgabe_id) + if(termin && paabgabe.signatur !== undefined) termin.signatur = paabgabe.signatur + }) + } + }) + } + const paIsBenotet = pa.note !== null pa.abgabetermine.forEach(termin => { From 1eda652fba9ce7cab8912f648319334e4072c4f7 Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Wed, 4 Feb 2026 17:34:21 +0100 Subject: [PATCH 2/6] remove old code --- application/controllers/api/frontend/v1/Abgabe.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/application/controllers/api/frontend/v1/Abgabe.php b/application/controllers/api/frontend/v1/Abgabe.php index 1ff4fd13d..39c7ebae6 100644 --- a/application/controllers/api/frontend/v1/Abgabe.php +++ b/application/controllers/api/frontend/v1/Abgabe.php @@ -892,11 +892,6 @@ class Abgabe extends FHCAPI_Controller }; $projektarbeit->abgabetermine = array_values(array_filter($projektabgaben, $filterFunc)); - -// // check the signature status for enduploads -// foreach($projektarbeit->abgabetermine as $abgabe) { -// $this->checkAbgabeSignatur($abgabe, $projektarbeit); -// } } $this->terminateWithSuccess(array($projektarbeiten, DOMAIN)); From 6da19585ff836b304e994b34e6e691986c505776 Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Mon, 9 Feb 2026 13:45:01 +0100 Subject: [PATCH 3/6] optional sammelmail buttons assistenz abgabetool --- application/config/abgabe.php | 3 + .../controllers/api/frontend/v1/Abgabe.php | 28 +++++++- .../models/education/Projektarbeit_model.php | 22 ++++++ .../Cis/Abgabetool/AbgabetoolAssistenz.js | 70 +++++++++++++++++-- system/phrasesupdate.php | 52 ++++++++++++-- 5 files changed, 162 insertions(+), 13 deletions(-) diff --git a/application/config/abgabe.php b/application/config/abgabe.php index f9b043a34..5cf3042ed 100644 --- a/application/config/abgabe.php +++ b/application/config/abgabe.php @@ -36,3 +36,6 @@ $config['SIGNATUR_CHECK_PAABGABETYPEN'] = ['end']; // to be used as "https://moodle.technikum-wien.at/course/view.php?idnumber=dl{$stg_kz}" for stg specific moodle routing $config['STG_MOODLE_LINK'] = 'https://moodle.technikum-wien.at/course/view.php?idnumber=dl'; + +$config['ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'] = true; +$config['ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'] = true; diff --git a/application/controllers/api/frontend/v1/Abgabe.php b/application/controllers/api/frontend/v1/Abgabe.php index 39c7ebae6..c8f48b9df 100644 --- a/application/controllers/api/frontend/v1/Abgabe.php +++ b/application/controllers/api/frontend/v1/Abgabe.php @@ -87,11 +87,15 @@ class Abgabe extends FHCAPI_Controller $old_abgabe_beurteilung_link =$this->config->item('old_abgabe_beurteilung_link'); $turnitin_link = $this->config->item('turnitin_link'); $abgabetypenBetreuer = $this->config->item('ALLOWED_ABGABETYPEN_BETREUER'); + $ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'); + $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'); $ret = array( 'old_abgabe_beurteilung_link' => $old_abgabe_beurteilung_link, 'turnitin_link' => $turnitin_link, - 'abgabetypenBetreuer' => $abgabetypenBetreuer + 'abgabetypenBetreuer' => $abgabetypenBetreuer, + 'ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT' => $ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT, + 'ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER' => $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER ); $this->terminateWithSuccess($ret); @@ -762,7 +766,7 @@ class Abgabe extends FHCAPI_Controller /** * helper function to fetch the correct email for a projektarbeits erstbetreuer */ - private function getProjektbetreuerEmail($projektarbeit_id) { + private function getProjektbetreuerEmailByProjektarbeitID($projektarbeit_id) { $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); $result = $this->ProjektarbeitModel->getProjektbetreuerEmail($projektarbeit_id); $email = $this->getDataOrTerminateWithError($result, 'general'); @@ -771,6 +775,18 @@ class Abgabe extends FHCAPI_Controller } + /** + * helper function to fetch the correct email for a projektarbeits zweitbetreuer by their person id + * can be used for erstbetreuer aswell if necessary + */ + private function getProjektbetreuerEmailByPersonID($person_id) { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + $result = $this->ProjektarbeitModel->getProjektbetreuerEmailByPersonID($person_id); + $email = $this->getDataOrTerminateWithError($result, 'general'); + + return $email[0]->uid ? $email[0]->uid.'@'.DOMAIN : $email[0]->private_email; + } + //TODO: SWITCH TO NOTEN API ONCE NOTENTOOL IS IN MASTER TO AVOID DUPLICATE API /** @@ -887,6 +903,12 @@ class Abgabe extends FHCAPI_Controller // map the abgaben into projektarbeiten foreach($projektarbeiten as $projektarbeit) { + $projektarbeit->betreuer_mail = $this->getProjektbetreuerEmailByProjektarbeitID($projektarbeit->projektarbeit_id); + + if($projektarbeit->zweitbetreuer_person_id !== null) { + $projektarbeit->zweitbetreuer_mail = $this->getProjektbetreuerEmailByPersonID($projektarbeit->zweitbetreuer_person_id); + } + $filterFunc = function($projektabgabe) use ($projektarbeit) { return $projektabgabe->projektarbeit_id == $projektarbeit->projektarbeit_id; }; @@ -1140,7 +1162,7 @@ class Abgabe extends FHCAPI_Controller $maildata['bewertunglink'] = $projektarbeitIsCurrent && $paabgabetyp_kurzbz == 'end' ? "

Zur Beurteilung der Arbeit

" : ""; $maildata['token'] = ""; - $email = $this->getProjektbetreuerEmail($projektarbeit_id); + $email = $this->getProjektbetreuerEmailByProjektarbeitID($projektarbeit_id); if(!$email) $this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailBegutachter'), 'general'); diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index d80878f6d..e2d4d1b70 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -244,6 +244,28 @@ class Projektarbeit_model extends DB_Model return $this->execReadOnlyQuery($qry, [$projektarbeit_id]); } + + public function getProjektbetreuerEmailByPersonID($person_id) { + $qry = "SELECT ( + SELECT kontakt + FROM public.tbl_kontakt + WHERE kontakttyp = 'email' + AND person_id = pers.person_id + ORDER BY + CASE WHEN zustellung THEN 0 ELSE 1 END, + insertamum DESC NULLS LAST + LIMIT 1 + ) AS private_email, mitarbeiter_uid as uid + FROM lehre.tbl_projektarbeit pa + JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) + JOIN public.tbl_person pers USING (person_id) + LEFT JOIN public.tbl_benutzer ben USING (person_id) + LEFT JOIN public.tbl_mitarbeiter ma ON ben.uid = ma.mitarbeiter_uid + WHERE (ben.aktiv OR ben.aktiv IS NULL) + AND person_id = ?"; + + return $this->execReadOnlyQuery($qry, [$person_id]); + } public function getProjektarbeitBenutzer($uid) { $qry="SELECT * FROM campus.vw_benutzer where uid=?"; diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js index 4c4485fb4..20333ba41 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js @@ -77,6 +77,8 @@ export const AbgabetoolAssistenz = { phrasenResolved: false, turnitin_link: null, old_abgabe_beurteilung_link: null, + ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT: null, + ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER: null, saving: false, loading: false, abgabeTypeOptions: null, @@ -221,6 +223,32 @@ export const AbgabetoolAssistenz = { ]}; }, methods: { + sammelMailStudent() { + const emails = this.selectedData + .map(row => `${row.student_uid}@${this.domain}`) + .join(','); + + const subject = this.$p.t('abgabetool/c4sammelmailStudentBetreff', [this.selectedStudiengangOption?.bezeichnung]); + + const href = `mailto:${emails}?subject=${subject}`; + + window.location.href = href + }, + sammelMailBetreuer() { + const recipientList = []; + this.selectedData.forEach(row => { + if (row.betreuer_mail) recipientList.push(row.betreuer_mail); + if (row.zweitbetreuer_mail) recipientList.push(row.zweitbetreuer_mail); + }); + + // actually not necessary for email clients but looks better for assistenz if we avoid duplicates here + const uniqueRecipients = [...new Set(recipientList)]; + + const subject = this.$p.t('abgabetool/c4sammelmailBetreuerBetreff', [this.selectedStudiengangOption?.bezeichnung]); + const href = `mailto:${uniqueRecipients.join(',')}?subject=${encodeURIComponent(subject)}`; + + window.location.href = href; + }, selectHandler(e, cell) { const row = cell.getRow(); @@ -620,9 +648,8 @@ export const AbgabetoolAssistenz = { const mappedData = this.mapProjekteToTableData(this.projektarbeiten) - this.$refs.abgabeTable.tabulator.setColumns(this.abgabeTableOptions.columns) this.$refs.abgabeTable.tabulator.setData(mappedData) - + this.$refs.abgabeTable.tabulator.redraw(true) }).finally(()=>{ this.saving = false }) @@ -867,8 +894,8 @@ export const AbgabetoolAssistenz = { tableResolve(resolve) { this.tableBuiltResolve = resolve }, - buildMailToLink(abgabe) { - return 'mailto:' + abgabe.student_uid +'@'+ this.domain + buildMailToLink(projekt) { + return 'mailto:' + projekt.student_uid +'@'+ this.domain }, buildPKZ(projekt) { return `${projekt.student_uid} / ${projekt.matrikelnr}` @@ -941,6 +968,29 @@ export const AbgabetoolAssistenz = { this.calcMaxTableHeight() } }, + computed: { + uniqueBetreuerEmailCount() { + const emails = new Set(); + + this.selectedData.forEach(row => { + if (row.betreuer_mail) emails.add(row.betreuer_mail); + if (row.zweitbetreuer_mail) emails.add(row.zweitbetreuer_mail); + }); + + return emails.size; + }, + uniqueStudentEmailCount() { + const emails = new Set(); + + this.selectedData.forEach(row => { + if (row.student_uid) { + emails.add(row.student_uid); // actually dont need domain for this + } + }); + + return emails.size; + } + }, watch: { 'serienTermin.bezeichnung'(newVal) { if(newVal?.paabgabetyp_kurzbz === 'qualgate1' || newVal?.paabgabetyp_kurzbz === 'qualgate2') { @@ -987,6 +1037,8 @@ export const AbgabetoolAssistenz = { const res = results[0].value; this.turnitin_link = res.data?.turnitin_link; this.old_abgabe_beurteilung_link = res.data?.old_abgabe_beurteilung_link; + this.ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT = res.data?.ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT; + this.ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER = res.data?.ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER; } // 2. Studiengänge @@ -1292,6 +1344,16 @@ export const AbgabetoolAssistenz = { :useSelectionSpan="false" > From 67838eb630cc10968c3e3bedb3695574af3dd2ad Mon Sep 17 00:00:00 2001 From: Johann Hoffmann Date: Wed, 11 Feb 2026 13:39:23 +0100 Subject: [PATCH 5/6] load projektarbeit.note correctly for mitarbeiter; evaluate projektarbeit termin editability correctly and define a notenarray which does NOT count (currently "Nicht beurteilt" & "Noch nicht eingetragen"). such rules apply for betreuer, assistenz is allowed to do whatever they want since we never defined an actual business process anywhere and people do whatever they want anyways --- application/config/abgabe.php | 4 +++- .../controllers/api/frontend/v1/Abgabe.php | 5 +++- .../models/education/Projektarbeit_model.php | 2 +- .../Cis/Abgabetool/AbgabeMitarbeiterDetail.js | 23 +++++++++++++++---- .../Cis/Abgabetool/AbgabetoolAssistenz.js | 6 +++++ .../Cis/Abgabetool/AbgabetoolMitarbeiter.js | 16 ++++++++++++- 6 files changed, 48 insertions(+), 8 deletions(-) diff --git a/application/config/abgabe.php b/application/config/abgabe.php index 5cf3042ed..f806e1ef8 100644 --- a/application/config/abgabe.php +++ b/application/config/abgabe.php @@ -26,7 +26,9 @@ $config['RELEVANT_PAABGABETYPEN_SAMMELMAIL_ASSISTENZ'] = ['end']; $config['RELEVANT_PAABGABETYPEN_SAMMELMAIL_STUDENT'] = ['qualgate1', 'qualgate2', 'zwischen', 'note', 'abstract', 'end', 'enda']; //$config['ALLOWED_NOTEN_ABGABETOOL'] = ['Bestanden', 'Nicht bestanden']; $config['ALLOWED_NOTEN_ABGABETOOL'] = [10, 14]; // tbl_note pk - +// benotete projektarbeiten sperren weitere terminanlage & bearbeitung, diese noten sind ausnahmen dieser Regel +// wie zB "Nicht beurteilt" & "Noch nicht eingetragen" +$config['NONFINAL_NOTEN_ABGABETOOL'] = [7, 9]; $config['beurteilung_link_fallback'] = 'addons/fhtw/content/projektbeurteilung/projektbeurteilungDocumentExport.php?projektarbeit_id=?&betreuerart_kurzbz=?&person_id=?'; $config['PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ERSTBEGUTACHTER'] = 'index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter'; diff --git a/application/controllers/api/frontend/v1/Abgabe.php b/application/controllers/api/frontend/v1/Abgabe.php index c8f48b9df..b37c64713 100644 --- a/application/controllers/api/frontend/v1/Abgabe.php +++ b/application/controllers/api/frontend/v1/Abgabe.php @@ -801,7 +801,10 @@ class Abgabe extends FHCAPI_Controller $allowed_noten_abgabetool = $this->config->item('ALLOWED_NOTEN_ABGABETOOL'); - $this->terminateWithSuccess(array($noten, $allowed_noten_abgabetool)); + $nonfinal_noten_abgabetool = $this->config->item('NONFINAL_NOTEN_ABGABETOOL'); + + + $this->terminateWithSuccess(array($noten, $allowed_noten_abgabetool, $nonfinal_noten_abgabetool)); } /** diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index e2d4d1b70..5e453056d 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -299,7 +299,7 @@ class Projektarbeit_model extends DB_Model * FROM (SELECT tbl_person.vorname, tbl_person.nachname, tbl_studiengang.typ, tbl_studiengang.kurzbz, - tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung, tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id, + tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung, tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id, tbl_projektarbeit.note, tbl_projektbetreuer.person_id as betreuer_person_id, tbl_projektbetreuer.betreuerart_kurzbz, tbl_betreuerart.beschreibung AS betreuerart_beschreibung, tbl_benutzer.uid, tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz, public.tbl_student.student_uid FROM lehre.tbl_projektarbeit diff --git a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js index 35633321d..42952d0df 100644 --- a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js +++ b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js @@ -21,6 +21,7 @@ export const AbgabeMitarbeiterDetail = { 'abgabeTypeOptions', 'abgabetypenBetreuer', 'allowedNotenOptions', + 'notenOptionsNonFinal', 'turnitin_link', 'old_abgabe_beurteilung_link' ], @@ -48,7 +49,7 @@ export const AbgabeMitarbeiterDetail = { label: Vue.computed(() => this.$p.t('abgabetool/c4newAbgabetermin')), icon: "fa fa-plus", command: this.openCreateNewAbgabeModal, - disabled: Vue.computed(() => this.projektarbeit?.betreuerart_kurzbz == 'Zweitbegutachter') + disabled: Vue.computed(() => !this.getAllowedToCreateNewTermin) }, { label: Vue.computed(() => this.$p.t('abgabetool/c4benoten')), @@ -478,6 +479,21 @@ export const AbgabeMitarbeiterDetail = { }, computed: { + getAllowedToCreateNewTermin() { + if(this.assistenzMode) return true + if(this.projektarbeit?.betreuerart_kurzbz == 'Zweitbegutachter') return false + if(this.projektarbeit?.note !== undefined && this.projektarbeit.note !== null) { + // check if the note is not defined as a non final projektarbeit note + const opt = this.notenOptionsNonFinal.find(opt => opt.note) + // if thats the case allow further work + if(opt) return true + // else the PA is to be considered finished + return false + } + + // normally should be allowed if no rules apply + return true + }, allowedToSaveZusatzdaten() { return this.form.schlagwoerter.length > 0 && this.form.schlagwoerter_en.length > 0 && this.form.abstract.length > 0 && this.form.abstract_en.length > 0 && this.form.seitenanzahl > 0 }, @@ -755,9 +771,8 @@ export const AbgabeMitarbeiterDetail = {
- - - diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js index 0a4028a27..7fa78f7d1 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js @@ -38,6 +38,7 @@ export const AbgabetoolAssistenz = { return { abgabeTypeOptions: Vue.computed(() => this.abgabeTypeOptions), allowedNotenOptions: Vue.computed(() => this.allowedNotenOptions), + notenOptionsNonFinal: Vue.computed(() => this.notenOptionsNonFinal), turnitin_link: Vue.computed(() => this.turnitin_link), old_abgabe_beurteilung_link: Vue.computed(() => this.old_abgabe_beurteilung_link), abgabetypenBetreuer: Vue.computed(() => this.abgabeTypeOptions) @@ -86,6 +87,7 @@ export const AbgabetoolAssistenz = { notenOptions: null, allowedNotenFilterOptions: null, allowedNotenOptions: null, + notenOptionsNonFinal: null, serienTermin: Vue.reactive({ datum: new Date(), bezeichnung: { @@ -1089,6 +1091,10 @@ export const AbgabetoolAssistenz = { this.allowedNotenOptions = this.notenOptions.filter( opt => res.data[1].includes(opt.note) ); + + this.notenOptionsNonFinal = this.notenOptions.filter( + opt => res.data[2].includes(opt.note) + ) } this.allowedNotenFilterOptions = [ diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js index df521d52d..67e1d09af 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js @@ -22,6 +22,7 @@ export const AbgabetoolMitarbeiter = { abgabeTypeOptions: Vue.computed(() => this.abgabeTypeOptions), abgabetypenBetreuer: Vue.computed(() => this.abgabetypenBetreuer), allowedNotenOptions: Vue.computed(() => this.allowedNotenOptions), + notenOptionsNonFinal: Vue.computed(() => this.notenOptionsNonFinal), turnitin_link: Vue.computed(() => this.turnitin_link), old_abgabe_beurteilung_link: Vue.computed(() => this.old_abgabe_beurteilung_link) } @@ -50,6 +51,7 @@ export const AbgabetoolMitarbeiter = { abgabeTypeOptions: null, notenOptions: null, allowedNotenOptions: null, + notenOptionsNonFinal: null, serienTermin: Vue.reactive({ datum: new Date(), bezeichnung: { @@ -301,7 +303,15 @@ export const AbgabetoolMitarbeiter = { pa.abgabetermine = res.data[0].retval pa.isCurrent = res.data[1] - const paIsBenotet = pa.note !== null + let paIsBenotet = false + if(pa.note !== undefined && pa !== null) { + // check if the note is not defined as a non final projektarbeit note + const opt = this.notenOptionsNonFinal.find(opt => opt.note) + // if thats the case allow further work + if(opt) paIsBenotet = false + // else the PA is to be considered finished + paIsBenotet = true + } pa.abgabetermine.forEach(termin => { termin.note = this.allowedNotenOptions.find(opt => opt.note == termin.note) @@ -471,6 +481,10 @@ export const AbgabetoolMitarbeiter = { this.allowedNotenOptions = this.notenOptions.filter( opt => res.data[1].includes(opt.note) ) + + this.notenOptionsNonFinal = this.notenOptions.filter( + opt => res.data[2].includes(opt.note) + ) } }).catch(e => { From 0a97e5781ec21c60241cca768b46d06bd8a0e2eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96sterreicher?= Date: Thu, 12 Feb 2026 11:02:16 +0100 Subject: [PATCH 6/6] Nicht beurteilt aus Default Config entfernt --- application/config/abgabe.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application/config/abgabe.php b/application/config/abgabe.php index f806e1ef8..82782b043 100644 --- a/application/config/abgabe.php +++ b/application/config/abgabe.php @@ -28,7 +28,7 @@ $config['RELEVANT_PAABGABETYPEN_SAMMELMAIL_STUDENT'] = ['qualgate1', 'qualgate2' $config['ALLOWED_NOTEN_ABGABETOOL'] = [10, 14]; // tbl_note pk // benotete projektarbeiten sperren weitere terminanlage & bearbeitung, diese noten sind ausnahmen dieser Regel // wie zB "Nicht beurteilt" & "Noch nicht eingetragen" -$config['NONFINAL_NOTEN_ABGABETOOL'] = [7, 9]; +$config['NONFINAL_NOTEN_ABGABETOOL'] = [9]; $config['beurteilung_link_fallback'] = 'addons/fhtw/content/projektbeurteilung/projektbeurteilungDocumentExport.php?projektarbeit_id=?&betreuerart_kurzbz=?&person_id=?'; $config['PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ERSTBEGUTACHTER'] = 'index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter';