diff --git a/application/config/abgabe.php b/application/config/abgabe.php new file mode 100644 index 000000000..e2092a367 --- /dev/null +++ b/application/config/abgabe.php @@ -0,0 +1,9 @@ + self::PERM_LOGGED, 'getStudentProjektarbeiten' => self::PERM_LOGGED, // TODO: abgabetool berechtigung? 'getStudentProjektabgaben' => self::PERM_LOGGED, 'postStudentProjektarbeitZwischenabgabe' => self::PERM_LOGGED, @@ -70,6 +71,22 @@ class Abgabe extends FHCAPI_Controller //------------------------------------------------------------------------------------------------------------------ // Public methods + /** + * loads config related to abgabetool, found in application/config/abgabe + */ + public function getConfig() { + $this->load->config('abgabe'); + $old_abgabe_beurteilung_link =$this->config->item('old_abgabe_beurteilung_link'); + $turnitin_link =$this->config->item('turnitin_link'); + + $ret = array( + 'old_abgabe_beurteilung_link' => $old_abgabe_beurteilung_link, + 'turnitin_link' => $turnitin_link + ); + + $this->terminateWithSuccess($ret); + } + /** * fetches all projektabgabetermine for a given projektarbeit_id used in cis4 student abgabetool */ @@ -116,9 +133,19 @@ class Abgabe extends FHCAPI_Controller $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID()); if ($isMitarbeiter && $isZugeteilterBetreuer){ - $projektarbeiten = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer($uid); + $result = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer($uid); } else { - $projektarbeiten = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer(getAuthUID()); + $result = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer(getAuthUID()); + } + + $projektarbeiten = getData($result); + + // TODO: save access to this, array could be empty + foreach($projektarbeiten as $pa) { + $result = $this->ProjektarbeitModel->getProjektbetreuerEmail($pa->projektarbeit_id); + + // TODO: save access + $pa->email = getData($result)[0]->private_email; } $this->terminateWithSuccess(array($projektarbeiten, DOMAIN, $uid)); @@ -327,12 +354,8 @@ class Abgabe extends FHCAPI_Controller $maildata['parbeituebersichtlink'] = "
"; $maildata['bewertunglink'] = $num_rows_sem >= 1 && $paabgabetyp_kurzbz == 'end' ? "" : ""; $maildata['token'] = ""; - - // TODO: clarify if all betreuer are mitarbeiter and have benutzer entries - // or if uid = null has to be checked WITH - // 'CASE WHEN tbl_benutzer.uid IS NULL THEN kontakt ELSE tbl_benutzer.uid || '@".DOMAIN."' END AS email' - $email = $this->getBetreuerEmail($bperson_id); + $email = $this->getProjektbetreuerEmail($projektarbeit_id); if(!$email) $this->terminateWithError($this->p->t('abgabetool', 'fehlerMailBegutachter'), 'general'); @@ -401,12 +424,7 @@ class Abgabe extends FHCAPI_Controller $zweitbetmaildata['parbeituebersichtlink'] = $intern ? $maildata['parbeituebersichtlink'] : ""; $zweitbetmaildata['bewertunglink'] = $num_rows_sem >= 1 ? "" : ""; $zweitbetmaildata['token'] = $num_rows_sem >= 1 && isset($begutachterMitToken->zugangstoken) && !$intern ? "Zugangstoken: " . $begutachterMitToken->zugangstoken . "
" : ""; - - - $email = $this->getBetreuerEmail($bperson_id); - - if(!$email) $this->terminateWithError($this->p->t('abgabetool', 'fehlerMailBegutachter'), 'general'); - + $mailres = sendSanchoMail( 'ParbeitsbeurteilungEndupload', @@ -464,12 +482,13 @@ class Abgabe extends FHCAPI_Controller $fixtermin = $_POST['fixtermin']; $kurzbz = $_POST['kurzbz']; $note = $_POST['note']; - $upload_required = $_POST['upload_required']; + $upload_allowed = $_POST['upload_allowed']; + $betreuer_person_id = $_POST['betreuer_person_id']; if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id) || !isset($paabgabe_id) || isEmptyString($paabgabe_id) || !isset($datum) || isEmptyString($datum) - || !isset($datum) || isEmptyString($datum) + || !isset($kurzbz) || !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz)) $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); @@ -484,7 +503,7 @@ class Abgabe extends FHCAPI_Controller 'datum' => $datum, 'kurzbz' => $kurzbz, 'note' => $note, - 'upload_required' => $upload_required, + 'upload_allowed' => $upload_allowed, 'insertvon' => getAuthUID(), 'insertamum' => date('Y-m-d H:i:s') ) @@ -499,24 +518,37 @@ class Abgabe extends FHCAPI_Controller 'datum' => $datum, 'kurzbz' => $kurzbz, 'note' => $note, - 'upload_required' => $upload_required, + 'upload_allowed' => $upload_allowed, 'updatevon' => getAuthUID(), 'updateamum' => date('Y-m-d H:i:s') ) ); } - - $paabgabe_id = $this->getDataOrTerminateWithError($result); - - $paabgabe = $this->PaabgabeModel->load($paabgabe_id); // check if $paaabgabe is a qual gate and its note is deemed negative // -> send email to student with that info + $paabgabe_id = $this->getDataOrTerminateWithError($result); - // TODO: DEFAULT NOTE 9 OR DEFAULT NOTE NULL? 9 COUNTS AS NEGATIV :/ + $result = $this->PaabgabeModel->load($paabgabe_id); + $paabgabeArr = $this->getDataOrTerminateWithError($result); + $paabgabe = $paabgabeArr[0]; + $this->addMeta('paabgabe', $paabgabeArr); + + // check if abgabe even has note + if($paabgabe->note) { + $this->load->model('education/Note_model', 'NoteModel'); + $result = $this->NoteModel->load($paabgabe->note); + $noteArr = $this->getDataOrTerminateWithError($result); + $note = $noteArr[0]; + if($note->positiv === false) { + $this->addMeta('noteNegativ', true); + + $this->sendQualGateNegativEmail($projektarbeit_id, $betreuer_person_id, $paabgabe); + } + } - $this->terminateWithSuccess($result); + $this->terminateWithSuccess($paabgabe); } public function deleteProjektarbeitAbgabe() { @@ -556,7 +588,7 @@ class Abgabe extends FHCAPI_Controller if (!isset($projektarbeit_ids) || !is_array($projektarbeit_ids) || empty($projektarbeit_ids) || !isset($datum) || isEmptyString($datum) - || !isset($kurzbz) || isEmptyString($kurzbz) + || !isset($kurzbz) || !isset($bezeichnung) || isEmptyString($bezeichnung) || !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz)) $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); @@ -664,11 +696,11 @@ class Abgabe extends FHCAPI_Controller $this->terminateWithSuccess($paabgabetypen); } - private function getBetreuerEmail($person_id) { - $this->load->model('education/Projektbetreuer_model', 'ProjektbetreuerModel'); - $result = $this->ProjektbetreuerModel->getBetreuerEmail($person_id); + private function getProjektbetreuerEmail($projektarbeit_id) { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + $result = $this->ProjektarbeitModel->getProjektbetreuerEmail($projektarbeit_id); $email = $this->getDataOrTerminateWithError($result); - return $email[0]->email; + return $email[0]->private_email; } //TODO: SWITCH TO NOTEN API ONCE NOTENTOOL IS IN MASTER TO AVOID DUPLICATE API @@ -685,7 +717,24 @@ class Abgabe extends FHCAPI_Controller $this->terminateWithSuccess($noten); } - private function sendQualGateNegativEmail($student_uid) { + private function sendQualGateNegativEmail($projektarbeit_id, $betreuer_person_id, $paabgabe) { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + $result = $this->ProjektarbeitModel->load($projektarbeit_id); + $projektarbeitArr = $this->getDataOrTerminateWithError($result); + $projektarbeit = $projektarbeitArr[0]; + + $result = $this->ProjektarbeitModel->getProjektbetreuerAnrede($betreuer_person_id); + $anredeArr = $this->getDataOrTerminateWithError($result); + $anrede = $anredeArr[0]; + + $student_uid = $projektarbeit->student_uid; + + $this->load->model('education/Paabgabetyp_model', 'PaabgabetypModel'); + $result = $this->PaabgabetypModel->load($paabgabe->paabgabetyp_kurzbz); + $paabgabetyp_kurzbzArr = $this->getDataOrTerminateWithError($result); + $paabgabetyp_kurzbz = $paabgabetyp_kurzbzArr[0]; + // Mail an Student wenn Qualgate negativ beurteilt wurde $student = new student(); if(!$student->load($student_uid)) @@ -696,21 +745,21 @@ class Abgabe extends FHCAPI_Controller $tomail = $student_uid.'@'.DOMAIN; - // TODO: emaildata + // TODO: datum format $data = array( - 'betreuerfullname' => $student->vorname, - 'qualgatebezeichnung' => $student->nachname, - 'datum' => $datum, - 'projektarbeitname' => $name + 'betreuerfullname' => $anrede->first, + 'qualgatebezeichnung' => $paabgabetyp_kurzbz->bezeichnung, + 'datum' => $paabgabe->datum, + 'projektarbeitname' => $projektarbeit->titel ); + $this->addMeta('$emaildata', $data); + $mailres = sendSanchoMail( 'QualGateNegativ', $data, $tomail, $subject ); - - return $mailres; } } \ No newline at end of file diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index b1971cea7..c87e9c187 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -168,7 +168,7 @@ class Projektarbeit_model extends DB_Model campus.tbl_paabgabe.kurzbz, campus.tbl_paabgabe.datum, campus.tbl_paabgabe.note, - campus.tbl_paabgabe.upload_required, + campus.tbl_paabgabe.upload_allowed, campus.tbl_paabgabetyp.paabgabetyp_kurzbz, campus.tbl_paabgabetyp.bezeichnung, campus.tbl_paabgabe.abgabedatum, @@ -189,7 +189,28 @@ class Projektarbeit_model extends DB_Model WHERE public.tbl_person.person_id= ?"; return $this->execReadOnlyQuery($qry_betr, [$bperson_id]); + } + + public function getProjektbetreuerEmail($projektarbeit_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 + 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 projektarbeit_id = ?"; + return $this->execReadOnlyQuery($qry, [$projektarbeit_id]); } public function getProjektarbeitBenutzer($uid) { @@ -225,7 +246,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_projektbetreuer.betreuerart_kurzbz, tbl_betreuerart.beschreibung AS betreuerart_beschreibung, + 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 FROM lehre.tbl_projektarbeit LEFT JOIN lehre.tbl_projektbetreuer using(projektarbeit_id) diff --git a/application/models/education/Projektbetreuer_model.php b/application/models/education/Projektbetreuer_model.php index ae78b96d9..95950bf95 100644 --- a/application/models/education/Projektbetreuer_model.php +++ b/application/models/education/Projektbetreuer_model.php @@ -231,40 +231,4 @@ class Projektbetreuer_model extends DB_Model return $this->execQuery($qry, array($projektarbeit_id, $betreuer_person_id)); } - - /** - * Gets email of a Betreuer for a Projektarbeit. - * Projektarbeitbetreuer can be external employees, which should be contacted on their private - * email contact, if they have one. Internal Betreuer should be contacted on their "uid@DOMAIN" adress. - * @param int betreuer_person_id - * @return object success or error - */ - public function getBetreuerEmail($betreuer_person_id) { - // TODO: check if benutzer uid exists, not fixangestellt - - $qry =" - SELECT uid, - CASE - WHEN public.tbl_mitarbeiter.fixangestellt = false - THEN ( - SELECT kontakt AS email - FROM public.tbl_kontakt - WHERE - public.tbl_kontakt.person_id = ? AND - kontakttyp = 'email' - ) - - ELSE ( - SELECT public.tbl_benutzer.uid || '@' || '".DOMAIN."' AS email - FROM public.tbl_benutzer - WHERE person_id = ? - ) - END AS email - FROM public.tbl_benutzer - JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid) - WHERE person_id = ? - "; - - return $this->execReadOnlyQuery($qry, array($betreuer_person_id, $betreuer_person_id, $betreuer_person_id)); - } } diff --git a/public/js/api/factory/abgabe.js b/public/js/api/factory/abgabe.js index 0602a218c..67e67f385 100644 --- a/public/js/api/factory/abgabe.js +++ b/public/js/api/factory/abgabe.js @@ -1,4 +1,10 @@ export default { + getConfig() { + return { + method: 'get', + url: '/api/frontend/v1/Abgabe/getConfig' + }; + }, getStudentProjektarbeiten(uid) { return { method: 'get', @@ -51,12 +57,13 @@ export default { paabgabe_id: termin.paabgabe_id, paabgabetyp_kurzbz: termin.bezeichnung.paabgabetyp_kurzbz, datum: termin.datum, - note: termin.note, - upload_required: termin.upload_required, + note: termin.note_pk, + upload_allowed: termin.upload_allowed, fixtermin: termin.fixtermin, insertvon: termin.insertvon, kurzbz: termin.kurzbz, - projektarbeit_id: termin.projektarbeit_id + projektarbeit_id: termin.projektarbeit_id, + betreuer_person_id: termin.betreuer_person_id } }; }, diff --git a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js index c70c40ba7..ca8d92cd8 100644 --- a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js +++ b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js @@ -13,7 +13,7 @@ export const AbgabeMitarbeiterDetail = { Textarea: primevue.textarea, VueDatePicker }, - inject: ['abgabeTypeOptions', 'allowedNotenOptions'], + inject: ['abgabeTypeOptions', 'allowedNotenOptions', 'turnitin_link', 'old_abgabe_beurteilung_link'], props: { projektarbeit: { type: Object, @@ -22,7 +22,6 @@ export const AbgabeMitarbeiterDetail = { }, data() { return { - oldPaBeurteilungLink: 'https://moodle.technikum-wien.at/mod/page/view.php?id=1005052', // TODO: inject from app & app provide link from config eidAkzeptiert: false, enduploadTermin: null, allActiveLanguages: FHC_JS_DATA_STORAGE_OBJECT.server_languages @@ -34,18 +33,15 @@ export const AbgabeMitarbeiterDetail = { }, saveTermin(termin) { const paabgabe_id = termin.paabgabe_id - // 9 => magic number for "noch nicht eingetragen" - termin.note = termin.note?.note ?? 9 + termin.note_pk = termin.note?.note ?? null + termin.betreuer_person_id = this.projektarbeit.betreuer_person_id this.$api.call(ApiAbgabe.postProjektarbeitAbgabe(termin)).then( (res) => { if(res?.meta?.status == 'success') { this.$fhcAlert.alertSuccess(this.$p.t('ui/gespeichert')) - if(paabgabe_id === -1) { // new abgabe has been inserted - termin.paabgabe_id = res?.data?.retval - + termin.paabgabe_id = res?.data?.paabgabe_id this.projektarbeit.abgabetermine.push({ // new abgatermin row - 'paabgabe_id': -1, 'projektarbeit_id': this.projektarbeit.projektarbeit_id, 'fixtermin': false, @@ -53,7 +49,7 @@ export const AbgabeMitarbeiterDetail = { 'datum': new Date().toISOString().split('T')[0], 'paabgabetyp_kurzbz': termin.paabgabetyp_kurzbz, 'note': this.allowedNotenOptions.find(opt => opt.note == termin.note?.note), - 'upload_required': termin.upload_required, + 'upload_allowed': termin.upload_allowed, 'bezeichnung': this.abgabeTypeOptions.find(opt => opt.paabgabetyp_kurzbz === termin.paabgabetyp_kurzbz), 'abgabedatum': null, 'insertvon': this.viewData?.uid ?? '', @@ -61,12 +57,9 @@ export const AbgabeMitarbeiterDetail = { 'allowedToDelete': true }) } - - } else if(res?.meta?.status == 'error'){ this.$fhcAlert.alertError() } - }) }, deleteTermin(termin) { @@ -76,8 +69,6 @@ export const AbgabeMitarbeiterDetail = { // this.$p.t('global/tooltipLektorDeleteKontrolle', [this.$entryParams.permissions.kontrolleDeleteMaxReach ]) const deletedTerminIndex = this.projektarbeit.abgabetermine.findIndex(t => t.paabgabe_id === termin.paabgabe_id) this.projektarbeit.abgabetermine.splice(deletedTerminIndex, 1) - - } else if(res?.meta?.status == 'error'){ this.$fhcAlert.alertError() } @@ -92,15 +83,13 @@ export const AbgabeMitarbeiterDetail = { return true; }, downloadAbgabe(termin) { - // TODO: test this.$api.call(ApiAbgabe.getStudentProjektarbeitAbgabeFile(termin.paabgabe_id, this.projektarbeit.student_uid)) - // this.$fhcApi.factory.lehre.getStudentProjektarbeitAbgabeFile(termin.paabgabe_id, this.projektarbeit.student_uid) }, dateDiffInDays(datum, today){ const oneDayMs = 1000 * 60 * 60 * 24 return Math.round((new Date(datum) - new Date(today)) / oneDayMs) }, - getDateStyle(termin) { + getDateStyle(termin, mode) { const datum = new Date(termin.datum) const abgabedatum = new Date(termin.abgabedatum) @@ -108,21 +97,31 @@ export const AbgabeMitarbeiterDetail = { // https://wiki.fhcomplete.info/doku.php?id=cis:abgabetool_fuer_studierende let color = 'white' let fontColor = 'black' + let icon = ''; if (termin.abgabedatum === null) { if(datum < today) { color = 'red' fontColor = 'white' + icon = 'fa-triangle-exclamation' } else if (datum > today && this.dateDiffInDays(datum, today) <= 12) { color = 'yellow' + icon = 'fa-circle-exclamation' } } else if(abgabedatum > datum) { color = 'pink' // aka "hellrot" fontColor = 'white' + icon = 'fa-circle-question' } else { color = 'green' + icon = 'fa-square-check' } - return `font-color: ${fontColor} ; background-color: ${color}; border-radius: 50%;` + //return `font-color: ${fontColor} ; background-color: ${color}; border-radius: 50%;` + if( typeof mode !== 'undefined' || mode === 'icon') { + return icon; + } else { + return 'abgabe-zieldatum-border-' + color; + } }, openBeurteilungLink(link) { window.open(link, '_blank') @@ -153,8 +152,7 @@ export const AbgabeMitarbeiterDetail = { window.open(link, '_blank') }, openPlagiatcheck() { - // todo: hardcoded turnitin link? - const link = "https://technikum-wien.turnitin.com/sso/sp/redwood/saml/5IyfmBr2OcSIaWQTKlFCGj/start" + const link = this.turnitin_link window.open(link, '_blank') }, openBenotung() { @@ -175,8 +173,17 @@ export const AbgabeMitarbeiterDetail = { }, endUploadVorhanden(){ return this.projektarbeit?.abgabetermine.find(abgabe => abgabe.paabgabetyp_kurzbz === 'end' && abgabe.abgabedatum !== null) + }, + qualityGateTerminAvailable() { + let qgatefound = false + this.projektarbeit?.abgabetermine.forEach(abgabe => { + if(abgabe.bezeichnung?.paabgabetyp_kurzbz == 'qualgate1' + || abgabe?.bezeichnung?.paabgabetyp_kurzbz == 'qualgate2') { + qgatefound = true + } + }) + return qgatefound } - }, created() { @@ -185,7 +192,7 @@ export const AbgabeMitarbeiterDetail = { }, template: ` -Titel: {{ projektarbeit?.titel }}
+{{$p.t('abgabetool/c4titel')}}: {{ projektarbeit?.titel }}