diff --git a/application/controllers/api/frontend/v1/Abgabe.php b/application/controllers/api/frontend/v1/Abgabe.php index c0311426b..c962e4943 100644 --- a/application/controllers/api/frontend/v1/Abgabe.php +++ b/application/controllers/api/frontend/v1/Abgabe.php @@ -531,6 +531,7 @@ class Abgabe extends FHCAPI_Controller 'datum' => $datum, 'kurzbz' => $kurzbz, 'note' => $note, + 'fixtermin' => $fixtermin, 'beurteilungsnotiz' => $beurteilungsnotiz, 'upload_allowed' => $upload_allowed, 'updatevon' => getAuthUID(), @@ -543,6 +544,7 @@ class Abgabe extends FHCAPI_Controller 'datum' => $datum, 'kurzbz' => $kurzbz, 'note' => $note, + 'fixtermin' => $fixtermin, 'beurteilungsnotiz' => $beurteilungsnotiz, 'upload_allowed' => $upload_allowed, 'updatevon' => getAuthUID(), @@ -734,7 +736,7 @@ class Abgabe extends FHCAPI_Controller $result = $this->ProjektarbeitModel->getProjektbetreuerEmail($projektarbeit_id); $email = $this->getDataOrTerminateWithError($result); - return $email[0]->private_email ?? $email[0]->uid.'@'.DOMAIN; + return $email[0]->uid ? $email[0]->uid.'@'.DOMAIN : $email[0]->private_email; } @@ -787,7 +789,7 @@ class Abgabe extends FHCAPI_Controller $this->terminateWithError($this->p->t('abgabetool','c4userNichtGefunden'), 'general'); } - $subject = $this->p->t('abgabetool', 'c4qualgateNegativEmailSubject'); + $subject = $this->p->t('abgabetool', 'c4qualgateNegativEmailSubjectv2'); $tomail = $student_uid.'@'.DOMAIN; $datetime = new DateTime($paabgabe->datum); diff --git a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js index 38e9f9dd4..f084d9d5c 100644 --- a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js +++ b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js @@ -299,6 +299,14 @@ export const AbgabeMitarbeiterDetail = { const abgabedatum = new Date(termin.abgabedatum) termin.diffindays = this.dateDiffInDays(termin.datum) + + // TODO: load benotbar in every view or change status logic all together! + + // console.log('\n\n') + // console.log(termin) + // console.log(today) + // console.log(datum) + // console.log('\n\n') if(today > datum && termin.benotbar && !termin.note) return 'beurteilungerforderlich' if (termin.abgabedatum === null && termin.upload_allowed) { @@ -532,7 +540,7 @@ export const AbgabeMitarbeiterDetail = { }, getTooltipBeurteilungerforderlich() { return { - value: this.$p.t('abgabetool/c4tooltipBeurteilungerfolderlich'), + value: this.$p.t('abgabetool/c4tooltipBeurteilungerforderlich'), class: "custom-tooltip" } }, diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js index 8ca1b931e..739791ed4 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js @@ -72,6 +72,7 @@ export const AbgabetoolAssistenz = { selectedStudiengangOption: null, studiengaengeOptions: null, detailIsFullscreen: false, + allConfigPromise: null, phrasenPromise: null, phrasenResolved: false, turnitin_link: null, @@ -90,6 +91,7 @@ export const AbgabetoolAssistenz = { }, kurzbz: '', fixtermin: false, + invertedFixtermin: true, upload_allowed: false }), showAll: false, @@ -285,7 +287,7 @@ export const AbgabetoolAssistenz = { } else if(qgate.upload_allowed == true && qgate.abgabedatum == null && projekt.qgate1StatusRank <= 2) { projekt.qgate1Status = this.$p.t('abgabetool/c4notSubmitted') projekt.qgate1StatusRank = 2 - } else if (qgate.upload_allowed == false && diffMs <= 0 && projekt.qgate1StatusRank <= 1) { + } else if (qgate.upload_allowed == false && qgate.diffMs <= 0 && projekt.qgate1StatusRank <= 1) { projekt.qgate1Status = this.$p.t('abgabetool/c4notHappenedYet') projekt.qgate1StatusRank = 1 } @@ -307,7 +309,7 @@ export const AbgabetoolAssistenz = { } else if(qgate.upload_allowed == true && qgate.abgabedatum == null && projekt.qgate2StatusRank <= 2) { projekt.qgate2Status = this.$p.t('abgabetool/c4notSubmitted') projekt.qgate2StatusRank = 2 - } else if (qgate.upload_allowed == false && diffMs <= 0 && projekt.qgate2StatusRank <= 1) { + } else if (qgate.upload_allowed == false && qgate.diffMs <= 0 && projekt.qgate2StatusRank <= 1) { projekt.qgate2Status = this.$p.t('abgabetool/c4notHappenedYet') projekt.qgate2StatusRank = 1 } @@ -582,6 +584,7 @@ export const AbgabetoolAssistenz = { addSeries() { const pids = this.selectedData?.map(projekt => projekt.projektarbeit_id) this.saving = true + this.serienTermin.fixtermin = !this.serienTermin.invertedFixtermin this.$api.call(ApiAbgabe.postSerientermin( this.serienTermin.datum.toISOString(), this.serienTermin.bezeichnung.paabgabetyp_kurzbz, @@ -896,6 +899,8 @@ export const AbgabetoolAssistenz = { this.tableBuiltPromise = new Promise(this.tableResolve) await this.tableBuiltPromise + await this.allConfigPromise + // called through notenOptionFilter/selectedStudiengangOption watcher on startup // this.loadProjektarbeiten() @@ -929,79 +934,74 @@ export const AbgabetoolAssistenz = { this.loading = true this.phrasenPromise = this.$p.loadCategory(['abgabetool', 'global']) this.phrasenPromise.then(()=> {this.phrasenResolved = true}) - // fetch config to avoid hard coded links - this.$api.call(ApiAbgabe.getConfig()).then(res => { - this.turnitin_link = res.data?.turnitin_link - this.old_abgabe_beurteilung_link = res.data?.old_abgabe_beurteilung_link - }).catch(e => { - this.loading = false - }) - - // fetch studiengänge options - this.$api.call(ApiAbgabe.getStudiengaenge()).then(res => { - this.studiengaengeOptions = res.data - if(this.studiengaengeOptions?.length) { - - // use this.stg_kz_prop as default selected in case of url param usage - - this.selectedStudiengangOption = this.stg_kz_prop ? res.data.find(stgOpt => stgOpt.studiengang_kz == this.stg_kz_prop) : res.data[0] - } - - }).catch(e => { - this.loading = false - }) - this.$api.call(ApiStudiensemester.getAllStudiensemesterAndAktOrNext()).then((res) => { - this.allSem = res.data[0] - const all = {studiensemester_kurzbz: this.$p.t('abgabetool/c4all')} - this.curSem = all // res.data[1] - - this.studiensemesterOptions = [all, ...this.allSem] - - }).catch(e => { - this.loading = false - }) - - // fetch noten options //TODO: SWITCH TO NOTEN API ONCE NOTENTOOL IS IN MASTER TO AVOID DUPLICATE API - this.$api.call(ApiAbgabe.getNoten()).then(res => { - if(res.meta.status == 'success') { - this.notenOptions = res.data[0] + const requests = [ + this.$api.call(ApiAbgabe.getConfig()), + this.$api.call(ApiAbgabe.getStudiengaenge()), + this.$api.call(ApiStudiensemester.getAllStudiensemesterAndAktOrNext()), + this.$api.call(ApiAbgabe.getNoten()), + this.$api.call(ApiAbgabe.getPaAbgabetypen()) + ]; - this.allowedNotenOptions = this.notenOptions.filter( - opt => res.data[1].includes(opt.note) - ) - } - - // allowedNotenOptions apply to quality gates abgabetermine - // this selection is about graded projektarbeiten, so take different options here - this.allowedNotenFilterOptions = [ - { - bezeichnung: Vue.computed(() => this.$p.t('abgabetool/keineNoteEingetragen')), - benotet: 0, - }, - { - bezeichnung: Vue.computed(() => this.$p.t('abgabetool/c4benotet')), - benotet: 1, - }, - { - bezeichnung: Vue.computed(() => this.$p.t('abgabetool/showAll')), - benotet: -1, - }, - ] - - this.notenOptionFilter = this.allowedNotenFilterOptions[0] - - }).catch(e => { - this.loading = false - }) + this.allConfigPromise = Promise.allSettled(requests) + .then((results) => { + // results is an array of { status: 'fulfilled'|'rejected', value?: any, reason?: any } - // fetch abgabetypen options - this.$api.call(ApiAbgabe.getPaAbgabetypen()).then(res => { - this.abgabeTypeOptions = res.data - }).catch(e => { - this.loading = false - }) + // 1. Config + if (results[0].status === 'fulfilled') { + const res = results[0].value; + this.turnitin_link = res.data?.turnitin_link; + this.old_abgabe_beurteilung_link = res.data?.old_abgabe_beurteilung_link; + } + + // 2. Studiengänge + if (results[1].status === 'fulfilled') { + const res = results[1].value; + this.studiengaengeOptions = res.data; + if (this.studiengaengeOptions?.length) { + this.selectedStudiengangOption = this.stg_kz_prop + ? res.data.find(stgOpt => stgOpt.studiengang_kz == this.stg_kz_prop) + : res.data[0]; + } + } + + // 3. Studiensemester + if (results[2].status === 'fulfilled') { + const res = results[2].value; + this.allSem = res.data[0]; + const all = { studiensemester_kurzbz: this.$p.t('abgabetool/c4all') }; + this.curSem = all; + this.studiensemesterOptions = [all, ...this.allSem]; + } + + // 4. Noten + if (results[3].status === 'fulfilled') { + const res = results[3].value; + if (res.meta?.status === 'success') { + this.notenOptions = res.data[0]; + this.allowedNotenOptions = this.notenOptions.filter( + opt => res.data[1].includes(opt.note) + ); + } + + this.allowedNotenFilterOptions = [ + { bezeichnung: Vue.computed(() => this.$p.t('abgabetool/keineNoteEingetragen')), benotet: 0 }, + { bezeichnung: Vue.computed(() => this.$p.t('abgabetool/c4benotet')), benotet: 1 }, + { bezeichnung: Vue.computed(() => this.$p.t('abgabetool/showAll')), benotet: -1 } + ]; + this.notenOptionFilter = this.allowedNotenFilterOptions[0]; + } + + // 5. Abgabetypen + if (results[4].status === 'fulfilled') { + const res = results[4].value; + this.abgabeTypeOptions = res.data; + } + }) + .finally(() => { + this.loading = false; + }); }, mounted() { this.setupMounted() @@ -1023,7 +1023,7 @@ export const AbgabetoolAssistenz = {