diff --git a/application/controllers/api/frontend/v1/Lehre.php b/application/controllers/api/frontend/v1/Lehre.php index a6c593d3a..d0b712e36 100644 --- a/application/controllers/api/frontend/v1/Lehre.php +++ b/application/controllers/api/frontend/v1/Lehre.php @@ -43,7 +43,9 @@ class Lehre extends FHCAPI_Controller 'getStudentProjektabgaben' => self::PERM_LOGGED, 'postStudentProjektarbeitZwischenabgabe' => self::PERM_LOGGED, 'postStudentProjektarbeitEndupload' => self::PERM_LOGGED, - 'getMitarbeiterProjektarbeiten' => self::PERM_LOGGED + 'getMitarbeiterProjektarbeiten' => self::PERM_LOGGED, + 'postProjektarbeitAbgabe' => self::PERM_LOGGED, + 'deleteProjektarbeitAbgabe' => self::PERM_LOGGED ]); $this->load->library('PhrasesLib'); @@ -448,9 +450,6 @@ class Lehre extends FHCAPI_Controller public function getMitarbeiterProjektarbeiten() { $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); -// if (!isset($uid) || isEmptyString($uid)) -// $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - $boolParamStr = $this->input->get('showall'); $trueStrings = ['true', '1']; $falseStrings = ['false', '0']; @@ -473,5 +472,76 @@ class Lehre extends FHCAPI_Controller $this->terminateWithSuccess(array($projektarbeiten, DOMAIN)); } + + public function postProjektarbeitAbgabe() { + $projektarbeit_id = $_POST['projektarbeit_id']; + $paabgabe_id = $_POST['paabgabe_id']; + $paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz']; + $datum = $_POST['datum']; + $fixtermin = $_POST['fixtermin']; + $kurzbz = $_POST['kurzbz']; + + if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id) + || !isset($paabgabe_id) || isEmptyString($paabgabe_id) + || !isset($datum) || isEmptyString($datum) + || !isset($datum) || isEmptyString($datum) + || !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz)) + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + + if($paabgabe_id == -1) { + $result = $this->PaabgabeModel->insert( + array( + 'projektarbeit_id' => $projektarbeit_id, + 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, + 'fixtermin' => $fixtermin, + 'datum' => $datum, + 'kurzbz' => $kurzbz, + 'insertvon' => getAuthUID(), + 'insertamum' => date('Y-m-d H:i:s') + ) + ); + + $this->terminateWithSuccess($result); + } else { + $result = $this->PaabgabeModel->update( + $paabgabe_id, + array( + 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, + 'datum' => $datum, + 'kurzbz' => $kurzbz, + 'updatevon' => getAuthUID(), + 'updateamum' => date('Y-m-d H:i:s') + ) + ); + + $this->terminateWithSuccess($result); + } + } + + public function deleteProjektarbeitAbgabe() { + $paabgabe_id = $_POST['paabgabe_id']; + + if (!isset($paabgabe_id) || isEmptyString($paabgabe_id)) + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + + $result = $this->PaabgabeModel->load($paabgabe_id); + $result = $this->getDataOrTerminateWithError($result); + + if(count($result) == 0) + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + + // TODO: berechtigung? + if($result[0]->insertvon === getAuthUID()) { + $result = $this->PaabgabeModel->delete($paabgabe_id); + $result = $this->getDataOrTerminateWithError($result); + $this->terminateWithSuccess($result); + } + + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } } diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index 97235c37d..558059f72 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -31,15 +31,4 @@ class Paabgabe_model extends DB_Model return $this->execQuery($qry, array($projektarbeit_id)); } - public function updatePaabgabe($paabgabe_id) { - $qry=" - UPDATE campus.tbl_paabgabe SET - abgabedatum = now(), - updatevon = ?, - updateamum = now() - WHERE paabgabe_id= ?"; - - return $this->execQuery($qry, array(getAuthUID(), $paabgabe_id)); - } - } diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index fb5c62149..1041b3aec 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -169,7 +169,8 @@ class Projektarbeit_model extends DB_Model campus.tbl_paabgabe.datum, campus.tbl_paabgabetyp.paabgabetyp_kurzbz, campus.tbl_paabgabetyp.bezeichnung, - campus.tbl_paabgabe.abgabedatum + campus.tbl_paabgabe.abgabedatum, + campus.tbl_paabgabe.insertvon FROM campus.tbl_paabgabe JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz) WHERE campus.tbl_paabgabe.projektarbeit_id = ? ORDER BY campus.tbl_paabgabe.datum"; diff --git a/public/js/api/lehre.js b/public/js/api/lehre.js index cd8c911e2..2bf6dd277 100644 --- a/public/js/api/lehre.js +++ b/public/js/api/lehre.js @@ -54,5 +54,28 @@ export default { `/api/frontend/v1/Lehre/getMitarbeiterProjektarbeiten?showall=${all}` , {} ); + }, + postProjektarbeitAbgabe(termin) { + const payload = { + paabgabe_id: termin.paabgabe_id, + paabgabetyp_kurzbz: termin.bezeichnung.paabgabetyp_kurzbz, + datum: termin.datum, + fixtermin: termin.fixtermin, + insertvon: termin.insertvon, + kurzbz: termin.kurzbz, + projektarbeit_id: termin.projektarbeit_id + } + const url = '/api/frontend/v1/Lehre/postProjektarbeitAbgabe'; + + return this.$fhcApi.post(url, payload, null) + + }, + deleteProjektarbeitAbgabe(paabgabe_id) { + const payload = { + paabgabe_id + } + const url = '/api/frontend/v1/Lehre/deleteProjektarbeitAbgabe'; + + return this.$fhcApi.post(url, payload, null) } } \ No newline at end of file diff --git a/public/js/apps/Dashboard/Fhc.js b/public/js/apps/Dashboard/Fhc.js index 457d57e63..31f783b09 100644 --- a/public/js/apps/Dashboard/Fhc.js +++ b/public/js/apps/Dashboard/Fhc.js @@ -32,7 +32,7 @@ const router = VueRouter.createRouter({ props: true }, { - path: `/Cis/Abgabetool/Student`, + path: `/Cis/Abgabetool/Student/:student_uid_prop?`, name: 'AbgabetoolStudent', component: AbgabetoolStudent, props: true diff --git a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js index 016e08464..3451d97ba 100644 --- a/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js +++ b/public/js/components/Cis/Abgabetool/AbgabeMitarbeiterDetail.js @@ -8,7 +8,8 @@ export const AbgabeMitarbeiterDetail = { InputNumber: primevue.inputnumber, Checkbox: primevue.checkbox, Dropdown: primevue.dropdown, - Textarea: primevue.textarea + Textarea: primevue.textarea, + VueDatePicker }, props: { projektarbeit: { @@ -21,6 +22,29 @@ export const AbgabeMitarbeiterDetail = { eidAkzeptiert: false, enduploadTermin: null, allActiveLanguages: FHC_JS_DATA_STORAGE_OBJECT.server_languages, + // TODO: fetch types + allAbgabeTypes: [ + { + paabgabetyp_kurzbz: 'abstract', + bezeichnung: 'Entwurf' + }, + { + paabgabetyp_kurzbz: 'zwischen', + bezeichnung: 'Zwischenabgabe' + }, + { + paabgabetyp_kurzbz: 'note', + bezeichnung: 'Benotung' + }, + { + paabgabetyp_kurzbz: 'end', + bezeichnung: 'Endupload' + }, + { + paabgabetyp_kurzbz: 'enda', + bezeichnung: 'Endabgabe im Sekretariat' + } + ], form: Vue.reactive({ sprache: '', abstract: '', @@ -36,11 +60,52 @@ export const AbgabeMitarbeiterDetail = { openZusatzdatenModal(termin) { }, - save(termin) { - // TODO: api speichern termin + saveTermin(termin) { + const paabgabe_id = termin.paabgabe_id + this.$fhcApi.factory.lehre.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 + + this.projektarbeit.abgabetermine.push({ // new abgatermin row + + 'paabgabe_id': -1, + 'projektarbeit_id': this.projektarbeit.projektarbeit_id, + 'fixtermin': false, + 'kurzbz': '', + 'datum': new Date().toISOString().split('T')[0], + 'paabgabetyp_kurzbz': '', + 'bezeichnung': '', + 'abgabedatum': null, + 'insertvon': this.viewData?.uid ?? '', + 'allowedToSave': true, + 'allowedToDelete': true + }) + } + + + } else if(res?.meta?.status == 'error'){ + this.$fhcAlert.alertError() + } + + }) }, - delete(termin) { - // TODO: api delete termin + deleteTermin(termin) { + debugger + this.$fhcApi.factory.lehre.deleteProjektarbeitAbgabe(termin.paabgabe_id).then( (res) => { + if(res?.meta?.status == 'success') { + this.$fhcAlert.alertSuccess(this.$p.t('ui/genericDeleted', [this.$p.t('abgabetool/abgabe')])) + // 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() + } + }) }, validate: function(termin) { if(!termin.file.length) { @@ -84,8 +149,25 @@ export const AbgabeMitarbeiterDetail = { openBeurteilungLink(link) { window.open(link, '_blank') }, - getOptionLabel(option) { + getOptionLabelSprache(option) { return option.sprache + }, + getOptionLabelAbgabetyp(option){ + 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}`; + }, + openStudentPage() { + // TODO: do it } }, watch: { @@ -119,39 +201,58 @@ export const AbgabeMitarbeiterDetail = {
{{$p.t('abgabetool/c4abgabeMitarbeiterbereich')}}
-

{{projektarbeit?.student}}

-

{{projektarbeit?.titel}}

-

{{projektarbeit?.zweitbegutachter}}

+
+

{{projektarbeit?.student}}

+

{{projektarbeit?.titel}}

+

{{projektarbeit?.zweitbegutachter}}

+
+
+ +
{{$p.t('abgabetool/c4fixtermin')}}
-
{{$p.t('abgabetool/c4zieldatum')}}
-
{{$p.t('abgabetool/c4abgabetyp')}}
-
{{$p.t('abgabetool/c4abgabekurzbz')}}
+
{{$p.t('abgabetool/c4zieldatum')}}
+
{{$p.t('abgabetool/c4abgabetyp')}}
+
{{$p.t('abgabetool/c4abgabekurzbz')}}
{{$p.t('abgabetool/c4abgabedatum')}}
- +
keine Termine gefunden!

-
+
- - {{ termin.datum?.split("-").reverse().join(".") }} + +
-
- - {{ termin.bezeichnung }} -
- - {{ termin.kurzbz }} + + +
+
+
{{ termin.abgabedatum?.split("-").reverse().join(".") }} @@ -159,22 +260,16 @@ export const AbgabeMitarbeiterDetail = {
-
+
-
-
-
- -
-
- @@ -208,7 +303,7 @@ export const AbgabeMitarbeiterDetail = { :style="{'width': '100%'}" v-model="form.sprache" :options="allActiveLanguages" - :optionLabel="getOptionLabel"> + :optionLabel="getOptionLabelSprache">
diff --git a/public/js/components/Cis/Abgabetool/AbgabeStudentDetail.js b/public/js/components/Cis/Abgabetool/AbgabeStudentDetail.js index 513d4f0e5..3c695a038 100644 --- a/public/js/components/Cis/Abgabetool/AbgabeStudentDetail.js +++ b/public/js/components/Cis/Abgabetool/AbgabeStudentDetail.js @@ -16,6 +16,10 @@ export const AbgabeStudentDetail = { projektarbeit: { type: Object, default: null + }, + viewMode: { + type: Boolean, + default: false } }, data() { @@ -217,10 +221,10 @@ export const AbgabeStudentDetail = {
- +
- diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js index 30344e4a0..98d36be19 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js @@ -7,7 +7,7 @@ export const AbgabetoolMitarbeiter = { components: { CoreFilterCmpt, AbgabeDetail, - VerticalSplit + VerticalSplit, }, props: { viewData: { @@ -33,7 +33,7 @@ export const AbgabetoolMitarbeiter = { tableBuiltResolve: null, tableBuiltPromise: null, abgabeTableOptions: { - height: 300, + height: 700, index: 'projektarbeit_id', layout: 'fitDataStretch', placeholder: this.$p.t('global/noDataAvailable'), @@ -111,6 +111,7 @@ export const AbgabetoolMitarbeiter = { }, toggleShowAll(showall) { this.showAll = showall + // TODO: debug tabulator row render this.loadProjektarbeiten(showall, () => { this.$refs.abgabeTable?.tabulator.redraw(true) }) }, addSeries() { @@ -120,23 +121,31 @@ export const AbgabetoolMitarbeiter = { return new Date(date) < new Date(Date.now()) }, setDetailComponent(details){ - debugger this.loadAbgaben(details).then((res)=> { - debugger const pa = this.projektarbeiten?.retval?.find(projekarbeit => projekarbeit.projektarbeit_id == details.projektarbeit_id) pa.abgabetermine = res.data.retval + pa.abgabetermine.push({ // new abgatermin row + + 'paabgabe_id': -1, + 'projektarbeit_id': pa.projektarbeit_id, + 'fixtermin': false, + 'kurzbz': '', + 'datum': new Date().toISOString().split('T')[0], + 'paabgabetyp_kurzbz': '', + 'bezeichnung': '', + 'abgabedatum': null, + 'insertvon': this.viewData?.uid ?? '' + + }) pa.abgabetermine.forEach(termin => { termin.file = [] - termin.allowedToUpload = true - - // TODO: fixtermin logic? - if(termin.bezeichnung == 'Endupload' && this.isPastDate(termin.datum)) { - - // termin.allowedToUpload = false - } else { - // termin.allowedToUpload = true + termin.allowedToSave = termin.insertvon == this.viewData?.uid && pa.betreuerart_kurzbz != 'Zweitbegutachter' + termin.allowedToDelete = termin.allowedToSave && !termin.abgabedatum + + termin.bezeichnung = { + bezeichnung: termin.bezeichnung, + paabgabetyp_kurzbz: termin.paabgabetyp_kurzbz } - }) pa.betreuer = this.buildBetreuer(pa) pa.student_uid = details.student_uid @@ -192,6 +201,7 @@ export const AbgabetoolMitarbeiter = { return (projekt.typ + projekt.kurzbz)?.toUpperCase() }, buildBetreuer(abgabe) { + // TODO: preload and insert own titled name of betreuer somehow return abgabe.betreuerart_beschreibung + ': ' + (abgabe.btitelpre ? abgabe.btitelpre + ' ' : '') + abgabe.bvorname + ' ' + abgabe.bnachname + (abgabe.btitelpost ? ' ' + abgabe.btitelpost : '') }, setupData(data){ @@ -275,14 +285,14 @@ export const AbgabetoolMitarbeiter = { this.setupMounted() }, template: ` -
- -

{{$p.t('abgabetool/abgabetoolTitle')}}

-
+ - + + + -
`, }; diff --git a/public/js/components/Cis/Abgabetool/AbgabetoolStudent.js b/public/js/components/Cis/Abgabetool/AbgabetoolStudent.js index 699be7de6..086cc8a9d 100644 --- a/public/js/components/Cis/Abgabetool/AbgabetoolStudent.js +++ b/public/js/components/Cis/Abgabetool/AbgabetoolStudent.js @@ -4,11 +4,13 @@ import AbgabeDetail from "./AbgabeStudentDetail.js"; export const AbgabetoolStudent = { name: "AbgabetoolStudent", components: { - VueDatePicker, CoreFilterCmpt, AbgabeDetail }, props: { + student_uid_prop: { + default: null + }, viewData: { type: Object, required: true, @@ -177,7 +179,7 @@ export const AbgabetoolStudent = { this.$refs.abgabeTable.tabulator.setData(d); }, loadProjektarbeiten() { - this.$fhcApi.factory.lehre.getStudentProjektarbeiten(this.viewData?.uid ?? null) + this.$fhcApi.factory.lehre.getStudentProjektarbeiten(this.student_uid_prop ?? this.viewData?.uid ?? null) .then(res => { if(res?.data) this.setupData(res.data) }) @@ -205,7 +207,9 @@ export const AbgabetoolStudent = { }, computed: { - + isViewMode() { + return this.student_uid !== null + } }, created() { @@ -228,7 +232,7 @@ export const AbgabetoolStudent = {
- +
`, }; diff --git a/public/js/plugin/FhcApi.js b/public/js/plugin/FhcApi.js index 0845a1a5e..211a2c4e1 100644 --- a/public/js/plugin/FhcApi.js +++ b/public/js/plugin/FhcApi.js @@ -1,7 +1,5 @@ import FhcAlert from './FhcAlert.js'; import FhcApiFactory from '../api/fhcapifactory.js'; - - export default { install: (app, options) => { if (app.config.globalProperties.$fhcApi) {