diff --git a/application/config/stv.php b/application/config/stv.php index 0e18be220..8942c35e6 100644 --- a/application/config/stv.php +++ b/application/config/stv.php @@ -88,9 +88,14 @@ if (!defined('ZGV_DOKTOR_ANZEIGEN') || !ZGV_DOKTOR_ANZEIGEN) { ); } -$config['tabs']['projektarbeit']['defaultProjektbetreuerStunden'] = '4.0'; -$config['tabs']['projektarbeit']['defaultProjektbetreuerStundenDiplom'] = '5.0'; -$config['tabs']['projektarbeit']['lvLektroinnenzuteilungFixangestelltStundensatz'] = true; +$config['tabs']['projektarbeit']['defaultProjektbetreuerStunden'] = + defined('FAS_STUDIERENDE_PROJEKTARBEIT_DEFAULT_BETREUER_STUNDEN_BACHELOR') + ? FAS_STUDIERENDE_PROJEKTARBEIT_DEFAULT_BETREUER_STUNDEN_BACHELOR + : '0.0'; +$config['tabs']['projektarbeit']['defaultProjektbetreuerStundenDiplom'] = + defined('FAS_STUDIERENDE_PROJEKTARBEIT_DEFAULT_BETREUER_STUNDEN_MASTER') + ? FAS_STUDIERENDE_PROJEKTARBEIT_DEFAULT_BETREUER_STUNDEN_MASTER + : '0.0'; $config['tabs']['projektarbeit']['defaultProjektbetreuerStundensatz'] = '80.0'; $config['student_tab_order'] = [ diff --git a/application/controllers/api/frontend/v1/stv/Projektarbeit.php b/application/controllers/api/frontend/v1/stv/Projektarbeit.php index 9cc604184..db7d99752 100644 --- a/application/controllers/api/frontend/v1/stv/Projektarbeit.php +++ b/application/controllers/api/frontend/v1/stv/Projektarbeit.php @@ -17,7 +17,8 @@ class Projektarbeit extends FHCAPI_Controller 'getTypenProjektarbeit' => ['admin:r', 'assistenz:r'], 'getFirmen' => ['admin:r', 'assistenz:r'], 'getLehrveranstaltungen' => ['admin:r', 'assistenz:r'], - 'getNoten' => ['admin:r', 'assistenz:r'] + 'getNoten' => ['admin:r', 'assistenz:r'], + 'getStudiensemester' => ['admin:r', 'assistenz:r'] ]); // Load Libraries @@ -40,11 +41,15 @@ class Projektarbeit extends FHCAPI_Controller $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); $this->load->model('education/Note_model', 'NoteModel'); $this->load->model('education/Projektbetreuer_model', 'BetreuerModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); // load libraries $this->load->library('PermissionLib'); } + /** + * Get projekt works for a uid. + */ public function getProjektarbeit() { $student_uid = $this->input->get('uid'); @@ -53,10 +58,7 @@ class Projektarbeit extends FHCAPI_Controller $result = $this->ProjektarbeitModel->getProjektarbeit($student_uid); - if (isError($result)) - { - $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } + if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); if (!hasData($result)) $this->terminateWithSuccess([]); @@ -79,6 +81,9 @@ class Projektarbeit extends FHCAPI_Controller $this->terminateWithSuccess($projektarbeiten); } + /** + * Load a single Projektarbeit by id. + */ public function loadProjektarbeit() { $projektarbeit_id = $this->input->get('projektarbeit_id'); @@ -101,6 +106,9 @@ class Projektarbeit extends FHCAPI_Controller $this->terminateWithSuccess(current($data)); } + /** + * Inwert a Projektarbeit. + */ public function insertProjektarbeit() { $student_uid = $this->input->post('uid'); @@ -128,6 +136,9 @@ class Projektarbeit extends FHCAPI_Controller $this->terminateWithSuccess($data); } + /** + * Update a Projektarbeit by ID. + */ public function updateProjektarbeit() { $projektarbeit_id = $this->input->post('projektarbeit_id'); @@ -157,6 +168,9 @@ class Projektarbeit extends FHCAPI_Controller $this->terminateWithSuccess($data); } + /** + * Delete Projektarbeit by ID after validation. + */ public function deleteProjektarbeit() { $projektarbeit_id = $this->input->post('projektarbeit_id'); @@ -185,6 +199,9 @@ class Projektarbeit extends FHCAPI_Controller return $this->terminateWithSuccess(current(getData($result)) ? : null); } + /** + * Get all active projekt work types. + */ public function getTypenProjektarbeit() { $result = $this->ProjekttypModel->loadWhere(['aktiv' => true]); @@ -194,6 +211,9 @@ class Projektarbeit extends FHCAPI_Controller return $this->terminateWithSuccess(hasData($result) ? getData($result) : []); } + /** + * Gets companies by search string. + */ public function getFirmen() { $searchString = $this->input->get('searchString'); @@ -208,6 +228,9 @@ class Projektarbeit extends FHCAPI_Controller return $this->terminateWithSuccess(hasData($result) ? getData($result) : []); } + /** + * Get Lehrveranstaltungen by params, incling lehreinheiten for a specific Studiensemester.. + */ public function getLehrveranstaltungen() { $student_uid = $this->input->get('student_uid'); @@ -218,6 +241,7 @@ class Projektarbeit extends FHCAPI_Controller if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL); if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemster missing', self::ERROR_TYPE_GENERAL); + // get Lvs $lvsResult = $this->LehrveranstaltungModel->getLvsForProjektarbeit($student_uid, $studiengang_kz, $additional_lehrveranstaltung_id); if (isError($lvsResult)) return $this->terminateWithError($lvsResult, self::ERROR_TYPE_GENERAL); @@ -226,6 +250,7 @@ class Projektarbeit extends FHCAPI_Controller foreach ($lvs as $lv) { + // add Lehreinheiten for each Lv for the semester $lehreinheiten = $this->LehreinheitModel->getLesForLv( $lv->lehrveranstaltung_id, $studiensemester_kurzbz ); @@ -250,6 +275,9 @@ class Projektarbeit extends FHCAPI_Controller return $this->terminateWithSuccess($lvs); } + /** + * Get all noten. + */ public function getNoten() { $result = $this->NoteModel->load(); @@ -260,9 +288,22 @@ class Projektarbeit extends FHCAPI_Controller } /** - * - * @param - * @return object success or error + * Get all Studiensemester, sorted. + */ + public function getStudiensemester() + { + $this->StudiensemesterModel->addOrder('start', 'DESC'); + $result = $this->StudiensemesterModel->load(); + + if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + + return $this->terminateWithSuccess(hasData($result) ? getData($result) : []); + } + + /** + * Validate Projektarbeit data. + * @param formData + * @return bool true if data valid */ private function _validate($formData) { @@ -293,9 +334,9 @@ class Projektarbeit extends FHCAPI_Controller } /** - * - * @param - * @return object success or error + * Extract Projektarbeit data from passed form data. + * @param formData + * @return array */ private function _getProjektarbeitArr($formData) { @@ -317,9 +358,9 @@ class Projektarbeit extends FHCAPI_Controller } /** - * - * @param - * @return object success or error + * Check if deletion of a Projektarbeit is possible. + * @param $projektarbeit_id + * @return object success if deletion possible, error otherwise. */ private function _validateDelete($projektarbeit_id) { @@ -340,6 +381,11 @@ class Projektarbeit extends FHCAPI_Controller return success(); } + /** + * Checks permissions for a student. + * @param $student_uid + * @return bool true if authorized + */ private function _hasBerechtigungForStudent($student_uid) { if (!$student_uid) diff --git a/application/controllers/api/frontend/v1/stv/Projektbetreuer.php b/application/controllers/api/frontend/v1/stv/Projektbetreuer.php index 98567ecde..904fa6167 100644 --- a/application/controllers/api/frontend/v1/stv/Projektbetreuer.php +++ b/application/controllers/api/frontend/v1/stv/Projektbetreuer.php @@ -3,7 +3,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); use \DateTime as DateTime; -use CI3_Events as Events; +use \CI3_Events as Events; class Projektbetreuer extends FHCAPI_Controller { @@ -43,6 +43,9 @@ class Projektbetreuer extends FHCAPI_Controller $this->load->library('PermissionLib'); } + /** + * Gets Projektbetreuer data for a Projektarbeit. + */ public function getProjektbetreuer() { $projektarbeit_id = $this->input->get('projektarbeit_id'); @@ -50,21 +53,30 @@ class Projektbetreuer extends FHCAPI_Controller if (!isset($projektarbeit_id)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID']), self::ERROR_TYPE_GENERAL); - $this->ProjektbetreuerModel->addSelect( - 'projektarbeit_id, person_id, nachname, vorname, note, punkte, round(stunden, 1) AS stunden, - stundensatz, betreuerart_kurzbz, vertrag_id, titelpre, titelpost' - ); - $this->ProjektbetreuerModel->addSelect("CASE - WHEN EXISTS - (SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE person_id=pers.person_id) - THEN 'Mitarbeiter' - WHEN EXISTS - (SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_student ON(uid=student_uid) WHERE person_id=pers.person_id) - THEN 'Student' - ELSE 'Person' - END AS status"); - $this->ProjektbetreuerModel->addJoin('public.tbl_person pers', 'person_id'); - $result = $this->ProjektbetreuerModel->loadWhere(['projektarbeit_id' => $projektarbeit_id]); + $qry = " + SELECT * FROM ( + SELECT + projektarbeit_id, person_id, nachname, vorname, note, punkte, round(stunden, 1) AS stunden, + stundensatz, betreuerart_kurzbz, vertrag_id, titelpre, titelpost, + CASE + WHEN EXISTS + (SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE person_id=pers.person_id) + THEN 'Mitarbeiter' + WHEN EXISTS + (SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_student ON(uid=student_uid) WHERE person_id=pers.person_id) + THEN 'Student' + ELSE 'Person' + END AS status + FROM + lehre.tbl_projektbetreuer + JOIN public.tbl_person pers USING (person_id) + WHERE + projektarbeit_id = ? + ) betreuer + ORDER BY + CASE WHEN status = 'Mitarbeiter' THEN 0 WHEN status = 'Person' THEN 1 ELSE 2 END"; + + $result = $this->ProjektbetreuerModel->execReadOnlyQuery($qry, [$projektarbeit_id]); if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); @@ -86,6 +98,7 @@ class Projektbetreuer extends FHCAPI_Controller //~ } //~ } + // add thesis download link (from external extension) foreach ($projektbetreuer as $pb) { $downloadLink = null; @@ -104,6 +117,9 @@ class Projektbetreuer extends FHCAPI_Controller $this->terminateWithSuccess($this->_addFullNameToBetreuer($projektbetreuer)); } + /** + * Saves (adds or updates) a single Projektbetreuer for a Projektarbeit. + */ public function saveProjektbetreuer() { $projektarbeit_id = $this->input->post('projektarbeit_id'); @@ -118,14 +134,36 @@ class Projektbetreuer extends FHCAPI_Controller if ($this->_validate($projektbetreuer) == false) $this->terminateWithValidationErrors($this->form_validation->error_array()); + // check if assessor has already been assigned + if (isset($projektbetreuer['person_id'])) + { + $this->ProjektbetreuerModel->addSelect('1'); + $betreuerRes = $this->ProjektbetreuerModel->loadWhere( + [ + 'person_id' => $projektbetreuer['person_id'], + 'projektarbeit_id' => $projektbetreuer['projektarbeit_id'], + 'betreuerart_kurzbz' => $projektbetreuer['betreuerart_kurzbz'] + ] + ); + + if (hasData($betreuerRes) + && (!isset($projektbetreuer['person_id_old']) || $projektbetreuer['person_id'] != $projektbetreuer['person_id_old'])) { + return $this->terminateWithError($this->p->t('projektarbeit', 'betreuerZugewiesen'), self::ERROR_TYPE_GENERAL); + } + } + $result = null; + $stunden = isset($projektbetreuer['stunden']) && !isEmptyString($projektbetreuer['stunden']) ? $projektbetreuer['stunden'] : null; + $stundensatz = + isset($projektbetreuer['stundensatz']) && !isEmptyString($projektbetreuer['stundensatz']) ? $projektbetreuer['stundensatz'] : null; + $betreuer = [ 'projektarbeit_id' => $projektarbeit_id, 'person_id' => $projektbetreuer['person_id'], 'note' => $projektbetreuer['note'], - 'stunden' => $projektbetreuer['stunden'], - 'stundensatz' => $projektbetreuer['stundensatz'], + 'stunden' => $stunden, + 'stundensatz' => $stundensatz, 'betreuerart_kurzbz' => $projektbetreuer['betreuerart_kurzbz'] ]; @@ -152,6 +190,9 @@ class Projektbetreuer extends FHCAPI_Controller $this->terminateWithSuccess(hasData($result) ? getData($result) : []); } + /** + * Delete a Projektbetreuer assignment to a Projektarbeit. + */ public function deleteProjektbetreuer() { $projektarbeit_id = $this->input->post('projektarbeit_id'); @@ -159,21 +200,44 @@ class Projektbetreuer extends FHCAPI_Controller $betreuerart_kurzbz = $this->input->post('betreuerart_kurzbz'); if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id)) - return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> $this->p->t('projektarbeit', 'projektarbeit').' ID'], self::ERROR_TYPE_GENERAL)); + { + return $this->terminateWithError( + $this->p->t('ui', 'error_missingId', ['id'=> $this->p->t('projektarbeit', 'projektarbeit').' ID'], self::ERROR_TYPE_GENERAL) + ); + } if (!isset($person_id) || !is_numeric($person_id)) return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID'], self::ERROR_TYPE_GENERAL)); if (!isset($betreuerart_kurzbz)) - return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> $this->p->t('projektarbeit', 'betreuerart')], self::ERROR_TYPE_GENERAL)); + { + return $this->terminateWithError( + $this->p->t('ui', 'error_missingId', ['id'=> $this->p->t('projektarbeit', 'betreuerart')], self::ERROR_TYPE_GENERAL) + ); + } + // check permission if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id)) return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]); - $validate = $this->_validateDelete($projektarbeit_id, $person_id); + $validate = $this->_validateDelete($projektarbeit_id, $person_id, $betreuerart_kurzbz); if (isError($validate)) return $this->terminateWithError(getError($validate), self::ERROR_TYPE_GENERAL); + // check if there is a Projektarbeitsbeurteilung - if yes, it is handled (possibly deleted) by external extension. + $beurteilungDeleteSuccess = true; + + Events::trigger( + 'projektarbeitsbeurteilung_delete', + $projektarbeit_id, + function ($value) use (&$beurteilungDeleteSuccess) { + $beurteilungDeleteSuccess = $value; + } + ); + + // if there is still a Beurteilung, Projektarbeit cannot be deleted - return with error + if (!$beurteilungDeleteSuccess) return $this->terminateWithError($this->p->t('projektarbeit', 'error_paarbeitHatBeurteilung')); + $result = $this->ProjektbetreuerModel->delete( ['projektarbeit_id' => $projektarbeit_id, 'person_id' => $person_id, 'betreuerart_kurzbz' => $betreuerart_kurzbz] ); @@ -185,9 +249,12 @@ class Projektbetreuer extends FHCAPI_Controller $this->outputJson($result); } - return $this->terminateWithSuccess(current(getData($result)) ? : null); + return $this->terminateWithSuccess(getData($result)); } + /** + * Get all active Betreuerarten. + */ public function getBetreuerarten() { $result = $this->BetreuerartModel->loadWhere(['aktiv' => true]); @@ -197,6 +264,9 @@ class Projektbetreuer extends FHCAPI_Controller return $this->terminateWithSuccess(hasData($result) ? getData($result) : []); } + /** + * Get all Noten. + */ public function getNoten() { $result = $this->NoteModel->load(); @@ -206,6 +276,9 @@ class Projektbetreuer extends FHCAPI_Controller return $this->terminateWithSuccess(hasData($result) ? getData($result) : []); } + /** + * Get default Stundensätze for an employee in a semester. + */ public function getDefaultStundensaetze() { $person_id = $this->input->get('person_id'); @@ -216,6 +289,9 @@ class Projektbetreuer extends FHCAPI_Controller return $this->terminateWithSuccess($result); } + /** + * Get all Projektbetreuer by search string. + */ public function getProjektbetreuerBySearchQuery() { $searchString = $this->input->get('searchString'); @@ -227,9 +303,23 @@ class Projektbetreuer extends FHCAPI_Controller if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - return $this->terminateWithSuccess(hasData($result) ? $this->_addFullNameToBetreuer(getData($result)) : []); + if (!hasData($result)) $this->terminateWithSuccess([]); + + $persons = $this->_addFullNameToBetreuer(getData($result)); + + // sort persons by type (employees first) + usort($persons, function ($a, $b) { + $statusRanks = ['Mitarbeiter' => 0, 'Person' => 1, 'Student' => 2]; + return (isset($statusRanks[$a->status]) ? $statusRanks[$a->status] : count($statusRanks) + 1) + - (isset($statusRanks[$b->status]) ? $statusRanks[$b->status] : count($statusRanks) + 1); + }); + + return $this->terminateWithSuccess($persons); } + /** + * Get person info by Id. + */ public function getPerson() { $person_id = $this->input->get('person_id'); @@ -255,9 +345,7 @@ class Projektbetreuer extends FHCAPI_Controller } /** - * - * @param - * @return object success or error + * Validate list of Projektbetreuer. */ public function validateProjektbetreuer() { @@ -277,9 +365,9 @@ class Projektbetreuer extends FHCAPI_Controller } /** - * - * @param - * @return object success or error + * Validation funciton for checking Projektbetreuer input. + * @param $formData Betreuer data + * @return bool true when data is valid */ private function _validate($formData) { @@ -306,26 +394,32 @@ class Projektbetreuer extends FHCAPI_Controller } /** - * - * @param - * @return object success or error + * Check possibility of deletion of a Projektbetreuer. + * @param projektarbeit_id + * @param person_id + * @param betreuerart_kurzbz + * @return object success when delete possible, error otherwise */ - private function _validateDelete($projektarbeit_id, $person_id) + private function _validateDelete($projektarbeit_id, $person_id, $betreuerart_kurzbz) { + // check if contract exists $this->ProjektbetreuerModel->addSelect('vertrag_id'); - $result = $this->ProjektbetreuerModel->loadWhere(['projektarbeit_id' => $projektarbeit_id, 'person_id' => $person_id]); + $result = $this->ProjektbetreuerModel->loadWhere( + ['projektarbeit_id' => $projektarbeit_id, 'person_id' => $person_id, 'betreuerart_kurzbz' => $betreuerart_kurzbz] + ); if (isError($result)) return $result; + // if contract exists, no deletion is possible if (hasData($result) && getData($result)[0]->vertrag_id != null) return error($this->p->t('projektarbeit', 'error_betreuerHatVertrag')); return success(); } /** - * - * @param - * @return object success or error + * Add full name to array with Betreuer. + * @param $betreuerArr + * @return array including Betreuer with their full names */ private function _addFullNameToBetreuer($betreuerArr) { diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index 1ca2a18a8..414d1d1be 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -24,17 +24,28 @@ class Projektarbeit_model extends DB_Model public function getProjektarbeit($student_uid, $studiengang_kz = null, $studiensemester_kurzbz = null, $projekttyp = null, $final = null) { $qry = "SELECT - tbl_projektarbeit.*, tbl_projekttyp.bezeichnung, + pa.*, tbl_projekttyp.bezeichnung, tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.lehrveranstaltung_id, - tbl_firma.name AS firma_name + tbl_firma.name AS firma_name, + ( + SELECT + STRING_AGG(trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')), ', ') + FROM + lehre.tbl_projektbetreuer + JOIN public.tbl_person USING (person_id) + WHERE + projektarbeit_id = pa.projektarbeit_id + AND student_uid = pa.student_uid + GROUP BY projektarbeit_id + ) AS projektbetreuer FROM - lehre.tbl_projektarbeit + lehre.tbl_projektarbeit pa JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz) JOIN lehre.tbl_lehreinheit USING (lehreinheit_id) JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id) LEFT JOIN public.tbl_firma USING (firma_id) WHERE - tbl_projektarbeit.student_uid = ?"; + pa.student_uid = ?"; $params = array($student_uid); diff --git a/application/models/ressource/Stundensatz_model.php b/application/models/ressource/Stundensatz_model.php index c8ee367d8..2a7418924 100644 --- a/application/models/ressource/Stundensatz_model.php +++ b/application/models/ressource/Stundensatz_model.php @@ -47,7 +47,6 @@ class Stundensatz_model extends DB_Model { $this->load->config('stv'); - $useFixangestelltStundensatz = $this->config->item('tabs')['projektarbeit']['lvLektroinnenzuteilungFixangestelltStundensatz']; $defaultStundensatz = $this->config->item('tabs')['projektarbeit']['defaultProjektbetreuerStundensatz']; $stundensatz = ''; @@ -63,7 +62,7 @@ class Stundensatz_model extends DB_Model { $studiensemester = getData($result)[0]; - if (isset($useFixangestelltStundensatz) && !$useFixangestelltStundensatz) + if (defined('FAS_LV_LEKTORINNENZUTEILUNG_FIXANGESTELLT_STUNDENSATZ') && !FAS_LV_LEKTORINNENZUTEILUNG_FIXANGESTELLT_STUNDENSATZ) { // load Mitarbeiter $params = [$person_id]; @@ -83,19 +82,30 @@ class Stundensatz_model extends DB_Model if (hasData($result)) { - foreach (getData($result) as $ma) - { - if (!$ma->fixangestellt) - { - $stundensatzRes = $this->getStundensatzByDatum( - $ma->mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'lehre' - ); + $ma = getData($result)[0]; - if (hasData($stundensatzRes)) - $stundensatz = getData($stundensatzRes)[0]->stundensatz; - else - $stundensatz = '0.00'; - } + $this->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel'); + $echterdv_result = $this->DienstverhaeltnisModel->existsDienstverhaeltnis( + $ma->mitarbeiter_uid, + $studiensemester->start, + $studiensemester->ende, + 'echterdv' + ); + + if (hasData($echterdv_result)) + { + $stundensatz = null; + } + else + { + $stundensatzRes = $this->getStundensatzByDatum( + $ma->mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'lehre' + ); + + if (hasData($stundensatzRes)) + $stundensatz = getData($stundensatzRes)[0]->stundensatz; + else + $stundensatz = '0.00'; } } else diff --git a/public/js/api/factory/stv/projektarbeit.js b/public/js/api/factory/stv/projektarbeit.js index 4412f1842..e9b3e7efc 100644 --- a/public/js/api/factory/stv/projektarbeit.js +++ b/public/js/api/factory/stv/projektarbeit.js @@ -49,6 +49,12 @@ export default { url: 'api/frontend/v1/stv/projektarbeit/getNoten' }; }, + getStudiensemester() { + return { + method: 'get', + url: 'api/frontend/v1/stv/projektarbeit/getStudiensemester' + }; + }, loadProjektarbeit(projektarbeit_id) { return { method: 'get', diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js index 63b80ba37..34dd99c8f 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js @@ -69,10 +69,13 @@ export default { final: true, anmerkung: null }, + studiensemester: null, arrTypen: [], arrFirmen: [], arrLvs: [], arrNoten: [], + arrStudiensemester: [], + additional_lehrveranstaltung_id: null, filteredFirmen: [], abortController: { firma: null @@ -103,7 +106,11 @@ export default { this.formData.anmerkung = null; this.$refs.formDetails.clearValidation(); }, - getFormData(statusNew, studiensemester_kurzbz, additional_lehrveranstaltung_id) { + getFormData(newProjektarbeit, studiensemester_kurzbz, additional_lehrveranstaltung_id) { + + this.additional_lehrveranstaltung_id = additional_lehrveranstaltung_id; + this.studiensemester = studiensemester_kurzbz || this.defaultSemester; + this.newProjektarbeit = newProjektarbeit; this.$api .call(ApiStvProjektarbeit.getTypenProjektarbeit()) @@ -112,18 +119,7 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); - this.$api - .call(ApiStvProjektarbeit.getLehrveranstaltungen( - this.student.uid, - statusNew ? this.student.studiengang_kz : null, - studiensemester_kurzbz ?? this.defaultSemester, - additional_lehrveranstaltung_id - )) - .then(result => { - this.arrLvs = result.data - } - ) - .catch(this.$fhcAlert.handleSystemError); + this.getLehrveranstaltungen(); this.$api .call(ApiStvProjektarbeit.getNoten()) @@ -132,7 +128,14 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); - if (statusNew) this.resetForm(); + this.$api + .call(ApiStvProjektarbeit.getStudiensemester()) + .then(result => { + this.arrStudiensemester = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + if (this.newProjektarbeit) this.resetForm(); }, loadProjektarbeit(projektarbeit_id) { @@ -178,9 +181,30 @@ export default { this.filteredFirmen = result.data; }); }, + getLehrveranstaltungen() { + return this.$api + .call(ApiStvProjektarbeit.getLehrveranstaltungen( + this.student.uid, + this.newProjektarbeit ? this.student.studiengang_kz : null, + this.studiensemester, + this.additional_lehrveranstaltung_id + )) + .then(result => { + this.arrLvs = result.data + } + ) + .catch(this.$fhcAlert.handleSystemError); + }, lvChanged(event) { this.formData.lehreinheit_id = null; }, + studiensemesterChanged() { + this.formData.lehreinheit_id = null; + this.getLehrveranstaltungen(); + }, + gesperrtBisChanged(newSperrdatum) { + this.formData.freigegeben = newSperrdatum == null || newSperrdatum == ''; + }, // enrich and modify data before sending getPreparedFormData() { let preparedFormData = JSON.parse(JSON.stringify(this.formData)); // deep copy @@ -281,7 +305,7 @@ export default {
+ + + +
@@ -362,6 +403,7 @@ export default { format="dd.MM.yyyy" model-type="yyyy-MM-dd" name="gesperrtbis" + @update:model-value="gesperrtBisChanged" >
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektarbeit.js b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektarbeit.js index 084b5daad..57a18bf15 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektarbeit.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektarbeit.js @@ -47,16 +47,25 @@ export default { { event: 'tableBuilt', handler: async() => { - await this.$p.loadCategory(['global', 'person', 'stv', 'ui', 'projektarbeit']); + await this.$p.loadCategory(['global', 'person', 'lehre', 'stv', 'ui', 'projektarbeit']); let cm = this.$refs.table.tabulator.columnManager; cm.getColumnByField('projekttyp_kurzbz').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'typ_kurzbz') + }); + cm.getColumnByField('bezeichnung').component.updateDefinition({ title: this.$p.t('projektarbeit', 'typ') }); + cm.getColumnByField('studiensemester_kurzbz').component.updateDefinition({ + title: this.$p.t('lehre', 'studiensemester') + }); cm.getColumnByField('titel').component.updateDefinition({ title: this.$p.t('projektarbeit', 'titel') }); + cm.getColumnByField('note').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'gesamtnote') + }); cm.getColumnByField('beginn').component.updateDefinition({ title: this.$p.t('projektarbeit', 'beginn') }); @@ -78,6 +87,12 @@ export default { cm.getColumnByField('firma_id').component.updateDefinition({ title: this.$p.t('projektarbeit', 'firmaId') }); + cm.getColumnByField('abgabedatum').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'abgabeEndupload') + }); + cm.getColumnByField('actions').component.updateDefinition({ + title: this.$p.t('global', 'aktionen') + }); } }, ], @@ -101,6 +116,7 @@ export default { {title: "Typ Kurzbz", field: "projekttyp_kurzbz", visible: false}, {title: "Studiensemester", field: "studiensemester_kurzbz"}, {title: "Titel", field: "titel"}, + {title: "Gesamtnote", field: "note"}, { title: "Abgabe Enduplad", field: "abgabedatum", @@ -183,6 +199,7 @@ export default { {title: "Anmerkung", field: "anmerkung", visible: false}, {title: "Lehreinheit ID", field: "lehreinheit_id", visible: false}, {title: "Student UID", field: "student_uid", visible: false}, + {title: "Projektbetreuer", field: "projektbetreuer"}, { title:"Final", field:"final", @@ -258,7 +275,7 @@ export default { this.statusNew = true; this.editedProjektarbeit = null; this.toggleMenu('details'); - this.$refs.projektarbeitDetails.getFormData(this.statusNew); + this.$refs.projektarbeitDetails.getFormData(this.statusNew, null, null); this.$refs.projektarbeitModal.show(); }, actionEditProjektarbeit() { @@ -388,7 +405,7 @@ export default {
- +
diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektbetreuer.js b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektbetreuer.js index 696f18916..037aceb52 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektbetreuer.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektbetreuer.js @@ -20,6 +20,7 @@ export default { Contact, Vertrag }, + emits: ['betreuerSaved'], provide() { return { configShowVertragsdetails: this.config.showVertragsdetails @@ -131,7 +132,43 @@ export default { { event: 'tableBuilt', handler: async() => { - await this.$p.loadCategory(['global', 'person', 'stv', 'projektarbeit', 'ui']); + await this.$p.loadCategory(['global', 'person', 'lehre', 'stv', 'projektarbeit', 'ui']); + + let cm = this.$refs.projektbetreuerTable.tabulator.columnManager; + + cm.getColumnByField('nachname').component.updateDefinition({ + title: this.$p.t('person', 'nachname') + }); + cm.getColumnByField('vorname').component.updateDefinition({ + title: this.$p.t('person', 'vorname') + }); + cm.getColumnByField('note').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'note') + }); + cm.getColumnByField('punkte').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'titel') + }); + cm.getColumnByField('stunden').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'stunden') + }); + cm.getColumnByField('stundensatz').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'stundensatz') + }); + cm.getColumnByField('betreuerart_kurzbz').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'betreuerart_kurzbz') + }); + cm.getColumnByField('person_id').component.updateDefinition({ + title: this.$p.t('system', 'person_id') + }); + cm.getColumnByField('vertrag_id').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'vertrag_id') + }); + cm.getColumnByField('projektarbeit_id').component.updateDefinition({ + title: this.$p.t('projektarbeit', 'projektarbeit_id') + }); + cm.getColumnByField('actions').component.updateDefinition({ + title: this.$p.t('global', 'actions') + }); // Force layout recalculation for handling overflow text this.$refs.projektbetreuerTable.tabulator.redraw(true); @@ -152,6 +189,7 @@ export default { stunden: null, stundensatz: null }, + defaultStundensatz: null, newMode: false, editMode: false, initialFormData: null, @@ -171,53 +209,49 @@ export default { }, methods: { actionNewProjektbetreuer() { - this.resetForm(); this.newMode = !this.newMode; this.editMode = false; + this.resetForm(); + this.defaultStundensatz = this.config.defaultProjektbetreuerStundensatz; this.captureFormData(); }, actionEditProjektbetreuer(projektarbeit_id, person_id, betreuerart_kurzbz) { this.editMode = true; this.newMode = false; - this.$api - .call(ApiStvProjektbetreuer.getDefaultStundensaetze(person_id, this.studiensemester_kurzbz)) - .then(result => { - this.resetForm(); + this.resetForm(); + this.getDefaultStundensaetze(person_id).finally(() => { - // get betreuer from tabulator list - let projektbetreuerListe = this.$refs.projektbetreuerTable.tabulator.getData(); - const idx = projektbetreuerListe.findIndex( - betr => - betr.person_id === person_id && - betr.projektarbeit_id === projektarbeit_id && - betr.betreuerart_kurzbz === betreuerart_kurzbz - ); + // get betreuer from tabulator list + let projektbetreuerListe = this.$refs.projektbetreuerTable.tabulator.getData(); + const idx = projektbetreuerListe.findIndex( + betr => + betr.person_id === person_id && + betr.projektarbeit_id === projektarbeit_id && + betr.betreuerart_kurzbz === betreuerart_kurzbz + ); - if (idx >= 0) { // if betreuer found + if (idx >= 0) { // if betreuer found - // set currently edited betreuer (deep copy) - this.formData = JSON.parse(JSON.stringify(projektbetreuerListe[idx])); + // set currently edited betreuer (deep copy) + this.formData = JSON.parse(JSON.stringify(projektbetreuerListe[idx])); - // set download link - if (this.formData.beurteilungDownloadLink !== null) this.beurteilungDownloadLink = this.formData.beurteilungDownloadLink; + // set download link + if (this.formData.beurteilungDownloadLink !== null) this.beurteilungDownloadLink = this.formData.beurteilungDownloadLink; - // set betreuer for autocomplete field - this.autocompleteSelectedBetreuer = { - person_id: this.formData.person_id, - name: this.formData.name, - vorname: this.formData.vorname, - nachname: this.formData.nachname, - vertrag_id: this.formData.vertrag_id - }; - } + // set betreuer for autocomplete field + this.autocompleteSelectedBetreuer = { + person_id: this.formData.person_id, + name: this.formData.name, + vorname: this.formData.vorname, + nachname: this.formData.nachname, + vertrag_id: this.formData.vertrag_id + }; + } - // set default stundensatz (if no other is set yet) - if (this.formData.stundensatz == null) this.formData.stundensatz = result.data; + // capture initial form data for detecting changes + this.captureFormData(); + }); - // capture initial form data for detecting changes - this.captureFormData(); - }) - .catch(this.$fhcAlert.handleSystemError); }, actionDeleteProjektbetreuer(betreuer_id, projektarbeit_id, person_id, betreuerart_kurzbz) { this.$fhcAlert @@ -239,6 +273,7 @@ export default { // default Stundensätze from config this.defaultFormDataValues.stunden = this.getDefaultStunden(projekttyp_kurzbz); this.defaultFormDataValues.stundensatz = this.config.defaultProjektbetreuerStundensatz; + this.defaultStundensatz = this.config.defaultProjektbetreuerStundensatz; // get other initial data this.$api @@ -271,7 +306,7 @@ export default { }) .catch(this.$fhcAlert.handleSystemError); } else { - this.emptyBetreuer(); + this.emptyBetreuerList(); } }, saveProjektbetreuer() { @@ -282,6 +317,7 @@ export default { this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successSave')); this.getProjektbetreuer(this.projektarbeit_id, this.studiensemester_kurzbz); this.resetModes(); + this.$emit('betreuerSaved'); }) .catch(this.$fhcAlert.handleSystemError); }, @@ -297,11 +333,12 @@ export default { this.filteredBetreuer = result.data; }); }, - emptyBetreuer() { + emptyBetreuerList() { this.$refs.projektbetreuerTable.tabulator.clearData(); }, resetForm() { - this.formData = this.getDefaultFormData(); + const defaultFormData = this.getDefaultFormData(); + this.formData = defaultFormData; if (this.beurteilungDownloadLink !== null) this.beurteilungDownloadLink = ''; this.autocompleteSelectedBetreuer = null; this.initialFormData = null; @@ -360,25 +397,22 @@ export default { }, setDefaultStunden(projekttyp_kurzbz) { this.projekttyp_kurzbz = projekttyp_kurzbz; - // if form data has not already been modified by user, set the default stunden - if (!this.formDataModified()) { + // set default stunden if not in edit mode (so hours of editen person are not overwritten) + if (!this.editMode) + { let defaultStunden = this.getDefaultStunden(projekttyp_kurzbz); - // adapt initial form data so it does not count as modified - if (this.initialFormData) this.initialFormData.stunden = defaultStunden; - // set default Stunden this.formData.stunden = defaultStunden; } }, - // check if form data has been modified since initial data has been captured - formDataModified() { - if (this.autocompleteSelectedBetreuer != null) return true; - - for (const prop in this.initialFormData) { - if (typeof this.formData[prop] == 'undefined') return true; - if (this.formData[prop] != this.initialFormData[prop]) return true; - } - - return false; + getDefaultStundensaetze(person_id) { + return this.$api + .call(ApiStvProjektbetreuer.getDefaultStundensaetze(person_id, this.studiensemester_kurzbz)) + .then(result => { + // set default stundensatz (if no other is set yet) + this.defaultStundensatz = result.data; + this.formData.stundensatz = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); }, actionNewPerson() { this.$refs.newPersonModal.open(); @@ -394,12 +428,16 @@ export default { .then(response => { // set the new person in Betreuer autocomplete field this.autocompleteSelectedBetreuer = response.data; + this.getDefaultStundensaetze(this.autocompleteSelectedBetreuer.person_id); }) .catch(this.$fhcAlert.handleSystemError) }, // disable fields which are dependent on Vertrag status disableVertragFields(statusAkzeptiert) { this.vertragFieldsDisabled = statusAkzeptiert; + }, + onBetreuerSelected(ev) { + this.getDefaultStundensaetze(ev.value.person_id); } }, template: ` @@ -421,7 +459,7 @@ export default { > - +
@@ -501,7 +541,7 @@ export default { container-class="stv-details-projektarbeit-stundensatz" type="text" name="stundensatz" - :label="$p.t('projektarbeit', 'stundensatz')" + :label="$p.t('projektarbeit', 'stundensatz') + (defaultStundensatz ? ' (Default ' + defaultStundensatz + ')' : '')" :disabled="vertragFieldsDisabled" v-model="formData.stundensatz" > diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index ed50b0df1..7bd195064 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -85,6 +85,7 @@ require_once('dbupdate_3.4/66982_berufsschule.php'); require_once('dbupdate_3.4/40314_electronic_onboarding_anbindung_ida.php'); require_once('dbupdate_3.4/47972_pruefungsverwaltung_ects_angabe.php'); require_once('dbupdate_3.4/67490_studstatus_suche_abort_controller_haengt.php'); +require_once('dbupdate_3.4/69065_Projektarbeiten_Firmen_verwalten.php'); require_once('dbupdate_3.4/68744_StV_settings.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen diff --git a/system/dbupdate_3.4/69065_Projektarbeiten_Firmen_verwalten.php b/system/dbupdate_3.4/69065_Projektarbeiten_Firmen_verwalten.php new file mode 100644 index 000000000..52b546846 --- /dev/null +++ b/system/dbupdate_3.4/69065_Projektarbeiten_Firmen_verwalten.php @@ -0,0 +1,20 @@ +db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berechtigung_kurzbz = 'paarbeit/beurteilung_loeschen';")) +{ + if($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('paarbeit/beurteilung_loeschen', 'Berechtigung zum Löschen von Projektarbeitsbeurteilung');"; + + if(!$db->db_query($qry)) + { + echo 'system.tbl_berechtigung '.$db->db_last_error().'
'; + } + else + { + echo 'system.tbl_berechtigung: Added permission for paarbeit/beurteilung_loeschen
'; + } + } +} \ No newline at end of file diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 39ff6c2e5..b08d89b21 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -52245,6 +52245,186 @@ I have been informed that I am under no obligation to consent to the transmissio ) ) ), + array( + 'app' => 'core', + 'category' => 'projektarbeit', + 'phrase' => 'punkte', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Punkte', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'points', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'projektarbeit', + 'phrase' => 'gesamtnote', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Gesamtnote', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'final grade', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'projektarbeit', + 'phrase' => 'abgabeEndupload', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Abgabe Endupload', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'final submission upload', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'projektarbeit', + 'phrase' => 'vertrag_id', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Vertrag ID', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'contract ID', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'projektarbeit', + 'phrase' => 'projektarbeit_id', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Projektarbeit ID', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'project work ID', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'projektarbeit', + 'phrase' => 'betreuerart_kurzbz', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Betreuerart Kurzbezeichnung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'project assessor short name', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'projektarbeit', + 'phrase' => 'typ_kurzbz', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Typ Kurzbezeichnung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'type short name', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'projektarbeit', + 'phrase' => 'betreuerZugewiesen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Betreuer*In ist bereits zugewiesen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'This project assessor is already assigned', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'projektarbeit', + 'phrase' => 'error_paarbeitHatBeurteilung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Für diese Projektarbeit ist bereits eine Projektarbeitsbeurteilung eingetragen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'This project work has already been assessed', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), // FHC-4 Projektarbeiten & Vertraege ENDE // ### DOKUMENTE ERSTELLEN PHRASEN START ### array(