From ea2be8026b463c8cf9c7132197aea82831aa9886 Mon Sep 17 00:00:00 2001 From: ma0068 Date: Wed, 12 Mar 2025 08:06:23 +0100 Subject: [PATCH 01/88] filter hidden from kontakttyp, show typ.beschreibung in dropdown --- .../controllers/api/frontend/v1/stv/Kontakt.php | 15 ++++++++------- .../Details/Kontakt/Contact.js | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/application/controllers/api/frontend/v1/stv/Kontakt.php b/application/controllers/api/frontend/v1/stv/Kontakt.php index fd16fff06..1c3c0c95d 100644 --- a/application/controllers/api/frontend/v1/stv/Kontakt.php +++ b/application/controllers/api/frontend/v1/stv/Kontakt.php @@ -439,6 +439,7 @@ class Kontakt extends FHCAPI_Controller $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } $this->terminateWithSuccess((getData($result) ?: [])); + } public function getKontakttypen() @@ -446,13 +447,13 @@ class Kontakt extends FHCAPI_Controller $this->load->model('person/Kontakttyp_model', 'KontakttypModel'); $result = $this->KontakttypModel->load(); - if (isError($result)) { - $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - } - else - { - $this->terminateWithSuccess(getData($result) ?: []); - } + + $data = $this->getDataOrTerminateWithError($result); + + $filteredData = array_filter($data, function ($item) { + return $item->kontakttyp !== "hidden"; + }); + $this->terminateWithSuccess($filteredData); } public function loadContact() diff --git a/public/js/components/Stv/Studentenverwaltung/Details/Kontakt/Contact.js b/public/js/components/Stv/Studentenverwaltung/Details/Kontakt/Contact.js index 87dc70eb1..0bda648a9 100644 --- a/public/js/components/Stv/Studentenverwaltung/Details/Kontakt/Contact.js +++ b/public/js/components/Stv/Studentenverwaltung/Details/Kontakt/Contact.js @@ -322,7 +322,7 @@ export default{ v-model="contactData.kontakttyp"> > - + From f96bfbe0004a41312fb64d940bf9686329939a20 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Wed, 28 May 2025 07:51:10 +0200 Subject: [PATCH 02/88] =?UTF-8?q?lehrf=C3=A4cherverteilung=20v1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/controllers/LVVerwaltung.php | 42 + .../api/frontend/v1/Lehrveranstaltung.php | 243 ++++++ .../api/frontend/v1/lv/DirektGruppe.php | 108 +++ .../api/frontend/v1/lv/Favorites.php | 47 ++ .../controllers/api/frontend/v1/lv/Gruppe.php | 189 +++++ .../api/frontend/v1/lv/Lehreinheit.php | 438 +++++++++++ .../controllers/api/frontend/v1/lv/Lektor.php | 380 +++++++++ .../controllers/api/frontend/v1/lv/Setup.php | 116 +++ .../api/frontend/v1/lv/StgTree.php | 91 +++ .../controllers/api/frontend/v1/lv/Tags.php | 24 + .../frontend/v1/notiz/NotizLehreinheit.php | 21 + application/libraries/LektorLib.php | 342 +++++++++ .../models/accounting/Vertrag_model.php | 70 ++ .../models/education/Lehreinheit_model.php | 438 +++++++++++ .../education/Lehreinheitgruppe_model.php | 208 +++++ .../Lehreinheitmitarbeiter_model.php | 71 ++ .../education/Lehrveranstaltung_model.php | 225 ++++++ .../Organisationseinheit_model.php | 30 + .../models/organisation/Studienplan_model.php | 21 + application/models/person/Notiz_model.php | 54 +- .../models/ressource/Mitarbeiter_model.php | 14 + .../models/ressource/Stundenplandev_model.php | 83 ++ .../models/ressource/Stundensatz_model.php | 16 + .../Dienstverhaeltnis_model.php | 21 + application/views/LVVerwaltung.php | 39 + public/css/Lvverwaltung.css | 27 + public/js/api/factory/notiz.js | 5 +- public/js/api/factory/notiz/lehreinheit.js | 29 + public/js/api/lehrveranstaltung.js | 28 + public/js/api/lehrveranstaltung/details.js | 30 + .../js/api/lehrveranstaltung/direktgruppe.js | 26 + public/js/api/lehrveranstaltung/gruppe.js | 56 ++ .../js/api/lehrveranstaltung/lehreinheit.js | 41 + public/js/api/lehrveranstaltung/lektor.js | 78 ++ public/js/api/lehrveranstaltung/setup.js | 9 + .../api/lehrveranstaltung/studiengangtree.js | 43 ++ public/js/api/lehrveranstaltung/tag.js | 54 ++ public/js/api/lehrveranstaltung/vertrag.js | 22 + public/js/apps/LVVerwaltung.js | 46 ++ .../LVVerwaltung/Details/Direktinskription.js | 155 ++++ .../components/LVVerwaltung/Details/Form.js | 209 +++++ .../LVVerwaltung/Details/Gruppen.js | 195 +++++ .../components/LVVerwaltung/LVVerwaltung.js | 282 +++++++ .../components/LVVerwaltung/Lektor/Daten.js | 270 +++++++ .../components/LVVerwaltung/Lektor/Table.js | 223 ++++++ .../components/LVVerwaltung/Lektor/Vertrag.js | 161 ++++ .../js/components/LVVerwaltung/Setup/Table.js | 683 +++++++++++++++++ .../js/components/LVVerwaltung/Setup/Tabs.js | 62 ++ .../components/LVVerwaltung/Tabs/Details.js | 133 ++++ .../js/components/LVVerwaltung/Tabs/Lektor.js | 70 ++ .../js/components/LVVerwaltung/Tabs/Notiz.js | 33 + .../js/components/Stv/Studentenverwaltung.js | 4 +- .../Stv/Studentenverwaltung/Verband.js | 69 +- public/js/components/Tag/Tag.js | 12 +- .../tabulator/filters/extendedHeaderFilter.js | 110 ++- system/dbupdate_3.4.php | 1 + .../60882_lehrfaecherverteilung_favorites.php | 16 + system/phrasesupdate.php | 723 +++++++++++++++++- 58 files changed, 7146 insertions(+), 90 deletions(-) create mode 100644 application/controllers/LVVerwaltung.php create mode 100644 application/controllers/api/frontend/v1/Lehrveranstaltung.php create mode 100644 application/controllers/api/frontend/v1/lv/DirektGruppe.php create mode 100644 application/controllers/api/frontend/v1/lv/Favorites.php create mode 100644 application/controllers/api/frontend/v1/lv/Gruppe.php create mode 100644 application/controllers/api/frontend/v1/lv/Lehreinheit.php create mode 100644 application/controllers/api/frontend/v1/lv/Lektor.php create mode 100644 application/controllers/api/frontend/v1/lv/Setup.php create mode 100644 application/controllers/api/frontend/v1/lv/StgTree.php create mode 100644 application/controllers/api/frontend/v1/lv/Tags.php create mode 100644 application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php create mode 100644 application/libraries/LektorLib.php create mode 100644 application/views/LVVerwaltung.php create mode 100644 public/css/Lvverwaltung.css create mode 100644 public/js/api/factory/notiz/lehreinheit.js create mode 100644 public/js/api/lehrveranstaltung.js create mode 100644 public/js/api/lehrveranstaltung/details.js create mode 100644 public/js/api/lehrveranstaltung/direktgruppe.js create mode 100644 public/js/api/lehrveranstaltung/gruppe.js create mode 100644 public/js/api/lehrveranstaltung/lehreinheit.js create mode 100644 public/js/api/lehrveranstaltung/lektor.js create mode 100644 public/js/api/lehrveranstaltung/setup.js create mode 100644 public/js/api/lehrveranstaltung/studiengangtree.js create mode 100644 public/js/api/lehrveranstaltung/tag.js create mode 100644 public/js/api/lehrveranstaltung/vertrag.js create mode 100644 public/js/apps/LVVerwaltung.js create mode 100644 public/js/components/LVVerwaltung/Details/Direktinskription.js create mode 100644 public/js/components/LVVerwaltung/Details/Form.js create mode 100644 public/js/components/LVVerwaltung/Details/Gruppen.js create mode 100644 public/js/components/LVVerwaltung/LVVerwaltung.js create mode 100644 public/js/components/LVVerwaltung/Lektor/Daten.js create mode 100644 public/js/components/LVVerwaltung/Lektor/Table.js create mode 100644 public/js/components/LVVerwaltung/Lektor/Vertrag.js create mode 100644 public/js/components/LVVerwaltung/Setup/Table.js create mode 100644 public/js/components/LVVerwaltung/Setup/Tabs.js create mode 100644 public/js/components/LVVerwaltung/Tabs/Details.js create mode 100644 public/js/components/LVVerwaltung/Tabs/Lektor.js create mode 100644 public/js/components/LVVerwaltung/Tabs/Notiz.js create mode 100644 system/dbupdate_3.4/60882_lehrfaecherverteilung_favorites.php diff --git a/application/controllers/LVVerwaltung.php b/application/controllers/LVVerwaltung.php new file mode 100644 index 000000000..2a79d6375 --- /dev/null +++ b/application/controllers/LVVerwaltung.php @@ -0,0 +1,42 @@ +method] = ['admin:r', 'assistenz:r']; + parent::__construct($permissions); + + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + } + + /** + * @return void + */ + public function _remap() + { + $this->load->view('LVVerwaltung', [ + 'permissions' => [ + 'lehre/lehrveranstaltung' => $this->permissionlib->isBerechtigt('lehre/lehrveranstaltung'), + 'lv-plan/gruppenentfernen' => $this->permissionlib->isBerechtigt('lv-plan/gruppenentfernen'), + 'lv-plan/lektorentfernen' => $this->permissionlib->isBerechtigt('lv-plan/lektorentfernen'), + ], + 'variables' => [ + 'semester_aktuell' => $this->variablelib->getVar('semester_aktuell') + ], + 'configs' => [ + 'showVertragsdetails' => defined('FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN') && FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN, + 'showGewichtung' => defined('CIS_GESAMTNOTE_GEWICHTUNG') && CIS_GESAMTNOTE_GEWICHTUNG, + 'lehreinheitAnmerkungDefault' => defined('LEHREINHEIT_ANMERKUNG_DEFAULT') ? LEHREINHEIT_ANMERKUNG_DEFAULT : '', + 'lehreinheitRaumtypDefault' => defined('DEFAULT_LEHREINHEIT_RAUMTYP') ? DEFAULT_LEHREINHEIT_RAUMTYP : '', + 'lehreinheitRaumtypAlternativeDefault' => defined('DEFAULT_LEHREINHEIT_RAUMTYP_ALTERNATIV') ? DEFAULT_LEHREINHEIT_RAUMTYP_ALTERNATIV : '' + ] + ]); + + } +} diff --git a/application/controllers/api/frontend/v1/Lehrveranstaltung.php b/application/controllers/api/frontend/v1/Lehrveranstaltung.php new file mode 100644 index 000000000..1b2e2bc35 --- /dev/null +++ b/application/controllers/api/frontend/v1/Lehrveranstaltung.php @@ -0,0 +1,243 @@ +. + */ + +if (!defined('BASEPATH')) + exit('No direct script access allowed'); + +class Lehrveranstaltung extends FHCAPI_Controller +{ + private $_ci; + private $_uid; + + public function __construct() + { + parent::__construct([ + 'loadByEmployee' => ['admin:r', 'assistenz:r'], + 'loadByStudiengang' => ['admin:r', 'assistenz:r'], + 'loadByLV' => ['admin:r', 'assistenz:r'], + ]); + + $this->_ci = &get_instance(); + $this->_setAuthUID(); + + $this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + $this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $this->_ci->load->library('VariableLib', ['uid' => $this->_uid]); + } + public function loadByEmployee($mitarbeiter_uid = null, $stg_kz = null) + { + if (is_null($mitarbeiter_uid)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $studiensemester_kurzbz = $this->_ci->variablelib->getVar('semester_aktuell'); + + $lehrveranstaltungen = $this->_ci->LehreinheitModel->getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz); + $lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen); + + $tree = []; + + foreach ($lehrveranstaltungen_data as $lehrveranstaltung) + { + $lehreinheiten = $this->_ci->LehreinheitModel->getLEByLV($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz, $mitarbeiter_uid); + $lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten); + + if (!isset($lehrveranstaltung->_children)) + { + $lehrveranstaltung->_children = $lehreinheiten_data; + } + $tree[] = $lehrveranstaltung; + } + + $this->terminateWithSuccess($tree); + } + + public function loadByStudiengang($studiengang_kz = null, $semester = null) + { + if (is_null($studiengang_kz) || !ctype_digit((string)$studiengang_kz)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $verband = null; + if (!is_null($semester) && !is_numeric($semester)) + { + $verband = $semester; + $semester = null; + } + + $this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel'); + + $studiensemester_kurzbz = $this->_ci->variablelib->getVar('semester_aktuell'); + $studienplan_data = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $semester, $verband); + + $studienplan_ids = array(); + $only_ids = array(); + $placeholders = array(); + + if (hasData($studienplan_data)) + { + foreach (getData($studienplan_data) as $studienplan) { + $placeholders[] = "(?, ?)"; + $studienplan_ids[] = $studienplan->studienplan_id; + $studienplan_ids[] = $studienplan->semester; + $only_ids[] = $studienplan->studienplan_id; + } + } + + $lehrveranstaltungen_data = $this->_ci->LehrveranstaltungModel->getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester, $verband); + $lehrveranstaltungen_data = hasData($lehrveranstaltungen_data) ? getData($lehrveranstaltungen_data) : array(); + + + $tree = []; + foreach ($lehrveranstaltungen_data as $row) + { + $rowData = $row; + + $lehreinheiten_data = $this->_ci->LehreinheitModel->getByLvidStudiensemester($row->lehrveranstaltung_id, $studiensemester_kurzbz); + + if (hasData($lehreinheiten_data)) + { + $lehreinheiten = getData($lehreinheiten_data); + $rowData->_children = $lehreinheiten; + } + + if (!isEmptyString($row->studienplan_lehrveranstaltung_id_parent)) + { + $child = $this->_ci->StudienplanModel->loadStudienplanLehrveranstaltung($row->studienplan_lehrveranstaltung_id_parent); + + if (hasData($child)) + { + $child = getData($child)[0]; + $searchId = $child->lehrveranstaltung_id; + + foreach ($lehrveranstaltungen_data as &$searchParent) + { + if ($searchParent->lehrveranstaltung_id === $searchId) + { + if (!isset($searchParent->_children)) + { + $searchParent->_children = []; + } + + if (is_array($searchParent->_children)) + { + $searchParent->_children[] = $row; + } + else + { + $searchParent->_children = [$searchParent->_children, $row]; + } + break; + } + } + + } + } + else + { + $tree[] = $rowData; + } + } + + $counter = 0; + $this->assignUniqueIndex($tree, $counter); + $this->terminateWithSuccess($tree); + } + + + public function loadByLV($lehrveranstaltung_id = null) + { + if (is_null($lehrveranstaltung_id) || !ctype_digit((string)$lehrveranstaltung_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $this->_ci->LehrveranstaltungModel->addSelect('lehrveranstaltung_id, lehrform_kurzbz, lehre, bezeichnung as lvbezeichnung'); + $lehrveranstaltung_result = $this->_ci->LehrveranstaltungModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung_id)); + $lehrveranstaltung_result = $this->getDataOrTerminateWithError($lehrveranstaltung_result); + $lehrveranstaltung = $lehrveranstaltung_result[0]; + + $this->_ci->LehreinheitModel->addSelect('lehrveranstaltung_id_kompatibel'); + $this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung_kompatibel', 'lehrveranstaltung_id'); + $lehrfaecher = $this->_ci->LehreinheitModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung->lehrveranstaltung_id)); + + $lehrfaecher_array = []; + if (hasData($lehrfaecher)) + $lehrfaecher_array = array_merge($lehrfaecher_array, array_column(getData($lehrfaecher), 'lehrveranstaltung_id_kompatibel')); + + $lehrfaecher_array[] = $lehrveranstaltung->lehrveranstaltung_id; + + $this->_ci->LehrveranstaltungModel->addDistinct('lehrfach_id'); + $this->_ci->LehrveranstaltungModel->addSelect("tbl_lehrveranstaltung.lehrveranstaltung_id, CONCAT(tbl_lehrveranstaltung.bezeichnung || '(' || tbl_lehrveranstaltung.oe_kurzbz || ')') as lehrfach"); + $this->_ci->LehrveranstaltungModel->db->where_in('tbl_lehrveranstaltung.lehrveranstaltung_id', $lehrfaecher_array); + $lehrfaecher_result = $this->_ci->LehrveranstaltungModel->load(); + + $lehrfaecher_array = hasData($lehrfaecher_result) ? getData($lehrfaecher_result) : array(); + + $lehrveranstaltung->lehrfaecher = $lehrfaecher_array; + $this->terminateWithSuccess($lehrveranstaltung); + } + + /* + * (david) ggf. im naechsten release + * public function loadByOrganization($oe_kurzbz) + { + $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); + + $lehrveranstaltungen = $this->LehrveranstaltungModel->getLvsByOrganization($oe_kurzbz); + $lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen); + $tree = []; + + foreach ($lehrveranstaltungen_data as $lehrveranstaltung) + { + $lehreinheiten = $this->LehreinheitModel->getLEByLV($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz); + $lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten); + + if (!isset($lehrveranstaltung->_children)) + { + + $lehrveranstaltung->_children = $lehreinheiten_data; + } + $tree[] = $lehrveranstaltung; + } + $this->terminateWithSuccess($tree); + }*/ + + /*public function loadByFachbereich($fachbereich, $mitarbeiter_uid = null) + { + $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); + + $this->LehreinheitModel->getLvsByFachbereich($fachbereich, $studiensemester_kurzbz, $mitarbeiter_uid); + }*/ + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) + show_error('User authentification failed'); + } + + private function assignUniqueIndex(&$nodes, &$counter) + { + foreach ($nodes as &$node) + { + $node->uniqueindex = $counter++; + if (!empty($node->_children) && is_array($node->_children)) + { + $this->assignUniqueIndex($node->_children, $counter); + } + } + } +} diff --git a/application/controllers/api/frontend/v1/lv/DirektGruppe.php b/application/controllers/api/frontend/v1/lv/DirektGruppe.php new file mode 100644 index 000000000..fe1737f6a --- /dev/null +++ b/application/controllers/api/frontend/v1/lv/DirektGruppe.php @@ -0,0 +1,108 @@ +. + */ + +if (!defined('BASEPATH')) + exit('No direct script access allowed'); + +class DirektGruppe extends FHCAPI_Controller +{ + private $_ci; + public function __construct() + { + parent::__construct([ + 'add' => ['admin:rw', 'assistenz:rw'], + 'delete' => ['admin:rw', 'assistenz:rw'], + 'getByLehreinheit' => ['admin:r', 'assistenz:r'], + ]); + + $this->_ci = &get_instance(); + + $this->loadPhrases([ + 'ui' + ]); + $this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel'); + $this->_ci->load->model('education/lehreinheit_model', 'LehreinheitModel'); + $this->_ci->load->model('person/Benutzer_model', 'BenutzerModel'); + } + + public function add() + { + $uid = $this->input->post('uid'); + $lehreinheit_id = $this->input->post('lehreinheit_id'); + + $this->checkPermission($lehreinheit_id, $uid); + + $result = $this->_ci->LehreinheitgruppeModel->direktUserAdd($uid, $lehreinheit_id); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess($result); + } + + public function delete() + { + $uid = $this->input->post('uid'); + $lehreinheit_id = $this->input->post('lehreinheit_id'); + + $this->checkPermission($lehreinheit_id, $uid); + + $result = $this->_ci->LehreinheitgruppeModel->direktUserDelete($uid, $lehreinheit_id); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess($result); + } + + public function getByLehreinheit($lehreinheit_id = null) + { + $this->checkPermission($lehreinheit_id); + $gruppen = $this->_ci->LehreinheitgruppeModel->getDirectGroup($lehreinheit_id); + $this->terminateWithSuccess(hasData($gruppen) ? getData($gruppen) : array()); + } + + private function checkPermission($lehreinheit_id, $uid = false) + { + if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id); + + if (!hasData($lehreinheit_result) || isError($lehreinheit_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + if ($uid) + { + $benuzuer_result = $this->_ci->BenutzerModel->load(array($uid)); + if (!hasData($benuzuer_result) || isError($benuzuer_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + } + + $result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id); + + if (isError($result)) + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + + $oe_array = $result; + + if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') && + !$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid')) + $this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess')); + } +} diff --git a/application/controllers/api/frontend/v1/lv/Favorites.php b/application/controllers/api/frontend/v1/lv/Favorites.php new file mode 100644 index 000000000..080a4ec6e --- /dev/null +++ b/application/controllers/api/frontend/v1/lv/Favorites.php @@ -0,0 +1,47 @@ + self::PERM_LOGGED, + 'set' => self::PERM_LOGGED + ]); + + // Load models + $this->load->model('system/Variable_model', 'VariableModel'); + } + + public function index() + { + $result = $this->VariableModel->getVariables(getAuthUID(), ['lv_favorites']); + + $data = $this->getDataOrTerminateWithError($result); + + if (!$data) + $this->terminateWithSuccess(null); + else + $this->terminateWithSuccess(isset($data['lv_favorites']) ? $data['lv_favorites'] : null); + } + + public function set() + { + $this->load->library('form_validation'); + + $this->form_validation->set_rules('favorites', 'Favorites', 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $favorites = $this->input->post('favorites'); + + $result = $this->VariableModel->setVariable(getAuthUID(), 'lv_favorites', $favorites); + + $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(true); + } +} diff --git a/application/controllers/api/frontend/v1/lv/Gruppe.php b/application/controllers/api/frontend/v1/lv/Gruppe.php new file mode 100644 index 000000000..01c11f98f --- /dev/null +++ b/application/controllers/api/frontend/v1/lv/Gruppe.php @@ -0,0 +1,189 @@ + ['admin:rw', 'assistenz:rw'], + 'delete' => ['admin:rw', 'assistenz:rw'], + 'deleteFromLVPlan' => ['admin:rw', 'assistenz:rw'], + 'getBenutzer' => ['admin:r', 'assistenz:r'], + 'getAll' => ['admin:r', 'assistenz:r'], + 'getByLehreinheit' => ['admin:r', 'assistenz:r'], + ]); + + $this->_ci = &get_instance(); + $this->_setAuthUID(); + $this->_ci->load->model('organisation/Gruppe_model', 'GruppeModel'); + $this->_ci->load->model('organisation/Lehrverband_model', 'LehrverbandModel'); + $this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel'); + $this->_ci->load->model('person/Person_model', 'PersonModel'); + $this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel'); + } + + public function delete() + { + $lehreinheitgruppe_id = $this->input->post('lehreinheitgruppe_id'); + $lehreinheit_id = $this->input->post('lehreinheit_id'); + + if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($lehreinheitgruppe_id) || !ctype_digit((string)$lehreinheitgruppe_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $lehreinheitgruppe_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheitgruppe_id' => $lehreinheitgruppe_id)); + if (!hasData($lehreinheitgruppe_result) || isError($lehreinheitgruppe_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $this->checkPermission($lehreinheit_id); + + $result = $this->_ci->LehreinheitgruppeModel->deleteGroup($lehreinheit_id, $lehreinheitgruppe_id); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess($result); + } + + public function add() + { + $lehreinheit_id = $this->input->post('lehreinheit_id'); + $gid = $this->input->post('gid'); + $lehrverband = $this->input->post('lehrverband'); + + if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($gid) || !ctype_digit((string)$gid) || is_null($lehrverband)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $gruppe_result = $this->_ci->GruppeModel->loadWhere(array('gid' => $gid)); + if (!hasData($gruppe_result) || isError($gruppe_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $this->checkPermission($lehreinheit_id); + + $result = $this->_ci->LehreinheitgruppeModel->addGroup($lehreinheit_id, $gid, !($lehrverband === 'false')); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess($result); + } + + public function getByLehreinheit($lehreinheit_id = null) + { + if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $this->checkPermission($lehreinheit_id); + + $gruppen = $this->_ci->LehreinheitgruppeModel->getByLehreinheit($lehreinheit_id); + $this->terminateWithSuccess(hasData($gruppen) ? getData($gruppen) : array()); + } + + public function deleteFromLVPlan() + { + $lehreinheit_id = $this->input->post('lehreinheit_id'); + $lehreinheitgruppe_id = $this->input->post('lehreinheitgruppe_id'); + + if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($lehreinheitgruppe_id) || !ctype_digit((string)$lehreinheitgruppe_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $lehreinheitgruppe_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheitgruppe_id' => $lehreinheitgruppe_id)); + if (!hasData($lehreinheitgruppe_result) || isError($lehreinheitgruppe_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $this->checkPermission($lehreinheit_id); + + $result = $this->_ci->StundenplandevModel->deleteGroupPlanning($lehreinheit_id, $lehreinheitgruppe_id); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess($result); + } + + + public function getAll() + { + $this->_ci->GruppeModel->addSelect('gruppe_kurzbz, + studiengang_kz, + semester, + bezeichnung, + gid, + \'false\' as lehrverband'); + $gruppen_result = $this->_ci->GruppeModel->loadWhere(array('sichtbar' => true, 'aktiv' => true, 'lehre' => true, 'direktinskription' => false)); + + $gruppen_array = array(); + + if (isError($gruppen_result)) + $this->terminateWithError(getError($gruppen_result), self::ERROR_TYPE_GENERAL); + + if (hasData($gruppen_result)) + $gruppen_array = getData($gruppen_result); + + $this->_ci->LehrverbandModel->addSelect('CONCAT(UPPER(CONCAT(typ, kurzbz)), \'\', semester, verband, COALESCE(gruppe,\'\')) as gruppe_kurzbz, + studiengang_kz, + semester, + tbl_lehrverband.bezeichnung, + gid, + \'true\' as lehrverband'); + $this->_ci->LehrverbandModel->addJoin('public.tbl_studiengang', 'studiengang_kz'); + $this->_ci->LehrverbandModel->addOrder('verband'); + $this->_ci->LehrverbandModel->addOrder('gruppe'); + $lehrverband_result = $this->_ci->LehrverbandModel->loadWhere(array('tbl_lehrverband.aktiv' => true)); + + $lehrverband_array = array(); + + if (isError($lehrverband_result)) + $this->terminateWithError(getError($lehrverband_result), self::ERROR_TYPE_GENERAL); + + if (hasData($lehrverband_result)) + $lehrverband_array = getData($lehrverband_result); + + $all_gruppen = array_merge($gruppen_array, $lehrverband_array); + + $this->terminateWithSuccess($all_gruppen); + } + + public function getBenutzer() + { + $this->_ci->PersonModel->addSelect('vorname, nachname, uid, semester, UPPER(CONCAT(tbl_studiengang.typ, tbl_studiengang.kurzbz)) as studiengang'); + $this->_ci->PersonModel->addJoin('public.tbl_benutzer', 'person_id'); + $this->_ci->PersonModel->addJoin('public.tbl_mitarbeiter', 'uid = mitarbeiter_uid', 'LEFT'); + $this->_ci->PersonModel->addJoin('public.tbl_student', 'uid = student_uid', 'LEFT'); + $this->_ci->PersonModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT'); + + $personen = $this->_ci->PersonModel->loadWhere(array('tbl_benutzer.aktiv' => true)); + $this->terminateWithSuccess(hasData($personen) ? getData($personen) : array()); + } + + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) + show_error('User authentification failed'); + } + + private function checkPermission($lehreinheit_id) + { + $lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id); + + if (!hasData($lehreinheit_result) || isError($lehreinheit_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id); + + if (isError($result)) + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $oe_array = $result; + + if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') && + !$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') && + !$this->_ci->permissionlib->isBerechtigtMultipleOe('lv-plan', $oe_array, 'suid')) + $this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess')); + } + +} diff --git a/application/controllers/api/frontend/v1/lv/Lehreinheit.php b/application/controllers/api/frontend/v1/lv/Lehreinheit.php new file mode 100644 index 000000000..84ee66d5d --- /dev/null +++ b/application/controllers/api/frontend/v1/lv/Lehreinheit.php @@ -0,0 +1,438 @@ + ['admin:rw', 'assistenz:rw'], + 'copy' => ['admin:rw', 'assistenz:rw'], + 'delete' => ['admin:rw', 'assistenz:rw'], + 'update' => ['admin:rw', 'assistenz:rw'], + + 'get' => ['admin:r', 'assistenz:r'], + 'getStudiensemester' => ['admin:r', 'assistenz:r'], + 'getLehrfach' => ['admin:r', 'assistenz:r'], + 'getSprache' => ['admin:r', 'assistenz:r'], + 'getRaumtyp' => ['admin:r', 'assistenz:r'], + 'getLehrform' => ['admin:r', 'assistenz:r'] + ]); + + $this->_ci = &get_instance(); + $this->_setAuthUID(); + $this->_ci->load->library('VariableLib', ['uid' => $this->_uid]); + $this->_ci->load->library('PhrasesLib'); + $this->loadPhrases( + array( + 'global', + 'ui' + ) + ); + + $this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + $this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel'); + $this->_ci->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel'); + } + + public function get($lehreinheit_id) + { + $lehreinheit = $this->checkLehreinheit($lehreinheit_id); + $lehreinheit->lehrfaecher = $this->getLehrfaecher($lehreinheit); + $this->terminateWithSuccess($lehreinheit); + } + + private function getLehrfaecher($lehreinheit) + { + $lehrfacher_array = array($lehreinheit->lehrfach_id); + $this->_ci->LehreinheitModel->addSelect('lehrveranstaltung_id_kompatibel'); + $this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung_kompatibel', 'lehrveranstaltung_id'); + $lehrfaecher = $this->_ci->LehreinheitModel->loadWhere(array('lehrveranstaltung_id' => $lehreinheit->lehrveranstaltung_id)); + + + if (hasData($lehrfaecher)) + $lehrfaecher_array = array_merge($lehrfacher_array, array_column(getData($lehrfaecher), 'lehrveranstaltung_id_kompatibel')); + + $lehrfaecher_array[] = $lehreinheit->lehrveranstaltung_id; + + $this->_ci->LehrveranstaltungModel->addDistinct('lehrfach_id'); + $this->_ci->LehrveranstaltungModel->addSelect("tbl_lehrveranstaltung.lehrveranstaltung_id, CONCAT(tbl_lehrveranstaltung.bezeichnung || '(' || tbl_lehrveranstaltung.oe_kurzbz || ')') as lehrfach"); + $this->_ci->LehrveranstaltungModel->db->where_in('tbl_lehrveranstaltung.lehrveranstaltung_id', $lehrfaecher_array); + $lehrfaecher_result = $this->_ci->LehrveranstaltungModel->load(); + + return hasData($lehrfaecher_result) ? getData($lehrfaecher_result) : array(); + } + + public function add() + { + $lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id'); + + if (is_null($lehrveranstaltung_id) || !ctype_digit((string)$lehrveranstaltung_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $lehrveranstaltung_result = $this->_ci->LehrveranstaltungModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung_id)); + + if (!hasData($lehrveranstaltung_result) || isError($lehrveranstaltung_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $lehrveranstaltung = getData($lehrveranstaltung_result)[0]; + + $oe_result = $this->_ci->LehrveranstaltungModel->getAllOe($lehrveranstaltung->lehrveranstaltung_id, $lehrveranstaltung->studiengang_kz); + $oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array(); + + if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') && + !$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') && + !$this->_ci->permissionlib->isBerechtigtMultipleOe('lv-plan', $oe_array, 'suid')) + $this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess')); + + $this->_ci->load->library('form_validation'); + + $updatableFields = array( + 'lehrveranstaltung_id', + 'studiensemester_kurzbz', + 'lehrfach_id', + 'lehrform_kurzbz', + 'stundenblockung', + 'wochenrythmus', + 'gewicht', + 'start_kw', + 'raumtyp', + 'raumtypalternativ', + 'sprache', + 'lehre', + 'anmerkung', + 'lvnr', + 'unr', + ); + + foreach ($updatableFields as $field) + { + switch ($field) { + case 'lehrveranstaltung_id': + $this->form_validation->set_rules($field, 'Lehrveranstaltung ID', 'required|integer'); + break; + case 'studiensemester_kurzbz': + $this->form_validation->set_rules($field, 'Studiensemester', 'required|max_length[16]'); + break; + case 'lehrfach_id': + $this->form_validation->set_rules($field, 'Lehrfach ID', 'required|integer'); + break; + case 'lehrform_kurzbz': + $this->form_validation->set_rules($field, 'Lehrform', 'required|max_length[8]'); + break; + case 'stundenblockung': + $this->form_validation->set_rules($field, 'Stundenblockung', 'required|integer|greater_than_equal_to[0]'); + break; + case 'wochenrythmus': + $this->form_validation->set_rules($field, 'Wochenrhytmus', 'required|integer|greater_than_equal_to[0]'); + break; + case 'start_kw': + $this->form_validation->set_rules($field, 'Start KW', 'integer|greater_than[0]|less_than_equal_to[53]'); + break; + case 'gewicht': + $this->form_validation->set_rules($field, 'Gewicht', 'numeric'); + break; + case 'raumtyp': + $this->form_validation->set_rules($field, 'Raumtyp', 'required|max_length[16]'); + break; + case 'raumtypalternativ': + $this->form_validation->set_rules($field, 'Raumtyp Alternativ', 'required|max_length[16]'); + break; + case 'sprache': + $this->form_validation->set_rules($field, 'Sprache', 'required|max_length[16]'); + break; + case 'lvnr': + $this->form_validation->set_rules($field, 'LVNR', 'integer'); + break; + case 'unr': + $this->form_validation->set_rules($field, 'UNR', 'integer'); + break; + case 'lehre': + $this->form_validation->set_rules($field, 'Lehre', 'trim'); + break; + case 'anmerkung': + $this->form_validation->set_rules($field, 'Anmerkung', 'trim'); + break; + } + } + + if ($this->form_validation->run() === false) + { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + + $updateData = array(); + foreach ($updatableFields as $field) + { + $value = $this->input->post($field); + + if ($value !== null) + { + $updateData[$field] = $value; + } + } + + $updateData['insertvon'] = $this->_uid; + $updateData['insertamum'] = date('Y-m-d H:i:s'); + + $result = $this->_ci->LehreinheitModel->insert( + $updateData + ); + + $this->terminateWithSuccess($result); + } + + public function copy() + { + $lehreinheit_id = $this->input->post('lehreinheit_id'); + $art = $this->input->post('art'); + + $lehreinheit_old = $this->checkLehreinheit($lehreinheit_id); + $this->checkPermission($lehreinheit_old->lehreinheit_id); + + $lehreinheit_new = $lehreinheit_old; + + $lehreinheit_new->unr = null; + unset($lehreinheit_new->lehreinheit_id); + $lehreinheit_new->updateamum = date('Y-m-d H:i:s'); + $lehreinheit_new->updatevon = $this->_uid; + $lehreinheit_new->insertamum = date('Y-m-d H:i:s'); + $lehreinheit_new->insertvon = $this->_uid; + + $insert_result = $this->_ci->LehreinheitModel->insert($lehreinheit_new); + + if (isError($insert_result)) + $this->terminateWithError(getError($insert_result), self::ERROR_TYPE_GENERAL); + + $lehreinheit_id_new = getData($insert_result); + + if (in_array($art, array('gruppen', 'alle'))) + { + $gruppen_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + + if (isError($gruppen_result)) + $this->terminateWithError(getError($gruppen_result), self::ERROR_TYPE_GENERAL); + + if (hasData($gruppen_result)) + { + $gruppen = getData($gruppen_result); + + foreach ($gruppen as $gruppe) + { + $gruppe_new = $gruppe; + unset($gruppe_new->lehreinheitgruppe_id); + $gruppe_new->lehreinheit_id = $lehreinheit_id_new; + $gruppe_new->insertamum = date('Y-m-d H:i:s'); + $gruppe_new->insertvon = $this->_uid; + $gruppe_new->updateamum = date('Y-m-d H:i:s'); + $gruppe_new->updatevon = $this->_uid; + + $gruppe_new_result = $this->_ci->LehreinheitgruppeModel->insert($gruppe_new); + + if (isError($gruppe_new_result)) + $this->terminateWithError(getError($gruppe_new_result), self::ERROR_TYPE_GENERAL); + } + } + } + + if (in_array($art, array('lektoren', 'alle'))) + { + $lektoren_result = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + + if (isError($lektoren_result)) + $this->terminateWithError(getError($lektoren_result), self::ERROR_TYPE_GENERAL); + + if (hasData($lektoren_result)) + { + $lektoren = getData($lektoren_result); + + foreach ($lektoren as $lektor) + { + + $lektor_new = $lektor; + $lektor_new->lehreinheit_id = $lehreinheit_id_new; + $lektor_new->insertamum = date('Y-m-d H:i:s'); + $lektor_new->insertvon = $this->_uid; + $lektor_new->updateamum = date('Y-m-d H:i:s'); + $lektor_new->updatevon = $this->_uid; + unset($lektor_new->vertrag_id); + + $lektor_new_result = $this->_ci->LehreinheitmitarbeiterModel->insert((array)$lektor_new); + + if (isError($lektor_new_result)) + $this->terminateWithError(getError($lektor_new_result), self::ERROR_TYPE_GENERAL); + } + } + } + + $this->terminateWithSuccess("Erfolgeich gespeichert"); + } + + public function delete() + { + $lehreinheit_id = $this->input->post('lehreinheit_id'); + $lehreinheit = $this->checkLehreinheit($lehreinheit_id); + $this->checkPermission($lehreinheit->lehreinheit_id); + + $result = $this->_ci->LehreinheitModel->deleteLehreinheit($lehreinheit->lehreinheit_id); + + if (isError($result)) + $this->terminateWithValidationErrors(getError($result)); + + $this->terminateWithSuccess('Erfolgreich geloescht'); + } + + public function update() + { + $lehreinheit = $this->checkLehreinheit($this->input->post('lehreinheit_id')); + + $this->checkPermission($lehreinheit->lehreinheit_id); + + $this->_ci->load->library('form_validation'); + + $formData = $this->input->post('formData'); + + $updatableFields = array( + 'lehrveranstaltung_id', + 'studiensemester_kurzbz', + 'lehrfach_id', + 'lehrform_kurzbz', + 'stundenblockung', + 'wochenrythmus', + 'gewicht', + 'start_kw', + 'raumtyp', + 'raumtypalternativ', + 'sprache', + 'lehre', + 'anmerkung', + 'lvnr', + 'unr', + ); + + $this->form_validation->set_data($formData); + + foreach ($updatableFields as $field) + { + if (array_key_exists($field, $formData)) + { + switch ($field) + { + case 'lehrveranstaltung_id': + $this->form_validation->set_rules($field, 'Lehrveranstaltung ID', 'required|integer'); + break; + case 'studiensemester_kurzbz': + $this->form_validation->set_rules($field, 'Studiensemester', 'required|max_length[16]'); + break; + case 'lehrfach_id': + $this->form_validation->set_rules($field, 'Lehrfach ID', 'required|integer'); + break; + case 'lehrform_kurzbz': + $this->form_validation->set_rules($field, 'Lehrform', 'required|max_length[8]'); + break; + case 'stundenblockung': + $this->form_validation->set_rules($field, 'Stundenblockung', 'required|integer|greater_than_equal_to[0]'); + break; + case 'wochenrythmus': + $this->form_validation->set_rules($field, 'Wochenrhytmus', 'required|integer|greater_than_equal_to[0]'); + break; + case 'start_kw': + $this->form_validation->set_rules($field, 'Start KW', 'integer|greater_than[0]|less_than_equal_to[53]'); + break; + case 'gewicht': + $this->form_validation->set_rules($field, 'Gewicht', 'numeric'); + break; + case 'raumtyp': + $this->form_validation->set_rules($field, 'Raumtyp', 'required|max_length[16]'); + break; + case 'raumtypalternativ': + $this->form_validation->set_rules($field, 'Raumtyp Alternativ', 'required|max_length[16]'); + break; + case 'sprache': + $this->form_validation->set_rules($field, 'Sprache', 'required|max_length[16]'); + break; + case 'lvnr': + $this->form_validation->set_rules($field, 'LVNR', 'integer'); + break; + case 'unr': + $this->form_validation->set_rules($field, 'UNR', 'integer'); + break; + case 'lehre': + $this->form_validation->set_rules($field, 'Lehre', 'trim'); + break; + case 'anmerkung': + $this->form_validation->set_rules($field, 'Anmerkung', 'trim'); + break; + } + } + } + + if ($this->form_validation->run() === false) + { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + $updateData = []; + foreach ($updatableFields as $field) + { + if (array_key_exists($field, $formData)) + { + $updateData[$field] = $formData[$field]; + } + } + + + $updateData['updatevon'] = $this->_uid; + $updateData['updateamum'] = date('Y-m-d H:i:s'); + $result = $this->_ci->LehreinheitModel->update( + [ + 'lehreinheit_id' => $this->input->post('lehreinheit_id'), + ], + $updateData + ); + + if (isError($result)) + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithSuccess($this->p->t('global', 'gespeichert')); + } + + + private function checkPermission($lehreinheit_id) + { + $result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id); + + if (isError($result)) + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + + $oe_array = $result; + + if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') && + !$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') && + !$this->_ci->permissionlib->isBerechtigtMultipleOe('lv-plan', $oe_array, 'suid')) + $this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess')); + } + private function checkLehreinheit($lehreinheit_id) + { + if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id); + + if (!hasData($lehreinheit_result) || isError($lehreinheit_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + return getData($lehreinheit_result)[0]; + } + + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) + show_error('User authentification failed'); + } +} diff --git a/application/controllers/api/frontend/v1/lv/Lektor.php b/application/controllers/api/frontend/v1/lv/Lektor.php new file mode 100644 index 000000000..332bc47b6 --- /dev/null +++ b/application/controllers/api/frontend/v1/lv/Lektor.php @@ -0,0 +1,380 @@ + ['admin:rw', 'assistenz:rw'], + 'update' => ['admin:rw', 'assistenz:rw'], + 'cancelVertrag' => ['admin:rw', 'assistenz:rw'], + 'deleteLVPlan' => ['admin:rw', 'assistenz:rw'], + 'deletePerson' => ['admin:rw', 'assistenz:rw'], + 'getLehrfunktionen' => ['admin:r', 'assistenz:r'], + 'getLektoren' => ['admin:r', 'assistenz:r'], + 'getLektorenByLE' => ['admin:r', 'assistenz:r'], + 'getLektorDaten' => ['admin:r', 'assistenz:r'], + 'getLektorVertrag' => ['admin:r', 'assistenz:r'], + + ]); + + $this->_ci = &get_instance(); + $this->_setAuthUID(); + $this->_ci->load->library('VariableLib', ['uid' => $this->_uid]); + $this->_ci->load->library('PermissionLib'); + $this->_ci->load->library('LektorLib'); + $this->_ci->load->library('form_validation'); + $this->loadPhrases([ + 'ui' + ]); + + $this->_ci->load->model('accounting/Vertrag_model', 'VertragModel'); + $this->_ci->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + $this->_ci->load->model('education/lehreinheit_model', 'LehreinheitModel'); + $this->_ci->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel'); + $this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel'); + $this->_ci->load->model('ressource/Stundensatz_model', 'StundensatzModel'); + + } + + private function checkMitarbeiter($mitarbeiter_uid) + { + if (is_null($mitarbeiter_uid)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid); + + if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + } + + public function add() + { + $lehreinheit_id = $this->input->post('lehreinheit_id'); + $mitarbeiter_uid = $this->input->post('mitarbeiter_uid'); + + $this->checkLehreinheit($lehreinheit_id); + $this->checkMitarbeiter($mitarbeiter_uid); + $lehrfach_permission = $this->checkLehrfachPermission($lehreinheit_id, array('assistenz', 'admin')); + $lehreinheit_permission = $this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan')); + + if (!$lehrfach_permission && !$lehreinheit_permission) + $this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess')); + + $result = $this->_ci->lektorlib->addLektorToLehreinheit($lehreinheit_id, $mitarbeiter_uid); + + if (isError($result)) $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess("Erfolgreich gespeichert"); + } + + public function update() + { + $formData = $this->input->post('formData'); + $lehreinheit_id = $this->input->post('lehreinheit_id'); + $mitarbeiter_uid = $this->input->post('mitarbeiter_uid'); + + $this->checkLehreinheit($lehreinheit_id); + $this->checkMitarbeiter($mitarbeiter_uid); + + $updatableFields = array( + 'lehrfunktion_kurzbz', + 'planstunden', + 'stundensatz', + 'faktor', + 'anmerkung', + 'bismelden', + 'semesterstunden', + 'mitarbeiter_uid' + ); + + $this->form_validation->set_data($formData); + + foreach ($updatableFields as $field) + { + if (array_key_exists($field, $formData)) + { + switch ($field) + { + case 'lehrfunktion_kurzbz': + $this->form_validation->set_rules($field, 'Lehrfunktion', 'required|max_length[16]'); + break; + case 'planstunden': + $this->form_validation->set_rules($field, 'Planstunden', 'integer|greater_than_equal_to[0]'); + break; + case 'stundensatz': + $this->form_validation->set_rules($field, 'Stundensatz', 'numeric|greater_than_equal_to[0]'); + break; + case 'faktor': + $this->form_validation->set_rules($field, 'Faktor', 'numeric|greater_than_equal_to[0]'); + break; + case 'anmerkung': + $this->form_validation->set_rules($field, 'Anmerkung', 'max_length[256]'); + break; + case 'bismelden': + $this->form_validation->set_rules($field, 'Bis Melden', 'trim'); + break; + case 'semesterstunden': + $this->form_validation->set_rules($field, 'Semesterstunden', 'callback__check_semesterstunden'); + break; + case 'mitarbeiter_uid': + $this->form_validation->set_rules($field, 'Semesterstunden', 'required|max_length[32]'); + break; + } + } + } + if (!$this->form_validation->run()) + { + $this->terminateWithError($this->form_validation->error_array()); + } + + if (isset($formData['semesterstunden']) && (!is_numeric($formData['semesterstunden']) || $formData['semesterstunden'] === '')) + { + $formData['semesterstunden'] = null; + } + + $lehreinheit_permission = $this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan')); + + if (!$lehreinheit_permission) + $this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess')); + + $result = $this->_ci->lektorlib->updateLektorFromLehreinheit($lehreinheit_id, $mitarbeiter_uid, $formData); + + if (isError($result)) $this->terminateWithError(getError($result)); + $this->terminateWithSuccess("Erfolgreich geupdated"); + } + + public function _check_semesterstunden($value) + { + if ($value === null || $value === '') { + return true; + } + + if (!is_numeric($value)) + { + $this->form_validation->set_message( + '_check_semesterstunden', + 'Das Feld {field} muss eine Zahl sein.' + ); + return false; + } + + if ($value < 0) + { + $this->form_validation->set_message( + '_check_semesterstunden', + 'Das Feld {field} muss eine Zahl größer oder gleich 0 sein.' + ); + return false; + } + + return true; + } + public function getLehrfunktionen() + { + $this->_ci->load->model('education/Lehrfunktion_model', 'LehrfunktionModel'); + $this->_ci->LehrfunktionModel->addOrder('lehrfunktion_kurzbz'); + $this->terminateWithSuccess(getData($this->_ci->LehrfunktionModel->load())); + } + + public function getLektoren() + { + $this->_ci->MitarbeiterModel->addSelect('uid, person_id, vorname, nachname'); + $this->_ci->MitarbeiterModel->addJoin('public.tbl_benutzer', 'uid = mitarbeiter_uid'); + $this->_ci->MitarbeiterModel->addJoin('public.tbl_person', 'person_id'); + $this->terminateWithSuccess(getData($this->_ci->MitarbeiterModel->loadWhere(array('public.tbl_benutzer.aktiv' => true)))); + } + + private function checkLehreinheit($lehreinheit_id) + { + if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id); + + if (!hasData($lehreinheit_result) || isError($lehreinheit_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + return getData($lehreinheit_result)[0]; + + } + public function getLektorenByLE($lehreinheit_id = null) + { + $this->checkLehreinheit($lehreinheit_id); + $le_mitarbeiter_data = $this->_ci->LehreinheitmitarbeiterModel->getLektorenByLe($lehreinheit_id); + $this->terminateWithSuccess(hasData($le_mitarbeiter_data) ? getData($le_mitarbeiter_data) : array()); + } + + public function getLektorDaten($lehreinheit_id = null, $mitarbeiter_uid = null) + { + $lehreinheit = $this->checkLehreinheit($lehreinheit_id); + + if (is_null($mitarbeiter_uid)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid); + + if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $this->load->model('organisation/Studiensemester_model','StudiensemesterModel'); + $studiensemester_result = $this->_ci->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz' => $lehreinheit->studiensemester_kurzbz)); + $studiensemester = getData($studiensemester_result)[0]; + + $defaultStundensatz = $this->_ci->StundensatzModel->getDefaultStundensatz($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'lehre'); + + $le_mitarbeiter_result = $this->_ci->LehreinheitmitarbeiterModel->getByLeLektor($lehreinheit_id, $mitarbeiter_uid); + + $le_mitarbeiter_data = array(); + if (hasData($le_mitarbeiter_result)) + { + $le_mitarbeiter_data = getData($le_mitarbeiter_result)[0]; + $le_mitarbeiter_data->default_stundensatz = $defaultStundensatz; + } + $vertrag = $this->getLektorVertrag($lehreinheit_id, $mitarbeiter_uid); + $le_mitarbeiter_data->vertrag = $vertrag; + $this->terminateWithSuccess($le_mitarbeiter_data); + } + + private function getLektorVertrag($lehreinheit_id = null, $mitarbeiter_uid = null) + { + $this->_ci->load->model('accounting/Vertrag_model', 'VertragModel'); + $vertrag = $this->_ci->VertragModel->getVertrag($mitarbeiter_uid, $lehreinheit_id); + return hasData($vertrag) ? getData($vertrag)[0] : null; + } + + private function checkLehrfachPermission($lehreinheit_id, $permissions) + { + $lehrfach_oe_kurzbz = $this->_ci->LehreinheitModel->getLehrfachOe($lehreinheit_id); + + if (isError($lehrfach_oe_kurzbz)) + $this->terminateWithError(getError($lehrfach_oe_kurzbz), self::ERROR_TYPE_GENERAL); + + $lehrfach_oe_kurzbz = array(''); + if (hasData($lehrfach_oe_kurzbz)) + $lehrfach_oe_kurzbz = array_column(getData($lehrfach_oe_kurzbz), 'oe_kurzbz'); + + + return $this->checkPermissionGenerel($permissions, $lehrfach_oe_kurzbz); + } + + private function checkPermissionGenerel($permissions, $oe_array) + { + $hasPermission = false; + foreach ($permissions as $permission) + { + if ($this->_ci->permissionlib->isBerechtigtMultipleOe($permission, $oe_array, 'suid')) + { + $hasPermission = true; + break; + } + } + + return $hasPermission; + } + + private function checkPermission($lehreinheit_id, $permissions) + { + $result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id); + + if (isError($result)) + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + + $oe_array = $result; + + return $this->checkPermissionGenerel($permissions, $oe_array); + } + public function cancelVertrag() + { + $vertrag_id = $this->input->post('vertrag_id'); + $lehreinheit_id = $this->input->post('lehreinheit_id'); + $mitarbeiter_uid = $this->input->post('mitarbeiter_uid'); + + $this->checkLehreinheit($lehreinheit_id); + $this->checkPermission($lehreinheit_id, array('admin', 'lehre/lehrauftrag_bestellen')); + + if (is_null($vertrag_id) || !ctype_digit((string)$vertrag_id)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $vertrag_result = $this->_ci->VertragModel->load($vertrag_id); + + if (!hasData($vertrag_result) || isError($vertrag_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + if (is_null($mitarbeiter_uid)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid); + + if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $result = $this->_ci->VertragModel->cancelVertrag($vertrag_id, $mitarbeiter_uid); + + if (isError($result)) + $this->terminateWithError(getError($result)); + + $this->terminateWithSuccess($result); + } + + public function deletePerson() + { + $lehreinheit_id = $this->input->post('lehreinheit_id'); + $mitarbeiter_uid = $this->input->post('mitarbeiter_uid'); + + $this->checkLehreinheit($lehreinheit_id); + $this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan')); + + if (is_null($mitarbeiter_uid)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid); + + if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $delete_result =$this->_ci->LehreinheitmitarbeiterModel->deleteLektorFromLe($lehreinheit_id, $mitarbeiter_uid); + + if (isError($delete_result)) + $this->terminateWithError(getError($delete_result)); + + $this->terminateWithSuccess($delete_result); + } + + public function deleteLVPlan() + { + $lehreinheit_id = $this->input->post('lehreinheit_id'); + $mitarbeiter_uid = $this->input->post('mitarbeiter_uid'); + + $this->checkLehreinheit($lehreinheit_id); + $this->checkPermission($lehreinheit_id, array('lv-plan/lektorentfernen')); + + if (is_null($mitarbeiter_uid)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid); + + if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + + $delete_result = $this->_ci->StundenplandevModel->deleteLektorPlanning($lehreinheit_id, $mitarbeiter_uid); + + if (isError($delete_result)) + $this->terminateWithError(getError($delete_result)); + + $this->terminateWithSuccess($delete_result); + } + + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) + show_error('User authentification failed'); + } +} diff --git a/application/controllers/api/frontend/v1/lv/Setup.php b/application/controllers/api/frontend/v1/lv/Setup.php new file mode 100644 index 000000000..cf73697a7 --- /dev/null +++ b/application/controllers/api/frontend/v1/lv/Setup.php @@ -0,0 +1,116 @@ +. + */ + +if (!defined('BASEPATH')) + exit('No direct script access allowed'); + +class Setup extends FHCAPI_Controller +{ + private $_ci; + private $_uid; + + public function __construct() + { + parent::__construct([ + 'getTabs' => ['admin:r', 'assistenz:r'], + 'getStudiensemester' => ['admin:r', 'assistenz:r'], + 'getSprache' => ['admin:r', 'assistenz:r'], + 'getRaumtyp' => ['admin:r', 'assistenz:r'], + 'getLehrform' => ['admin:r', 'assistenz:r'], + ]); + + $this->_ci = &get_instance(); + $this->_setAuthUID(); + + $this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + $this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $this->_ci->load->library('VariableLib', ['uid' => $this->_uid]); + } + + public function getTabs() + { + $tabs['details'] = array ( + 'title' => 'Details', + 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Details.js', + 'config' => [] + ); + $tabs['lektor'] = array ( + 'title' => 'LektorInnenzuteilung', + 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Lektor.js', + 'config' => [] + ); + $tabs['notiz'] = array ( + 'title' => 'Notizen', + 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Notiz.js', + 'config' => [] + ); + $this->terminateWithSuccess($tabs); + } + + public function getStudiensemester() + { + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $this->_ci->StudiensemesterModel->addOrder('start', 'DESC'); + $this->terminateWithSuccess(getData($this->_ci->StudiensemesterModel->load())); + } + public function getSprache() + { + $this->_ci->load->model('system/Sprache_model', 'SpracheModel'); + $this->terminateWithSuccess(getData($this->_ci->SpracheModel->load())); + } + + public function getRaumtyp() + { + $this->_ci->load->model('ressource/Raumtyp_model', 'RaumtypModel'); + $this->_ci->RaumtypModel->addOrder('raumtyp_kurzbz'); + $this->terminateWithSuccess(getData($this->_ci->RaumtypModel->loadWhere(array('aktiv' => true)))); + } + + public function getLehrform() + { + $language = $this->_getLanguageIndex(); + + $this->_ci->load->model('codex/lehrform_model', 'LehrformModel'); + + $this->_ci->LehrformModel->addSelect( + '*, + bezeichnung_kurz[('.$language.')] as bez_kurz, + bezeichnung_lang[('.$language.')] as bez + ' + ); + $this->terminateWithSuccess(getData($this->_ci->LehrformModel->load())); + } + + private function _getLanguageIndex() + { + $this->_ci->load->model('system/Sprache_model', 'SpracheModel'); + $this->_ci->SpracheModel->addSelect('index'); + $result = $this->_ci->SpracheModel->loadWhere(array('sprache' => getUserLanguage())); + + return hasData($result) ? getData($result)[0]->index : 1; + } + + private function _setAuthUID() + { + $this->_uid = getAuthUID(); + + if (!$this->_uid) + show_error('User authentification failed'); + } +} diff --git a/application/controllers/api/frontend/v1/lv/StgTree.php b/application/controllers/api/frontend/v1/lv/StgTree.php new file mode 100644 index 000000000..fe3047902 --- /dev/null +++ b/application/controllers/api/frontend/v1/lv/StgTree.php @@ -0,0 +1,91 @@ +method] = ['admin:r', 'assistenz:r']; + parent::__construct($permissions); + + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + } + + public function _remap($method, $params = []) + { + if ($method == '' || $method == 'index') + return $this->getBase(); + + if (!$this->permissionlib->isBerechtigt('assistenz', 's', $method) + && !$this->permissionlib->isBerechtigt('admin', 's', $method) + ) { + return $this->_outputAuthError([$method => ['admin:r', 'assistenz:r']]); + } + + return $this->getStudiengang($method); + show_404(); + } + + protected function getBase() + { + $this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz'); + + $this->StudiengangModel->addDistinct(); + $this->StudiengangModel->addSelect("v.studiengang_kz AS link"); + $this->StudiengangModel->addSelect( + "CONCAT(kurzbzlang, ' (', UPPER(CONCAT(typ, kurzbz)), ') - ', tbl_studiengang.bezeichnung) AS name", + false + ); + $this->StudiengangModel->addSelect('erhalter_kz'); + $this->StudiengangModel->addSelect('typ'); + $this->StudiengangModel->addSelect('kurzbz'); + $this->StudiengangModel->addSelect('studiengang_kz'); + $this->StudiengangModel->addSelect('studiengang_kz AS stg_kz'); + + $this->StudiengangModel->addOrder('erhalter_kz'); + $this->StudiengangModel->addOrder('typ'); + $this->StudiengangModel->addOrder('kurzbz'); + + $stgs = $this->permissionlib->getSTG_isEntitledFor('admin') ?: []; + $stgs = array_merge($stgs, $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []); + + if (!$stgs) + $this->terminateWithSuccess([]); + + $this->StudiengangModel->db->where_in('studiengang_kz', $stgs); + + $result = $this->StudiengangModel->loadWhere(['v.aktiv' => true]); + + $list = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($list); + } + + protected function getStudiengang($studiengang_kz) + { + $link = $studiengang_kz . '/'; + + $this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz'); + + $this->StudiengangModel->addDistinct(); + $this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", semester) AS link", false); + $this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester ORDER BY verband, gruppe LIMIT 1)) AS name", false); + $this->StudiengangModel->addSelect("TRUE AS leaf", false); + + $this->StudiengangModel->addSelect('semester'); + $this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false); + + $this->StudiengangModel->addOrder('semester'); + + $result = $this->StudiengangModel->loadWhere([ + 'v.studiengang_kz' => $studiengang_kz, + 'v.aktiv' => true + ]); + $list = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($list); + } +} diff --git a/application/controllers/api/frontend/v1/lv/Tags.php b/application/controllers/api/frontend/v1/lv/Tags.php new file mode 100644 index 000000000..234ab3cba --- /dev/null +++ b/application/controllers/api/frontend/v1/lv/Tags.php @@ -0,0 +1,24 @@ + self::BERECHTIGUNG_KURZBZ, + 'getTags' => self::BERECHTIGUNG_KURZBZ, + 'addTag' => self::BERECHTIGUNG_KURZBZ, + 'updateTag' => self::BERECHTIGUNG_KURZBZ, + 'doneTag' => self::BERECHTIGUNG_KURZBZ, + 'deleteTag' => self::BERECHTIGUNG_KURZBZ, + 'updateLehre' => self::BERECHTIGUNG_KURZBZ, + 'doneLehre' => self::BERECHTIGUNG_KURZBZ, + 'deleteLehre' => self::BERECHTIGUNG_KURZBZ, + ]); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php new file mode 100644 index 000000000..f8e1f816b --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php @@ -0,0 +1,21 @@ + ['admin:r', 'assistenz:r'], + 'getNotizen' => ['admin:r', 'assistenz:r'], + 'loadNotiz' => ['admin:r', 'assistenz:r'], + 'addNewNotiz' => ['admin:rw', 'assistenz:rw'], + 'updateNotiz' => ['admin:rw', 'assistenz:rw'], + 'deleteNotiz' => ['admin:rw', 'assistenz:rw'], + 'loadDokumente' => ['admin:r', 'assistenz:r'], + 'getMitarbeiter' => ['admin:r', 'assistenz:r'], + 'isBerechtigt' => ['admin:r', 'assistenz:r'], + ]); + } +} \ No newline at end of file diff --git a/application/libraries/LektorLib.php b/application/libraries/LektorLib.php new file mode 100644 index 000000000..44c71cdaa --- /dev/null +++ b/application/libraries/LektorLib.php @@ -0,0 +1,342 @@ +_ci =& get_instance(); + $this->_ci->load->model('education/lehreinheit_model', 'LehreinheitModel'); + $this->_ci->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel'); + $this->_ci->load->model('organisation/Studiensemester_model','StudiensemesterModel'); + $this->_ci->load->model('ressource/Stundensatz_model', 'StundensatzModel'); + $this->_ci->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel'); + $this->_ci->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel'); + $this->_ci->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); + $this->_ci->load->model('person/Benutzer_model', 'BenutzerModel'); + } + + public function addLektorToLehreinheit($lehreinheit_id, $mitarbeiter_uid) + { + $this->_ci->LehreinheitModel->addSelect('tbl_lehreinheit.*, tbl_lehrveranstaltung.studiengang_kz, semesterstunden'); + $this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); + $lehreinheit_result = $this->_ci->LehreinheitModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + + if (isError($lehreinheit_result)) return $lehreinheit_result; + + if (!hasData($lehreinheit_result)) return error("Lehreinheit not found"); + + $lehreinheit = getData($lehreinheit_result)[0]; + + $already_assigned = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit->lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); + + if (isError($already_assigned)) return $already_assigned; + + if (hasData($already_assigned)) return error('Lektor already assigned'); + + $studiensemester_result = $this->_ci->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz' => $lehreinheit->studiensemester_kurzbz)); + if (isError($studiensemester_result)) return $studiensemester_result; + $studiensemester = getData($studiensemester_result)[0]; + + $stundensatz = $this->_ci->StundensatzModel->getDefaultStundensatz($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'lehre'); + $echter_dv_result = $this->_ci->DienstverhaeltnisModel->existsDienstverhaeltnis($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'echterdv'); + + $echter_dv = false; + + if (hasData($echter_dv_result)) + { + $echter_dv = true; + } + + $maxstunden = $this->getMaxStunden($mitarbeiter_uid, $studiensemester->studiensemester_kurzbz, $lehreinheit->studiengang_kz, $echter_dv); + + $newData['semesterstunden'] = 0; + $newData['planstunden'] = 0; + if (!is_null($lehreinheit->semesterstunden)) + { + $newData['semesterstunden'] = min($lehreinheit->semesterstunden, $maxstunden); + $newData['planstunden'] = min($lehreinheit->semesterstunden, $maxstunden); + } + + $newData['lehreinheit_id'] = $lehreinheit->lehreinheit_id; + $newData['mitarbeiter_uid'] = $mitarbeiter_uid; + $newData['lehrfunktion_kurzbz'] = 'Lektor'; + $newData['bismelden'] = true; + $newData['insertvon'] = getAuthUID(); + $newData['insertamum'] = date('Y-m-d H:i:s'); + $newData['stundensatz'] = $stundensatz; + $result = $this->_ci->LehreinheitmitarbeiterModel->insert($newData); + + if (isError($result)) return $result; + + return success("Lektor added successfully"); + } + + public function updateLektorFromLehreinheit($lehreinheit_id, $mitarbeiter_uid, $new_data) + { + $this->_ci->LehreinheitmitarbeiterModel->addSelect('lehre.tbl_lehreinheitmitarbeiter.*, lehre.tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.studiengang_kz'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); + $lehreinheit_result = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); + + if (isError($lehreinheit_result)) return $lehreinheit_result; + + if (!hasData($lehreinheit_result)) return error("Lehreinheit not found"); + + $lehreinheit = getData($lehreinheit_result)[0]; + + //TODO kollision check, wird vorerst nicht implementiert -> nur über das FAS möglich + if (isset($new_data['mitarbeiter_uid']) && $new_data['mitarbeiter_uid'] !== $mitarbeiter_uid) + { + $this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel'); + $this->_ci->StundenplandevModel->addGroupBy('stundenplandev_id'); + $this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid'); + $this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid'); + $verplant = $this->_ci->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); + + if (hasData($verplant)) + return error('Wechsel vom Mitarbeiter nicht möglich da er bereits verplant ist!'); + } + $warning = ''; + if (isset($new_data['semesterstunden'])) + { + $studiengang_result = $this->_ci->StudiengangModel->loadWhere(array('studiengang_kz' => $lehreinheit->studiengang_kz)); + if (isError($studiengang_result)) return $studiengang_result; + if (!hasData($studiengang_result)) return error('Studiengang not found'); + $studiengang = getData($studiengang_result)[0]; + + $studiensemester_result = $this->_ci->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz' => $lehreinheit->studiensemester_kurzbz)); + if (isError($studiensemester_result)) return $studiensemester_result; + $studiensemester = getData($studiensemester_result)[0]; + + $echter_dv_result = $this->_ci->DienstverhaeltnisModel->existsDienstverhaeltnis($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'echterdv'); + + $echter_dv = false; + + if (hasData($echter_dv_result)) + { + $echter_dv = true; + } + + $neue_stunden_eingerechnet = isset($new_data['bismelden']) ? $new_data['bismelden'] : $lehreinheit->bismelden; + $alte_stunden_eingerechnet = $lehreinheit->bismelden; + + if (($new_data['semesterstunden'] > $lehreinheit->semesterstunden) || $neue_stunden_eingerechnet) + { + $stundengrenze_result = $this->_ci->OrganisationseinheitModel->getStundengrenze($studiengang->oe_kurzbz, $echter_dv); + if (isError($stundengrenze_result)) return $stundengrenze_result; + + $stundengrenze = getData($stundengrenze_result)[0]; + + $oe_result = $this->_ci->OrganisationseinheitModel->getChilds($stundengrenze->oe_kurzbz); + $oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array(''); + + if ($alte_stunden_eingerechnet && $neue_stunden_eingerechnet) + $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($lehreinheit->semesterstunden) + {$this->_ci->LehreinheitmitarbeiterModel->db->escape($new_data['semesterstunden'])}) as summe"); + else if ($alte_stunden_eingerechnet && !$neue_stunden_eingerechnet) + $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($lehreinheit->semesterstunden)) as summe"); + else if (!$alte_stunden_eingerechnet && $neue_stunden_eingerechnet) + $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) + ({$this->_ci->LehreinheitmitarbeiterModel->db->escape($new_data['semesterstunden'])})) as summe"); + else if (!$alte_stunden_eingerechnet && !$neue_stunden_eingerechnet) + $this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden)) as summe"); + + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz'); + + $this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', (isset($new_data['mitarbeiter_uid']) ? $new_data['mitarbeiter_uid'] : $mitarbeiter_uid)); + $this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $lehreinheit->studiensemester_kurzbz); + $this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true); + $this->_ci->LehreinheitmitarbeiterModel->db->where('lower(mitarbeiter_uid) NOT LIKE', '_dummy%'); + + $this->_ci->LehreinheitmitarbeiterModel->db->where_in('tbl_studiengang.oe_kurzbz', $oe_array); + + + if(defined('FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE') + && is_array(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) + && count(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) > 0) + { + $this->_ci->LehreinheitmitarbeiterModel->db->where_not_in('tbl_studiengang.oe_kurzbz', FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE); + } + + $summe_result = $this->_ci->LehreinheitmitarbeiterModel->load(); + + if (isError($summe_result)) return $summe_result; + + if (!hasData($summe_result)) return error('Fehler beim Ermitteln der Gesamtstunden'); + + $summe = getData($summe_result)[0]->summe; + + if ($summe > $stundengrenze->stunden) + { + + if (!$echter_dv && (!$this->_ci->permissionlib->isBerechtigt('admin'))) + { + if (!$this->LehrauftragAufFirma(isset($formData['mitarbeiter_uid']) ? $formData['mitarbeiter_uid'] : $mitarbeiter_uid)) + return error("ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\n Daten wurden NICHT gespeichert!\n\n"); + } + else + { + $warning .= "ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\n Daten wurden gespeichert!\n\n"; + } + + $stunden_limit_result = $this->getStundenInstitut($mitarbeiter_uid, $lehreinheit->studiensemester_kurzbz, $oe_array); + + if (hasData($stunden_limit_result)) + { + $stunden_limit_array = getData($stunden_limit_result); + foreach ($stunden_limit_array as $stunden_limit) + { + $warning .= $stunden_limit->summe . ' Stunden' . $stunden_limit->bezeichnung; + } + } + } + } + } + + $benutzer_result = $this->_ci->BenutzerModel->load(array(isset($formData['mitarbeiter_uid']) ? $formData['mitarbeiter_uid'] : $mitarbeiter_uid)); + + if (isError($benutzer_result)) return $benutzer_result; + + if (!hasData($benutzer_result)) return error('Benutzer not found'); + + $benutzer_aktiv = getData($benutzer_result)[0]->aktiv; + + if (!$benutzer_aktiv) + $warning .= "Achtung: Der/Die Benutzer*in ist inaktiv!\nBitte informieren Sie die Personalbteilung.\n\nDaten wurden gespeichert.\n\n"; + + $updatableFields = array( + 'semesterstunden', + 'planstunden', + 'stundensatz', + 'faktor', + 'anmerkung', + 'lehrfunktion_kurzbz', + 'mitarbeiter_uid', + 'bismelden' + ); + + $updateData = array(); + foreach ($updatableFields as $field) + { + $value = isset($new_data[$field]) ? $new_data[$field] : null; + + if ($value !== null) + { + $updateData[$field] = $value; + } + } + $updateData['updatevon'] = getAuthUID(); + $updateData['updateamum'] = date('Y-m-d H:i:s'); + + $result = $this->_ci->LehreinheitmitarbeiterModel->update(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid), $updateData); + + if (isError($result)) return $result; + + if ($warning !== '') return error($warning); + + return success('Successfully updated Lehreinheit'); + } + + private function getMaxStunden($mitarbeiter_uid, $studiensemester_kurzbz, $studiengang_kz, $echter_dv) + { + $maxstunden = 9999; + + $studiengang_result = $this->_ci->StudiengangModel->loadWhere(array('studiengang_kz' => $studiengang_kz)); + if (isError($studiengang_result)) return $studiengang_result; + + $studiengang = getData($studiengang_result)[0]; + + $stundengrenze_result = $this->_ci->OrganisationseinheitModel->getStundengrenze($studiengang->oe_kurzbz, $echter_dv); + if (isError($stundengrenze_result)) return $stundengrenze_result; + + $stundengrenze = getData($stundengrenze_result)[0]; + $maxstunden = $stundengrenze->stunden; + + $lehrauftrag_firma = $this->LehrauftragAufFirma($mitarbeiter_uid); + + if (!$echter_dv && !$lehrauftrag_firma) + { + $oe_result = $this->_ci->OrganisationseinheitModel->getChilds($stundengrenze->oe_kurzbz); + $oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array(''); + + $stunden_summe_result = $this->getSumSemesterstunden($mitarbeiter_uid, $studiensemester_kurzbz, $oe_array); + + $stunden_summe = hasData($stunden_summe_result) ? getData($stunden_summe_result)[0]->summe : 0; + + if ($stunden_summe >= $maxstunden && (!$this->_ci->permissionlib->isBerechtigt('admin'))) + { + $stunden_limit_result = $this->getStundenInstitut($mitarbeiter_uid, $studiensemester_kurzbz, $oe_array); + + $error = "ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $maxstunden Stunden ($stundengrenze->oe_kurzbz) wurde ueberschritten!\n + Daten wurden NICHT gespeichert!\n\n"; + + if (hasData($stunden_limit_result)) + { + $stunden_limit_array = getData($stunden_limit_result); + + foreach ($stunden_limit_array as $stunden_limit) + { + $error .= $stunden_limit->summe . ' Stunden' . $stunden_limit->bezeichnung; + } + } + return error($error); + } + else + $maxstunden =- $stunden_summe; + } + return $maxstunden; + } + + private function LehrauftragAufFirma($mitarbeiter_uid) + { + $this->_ci->MitarbeiterModel->addJoin('tbl_benutzer', 'tbl_mitarbeiter.mitarbeiter_uid = tbl_benutzer.uid'); + $this->_ci->MitarbeiterModel->addJoin('tbl_person', 'person_id'); + $this->_ci->MitarbeiterModel->addJoin('tbl_adresse', 'person_id', 'LEFT'); + $this->_ci->MitarbeiterModel->addOrder('zustelladresse', 'DESC'); + $this->_ci->MitarbeiterModel->addOrder('firma_id'); + $this->_ci->MitarbeiterModel->addLimit(1); + $firma_result = $this->_ci->MitarbeiterModel->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid)); + $firma = getData($firma_result)[0]->firma_id; + return !is_null($firma); + } + + private function getSumSemesterstunden($mitarbeiter_uid, $studiensemester_kurzbz, $oe_array = array()) + { + $this->_ci->LehreinheitmitarbeiterModel->addSelect('SUM(tbl_lehreinheitmitarbeiter.semesterstunden) as summe'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz'); + $this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', $mitarbeiter_uid); + $this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $studiensemester_kurzbz); + $this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true); + $this->_ci->LehreinheitmitarbeiterModel->db->where('lower(mitarbeiter_uid) NOT LIKE', '_dummy%'); + $this->_ci->LehreinheitmitarbeiterModel->db->where_in('tbl_studiengang.oe_kurzbz', $oe_array); + return $this->_ci->LehreinheitmitarbeiterModel->load(); + } + + private function getStundenInstitut($mitarbeiter_uid, $studiensemester_kurzbz, $oe_array = array()) + { + $this->_ci->LehreinheitmitarbeiterModel->addSelect('SUM(tbl_lehreinheitmitarbeiter.semesterstunden) as summe, tbl_studiengang.bezeichnung'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id'); + $this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz'); + $this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', $mitarbeiter_uid); + $this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $studiensemester_kurzbz); + $this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true); + $this->_ci->LehreinheitmitarbeiterModel->db->where_in('tbl_studiengang.oe_kurzbz', $oe_array); + + if(defined('FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE') + && is_array(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) + && count(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) > 0) + { + $this->_ci->LehreinheitmitarbeiterModel->db->where_not_in('tbl_studiengang.oe_kurzbz', FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE); + } + + $this->_ci->LehreinheitmitarbeiterModel->addGroupBy('tbl_studiengang.bezeichnung'); + return $this->_ci->LehreinheitmitarbeiterModel->load(); + } +} diff --git a/application/models/accounting/Vertrag_model.php b/application/models/accounting/Vertrag_model.php index abc2114a6..c17c676c7 100644 --- a/application/models/accounting/Vertrag_model.php +++ b/application/models/accounting/Vertrag_model.php @@ -384,6 +384,60 @@ class Vertrag_model extends DB_Model } } + public function getVertrag($mitarbeiter_uid, $lehreinheit_id) + { + $this->addSelect('tbl_lehreinheitmitarbeiter.*, tbl_vertrag.*, status.bezeichnung as vertragsstatus, status.vertragsstatus_kurzbz'); + $this->addJoin('lehre.tbl_lehreinheitmitarbeiter', 'vertrag_id'); + $this->addJoin('lehre.tbl_vertragstyp', 'vertragstyp_kurzbz', 'LEFT'); + $this->addJoin(' + ( + SELECT DISTINCT ON(vertrag_id) vertrag_id, + bezeichnung, + tbl_vertragsstatus.vertragsstatus_kurzbz + FROM lehre.tbl_vertrag_vertragsstatus + JOIN lehre.tbl_vertragsstatus USING(vertragsstatus_kurzbz) + ORDER BY vertrag_id, datum DESC + ) as status', 'status.vertrag_id = lehre.tbl_vertrag.vertrag_id', 'LEFT'); + + return $this->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid, 'lehreinheit_id' => $lehreinheit_id)); + } + + public function cancelVertrag($vertrag_id, $mitarbeiter_uid) + { + $vertrag = $this->load($vertrag_id); + + if (!hasData($vertrag)) + return error("Contract not found"); + + $vertrag = getData($vertrag)[0]; + + $this->_updateVertragRelevant($vertrag->vertrag_id); + + return $this->VertragvertragsstatusModel->insert(array( + 'vertrag_id' => $vertrag->vertrag_id, + 'vertragsstatus_kurzbz' => 'storno', + 'uid' => $mitarbeiter_uid, + 'datum' => 'NOW()', + 'insertamum' => 'NOW()', + 'insertvon' => getAuthUID() + )); + } + + public function deleteVertrag($vertrag_id) + { + $vertrag = $this->load($vertrag_id); + + if (!hasData($vertrag)) + return error("Contract not found"); + + $vertrag = getData($vertrag)[0]; + + $this->_updateVertragRelevant($vertrag->vertrag_id); + + $this->VertragvertragsstatusModel->delete(array('vertrag_id' => $vertrag->vertrag_id)); + return $this->delete(array('vertrag_id' => $vertrag->vertrag_id)); + } + // ----------------------------------------------------------------------------------------------------------------- // Private methods @@ -415,4 +469,20 @@ class Vertrag_model extends DB_Model return $bezeichnung; } + + private function _updateVertragRelevant($vertrag_id) + { + $this->LehreinheitmitarbeiterModel->update( + array("vertrag_id" => $vertrag_id), + array( + 'vertrag_id' => null + ) + ); + $this->ProjektbetreuerModel->update( + array("vertrag_id" => $vertrag_id), + array( + 'vertrag_id' => null + ) + ); + } } diff --git a/application/models/education/Lehreinheit_model.php b/application/models/education/Lehreinheit_model.php index d4bc7a22f..ba9e82c64 100644 --- a/application/models/education/Lehreinheit_model.php +++ b/application/models/education/Lehreinheit_model.php @@ -1,4 +1,6 @@ load->model('education/lehreinheitgruppe_model', 'LehreinheitgruppeModel'); $this->load->model('education/lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel'); $this->load->model('organisation/studiengang_model', 'StudiengangModel'); + $this->load->model('ressource/stundenplandev_model', 'StundenplandevModel'); + $this->load->model('ressource/stundenplan_model', 'StundenplanModel'); + $this->load->model('system/Log_model', 'LogModel'); } /** @@ -303,4 +308,437 @@ EOSQL; return $this->execQuery($query, $params); } + + + public function getOes($lehreinheit_id) + { + $this->addSelect('tbl_lehrveranstaltung.studiengang_kz, + tbl_lehrveranstaltung.lehrveranstaltung_id'); + $this->addJoin('lehre.tbl_lehrveranstaltung', 'tbl_lehrveranstaltung.lehrveranstaltung_id = tbl_lehreinheit.lehrveranstaltung_id'); + $result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + + if (isError($result)) return $result; + + if (hasData($result)) + { + $lehrveranstaltung = getData($result)[0]; + $oe_result = $this->LehrveranstaltungModel->getAllOe($lehrveranstaltung->lehrveranstaltung_id, $lehrveranstaltung->studiengang_kz); + return success(hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array('')); + } + } + + public function getLehrfachOe($lehreinheit_id) + { + $this->addSelect('lehrfach.oe_kurzbz'); + $this->addJoin('lehre.tbl_lehrveranstaltung lehrfach', 'lehrfach.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id', 'LEFT'); + return $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + } + + + public function getByLvidStudiensemester($lv_id, $studiensemester_kurzbz) + { + $qry = "WITH lehreinheiten AS ( + SELECT * + FROM lehre.tbl_lehreinheit + WHERE lehrveranstaltung_id = ? + AND studiensemester_kurzbz = ? + ), + gruppen AS ( + SELECT + COALESCE( + string_agg( + tbl_lehreinheitgruppe.gruppe_kurzbz, ' ' + ) FILTER (WHERE NOT direktinskription), + string_agg( + COALESCE( + upper(tbl_studiengang.typ::varchar(1) ||tbl_studiengang.kurzbz) || + '-'|| + COALESCE(tbl_lehreinheitgruppe.semester::varchar, '') || + COALESCE(tbl_lehreinheitgruppe.verband::varchar, '')|| + COALESCE(tbl_lehreinheitgruppe.gruppe, '')), ', ' + ) + ) AS gruppe, + lehreinheit_id + FROM + lehre.tbl_lehreinheitgruppe + LEFT JOIN public.tbl_studiengang USING(studiengang_kz) + LEFT JOIN public.tbl_gruppe USING(gruppe_kurzbz) + GROUP BY lehreinheit_id + ), + mitarbeiter AS ( + SELECT kurzbz, semesterstunden, planstunden, lehreinheit_id + FROM lehre.tbl_lehreinheitmitarbeiter + JOIN public.tbl_mitarbeiter USING(mitarbeiter_uid) + ), + fachbereich AS ( + SELECT + tbl_organisationseinheit.bezeichnung, + tbl_organisationseinheit.organisationseinheittyp_kurzbz, + lehreinheit_id + FROM + public.tbl_organisationseinheit, + lehre.tbl_lehrveranstaltung as lehrfach, + lehre.tbl_lehreinheit + WHERE tbl_organisationseinheit.oe_kurzbz = lehrfach.oe_kurzbz + AND lehrfach.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id + ), + tag_data_agg AS ( + SELECT + lehreinheit_id, + COALESCE(json_agg(tag ORDER BY id), '[]'::json) AS tags + FROM ( + SELECT DISTINCT ON (public.tbl_notiz.notiz_id) + tbl_notiz.notiz_id AS id, + typ_kurzbz, + array_to_json(tbl_notiz_typ.bezeichnung_mehrsprachig)->>0 AS beschreibung, + text AS notiz, + style, + erledigt AS done, + lehreinheit_id + FROM public.tbl_notizzuordnung + JOIN public.tbl_notiz ON tbl_notizzuordnung.notiz_id = tbl_notiz.notiz_id + JOIN public.tbl_notiz_typ ON tbl_notiz.typ = tbl_notiz_typ.typ_kurzbz + WHERE lehreinheit_id IN (SELECT lehreinheit_id FROM lehreinheiten) + ) AS tag + GROUP BY lehreinheit_id + ) + SELECT lehreinheiten.*, + lehreinheiten.lehrform_kurzbz as lv_lehrform_kurzbz, + tbl_lehrveranstaltung.kurzbz as lv_kurzbz, + tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, + COALESCE(tag_data_agg.tags, '[]'::json) AS tags, + ( + SELECT string_agg(gr.gruppe, ' ') + FROM gruppen gr + WHERE gr.lehreinheit_id = lehreinheiten.lehreinheit_id + ) AS gruppen, + ( + SELECT string_agg(ma.kurzbz, ' ') + FROM mitarbeiter ma + WHERE ma.lehreinheit_id = lehreinheiten.lehreinheit_id + ) AS lektoren, + ( + SELECT string_agg(fachbereich.bezeichnung, ' ') + FROM fachbereich + WHERE fachbereich.lehreinheit_id = lehreinheiten.lehreinheit_id + ) AS fachbereich + FROM lehreinheiten + LEFT JOIN lehre.tbl_lehrveranstaltung ON tbl_lehrveranstaltung.lehrveranstaltung_id = lehreinheiten.lehrfach_id + LEFT JOIN tag_data_agg ON tag_data_agg.lehreinheit_id = lehreinheiten.lehreinheit_id"; + + return $this->execReadOnlyQuery($qry, array($lv_id, $studiensemester_kurzbz)); + } + + private function getLVTmp($stg_kz = null) + { + $qry = "SELECT DISTINCT ON(lehrveranstaltung_id) *, + '' as studienplan_id, '' as studienplan_beeichnung, + CONCAT(vw_lehreinheit.stg_typ, vw_lehreinheit.stg_kurzbz) as studiengang + FROM campus.vw_lehreinheit + WHERE mitarbeiter_uid = ? + AND studiensemester_kurzbz = ?"; + + if (!is_null($stg_kz)) { + $qry .= " AND lv_studiengang_kz = ?"; + } + + return $qry; + } + + public function getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz = null) + { + $qry = "WITH lvs AS (" . $this->getLVTmp($stg_kz) . ") + SELECT lvs.* + FROM lvs + "; + + $params = array($mitarbeiter_uid, $studiensemester_kurzbz); + if (!is_null($stg_kz)) + { + $params[] = $stg_kz; + } + return $this->execReadOnlyQuery($qry, $params); + } + + + + public function getLEByLV($lv_id, $studiensemester_kurzbz, $mitarbeiter_uid = null, $fachbereich_kurzbz = null) + { + $qry = " + WITH gruppen AS ( + SELECT + COALESCE( + string_agg( + tbl_lehreinheitgruppe.gruppe_kurzbz, ', ' + ) FILTER (WHERE NOT direktinskription), + string_agg( + COALESCE( + upper(tbl_studiengang.typ::varchar(1) ||tbl_studiengang.kurzbz) || + '-'|| + COALESCE(tbl_lehreinheitgruppe.semester::varchar, '') || + COALESCE(tbl_lehreinheitgruppe.verband::varchar, '')|| + COALESCE(tbl_lehreinheitgruppe.gruppe, '')), ', ' + ) + ) AS gruppen, + lehreinheit_id + FROM + lehre.tbl_lehreinheitgruppe + LEFT JOIN public.tbl_studiengang USING(studiengang_kz) + LEFT JOIN public.tbl_gruppe USING(gruppe_kurzbz) + GROUP BY lehreinheit_id + ), + lektoren AS ( + SELECT string_agg(kurzbz, ' ') as lektoren, + string_agg(semesterstunden::text, ' ') as semesterstunden, + string_agg(planstunden::text, ' ') as planstunden, + lehreinheit_id + FROM lehre.tbl_lehreinheitmitarbeiter + JOIN public.tbl_mitarbeiter USING(mitarbeiter_uid) + GROUP BY lehreinheit_id + ), + fachbereich AS ( + SELECT + string_agg(CONCAT(tbl_organisationseinheit.bezeichnung, ' (', tbl_organisationseinheit.organisationseinheittyp_kurzbz, ')'),' ') as fachbereich, + lehreinheit_id + FROM + public.tbl_organisationseinheit, + lehre.tbl_lehrveranstaltung as lehrfach, + lehre.tbl_lehreinheit + WHERE + tbl_organisationseinheit.oe_kurzbz = lehrfach.oe_kurzbz + AND lehrfach.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id + GROUP BY lehreinheit_id + ) + SELECT tbl_lehreinheit.*, + tbl_lehrveranstaltung.*, + tbl_lehrveranstaltung.kurzbz as lv_kurzbz, + tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, + lektoren.lektoren, + lektoren.semesterstunden, + lektoren.planstunden, + fachbereich.fachbereich + FROM lehre.tbl_lehreinheit + LEFT JOIN lehre.tbl_lehrveranstaltung ON tbl_lehrveranstaltung.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id + LEFT JOIN gruppen ON tbl_lehreinheit.lehreinheit_id = gruppen.lehreinheit_id + LEFT JOIN lektoren ON tbl_lehreinheit.lehreinheit_id = lektoren.lehreinheit_id + LEFT JOIN fachbereich ON tbl_lehreinheit.lehreinheit_id = fachbereich.lehreinheit_id + WHERE tbl_lehreinheit.lehrveranstaltung_id = ? + AND studiensemester_kurzbz = ? + "; + + $params = array($lv_id, $studiensemester_kurzbz); + if ($mitarbeiter_uid !== null) + { + $qry .= " AND tbl_lehreinheit.lehreinheit_id IN ( SELECT lehreinheit_id FROM lehre.tbl_lehreinheitmitarbeiter WHERE mitarbeiter_uid = ?) "; + $params[] = $mitarbeiter_uid; + } + + if($fachbereich_kurzbz !== null) + { + $qry .= " AND EXISTS ( SELECT 1 FROM lehre.tbl_lehrveranstaltung JOIN public.tbl_fachbereich USING(oe_kurzbz) WHERE fachbereich_kurzbz= ? AND lehrveranstaltung_id=tbl_lehreinheit.lehrfach_id)"; + $params[] = $fachbereich_kurzbz; + } + $qry .= " ORDER BY lehreinheit_id;"; + + return $this->execReadOnlyQuery($qry, $params); + } + + public function deleteLehreinheit($lehreinheit_id) + { + $lehreinheit = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + + if (isError($lehreinheit)) return $lehreinheit; + + if (!hasData($lehreinheit)) + return error("Lehreinheit not found!"); + + $errorReasons = []; + $addError = function ($reason = null) use (&$errorReasons) + { + if ($reason !== null) + { + $errorReasons[] = $reason; + } + }; + + $stundenplandev_result = $this->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + $stundenplan_result = $this->StundenplanModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + + if (hasData($stundenplan_result) || hasData($stundenplandev_result)) + $addError('Dieser LV-Teil ist bereits im LV-Plan verplant und kann daher nicht geloescht werden!'); + + Events::trigger( + 'lehreinheit_delete_check', + $addError, + $lehreinheit_id + ); + + if (!empty($errorReasons)) return error($errorReasons); + + $this->db->trans_begin(); + + Events::trigger( + 'lehreinheit_delete', + $addError, + $lehreinheit_id + ); + + $undosql = ''; + + $lehreinheit_gruppe_result = $this->LehreinheitgruppeModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + if (hasData($lehreinheit_gruppe_result)) + { + foreach (getData($lehreinheit_gruppe_result) as $row) + { + $values = [ + $this->db->escape($row->lehreinheitgruppe_id), + $this->db->escape($row->lehreinheit_id), + $this->db->escape($row->studiengang_kz), + $this->db->escape($row->semester), + $this->db->escape($row->verband), + $this->db->escape($row->gruppe), + $this->db->escape($row->gruppe_kurzbz), + $this->db->escape($row->updateamum), + $this->db->escape($row->updatevon), + $this->db->escape($row->insertamum), + $this->db->escape($row->insertvon) + ]; + + $undosql .= "INSERT INTO lehre.tbl_lehreinheitgruppe ( + lehreinheitgruppe_id, + lehreinheit_id, + studiengang_kz, + semester, + verband, + gruppe, + gruppe_kurzbz, + updateamum, + updatevon, + insertamum, + insertvon + ) VALUES (" . implode(', ', $values) . ");\n"; + } + + $lehreinheit_gruppe_delete_result = $this->LehreinheitgruppeModel->delete(array('lehreinheit_id' => $lehreinheit_id)); + + if (isError($lehreinheit_gruppe_delete_result)) + $addError(getError($lehreinheit_gruppe_delete_result)); + } + + $lehreinheit_mitarbeiter_result = $this->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + if (hasData($lehreinheit_mitarbeiter_result)) + { + foreach (getData($lehreinheit_mitarbeiter_result) as $row) + { + $values = [ + $this->db->escape($row->lehreinheit_id), + $this->db->escape($row->mitarbeiter_uid), + $this->db->escape($row->lehrfunktion_kurzbz), + $this->db->escape($row->planstunden), + $this->db->escape($row->stundensatz), + $this->db->escape($row->faktor), + $this->db->escape($row->anmerkung), + $this->db->escape($row->bismelden), + $this->db->escape($row->updateamum), + $this->db->escape($row->updatevon), + $this->db->escape($row->insertamum), + $this->db->escape($row->insertvon), + $this->db->escape($row->semesterstunden) + ]; + + $undosql .= "INSERT INTO lehre.tbl_lehreinheitmitarbeiter ( + lehreinheit_id, + mitarbeiter_uid, + lehrfunktion_kurzbz, + planstunden, + stundensatz, + faktor, + anmerkung, + bismelden, + updateamum, + updatevon, + insertamum, + insertvon, + semesterstunden + ) VALUES (" . implode(', ', $values) . ");\n"; + } + + $lehreinheit_mitarbeiter_delete_result = $this->LehreinheitmitarbeiterModel->delete(array('lehreinheit_id' => $lehreinheit_id)); + if (isError($lehreinheit_mitarbeiter_delete_result)) + $addError(getError($lehreinheit_mitarbeiter_delete_result)); + } + + foreach (getData($lehreinheit) as $row) + { + $values = [ + $this->db->escape($row->lehreinheit_id), + $this->db->escape($row->lehrveranstaltung_id), + $this->db->escape($row->studiensemester_kurzbz), + $this->db->escape($row->lehrfach_id), + $this->db->escape($row->lehrform_kurzbz), + $this->db->escape($row->stundenblockung), + $this->db->escape($row->wochenrythmus), + $this->db->escape($row->start_kw), + $this->db->escape($row->raumtyp), + $this->db->escape($row->raumtypalternativ), + $this->db->escape($row->sprache), + $this->db->escape($row->lehre), + $this->db->escape($row->anmerkung), + $this->db->escape($row->unr), + $this->db->escape($row->lvnr), + $this->db->escape($row->updateamum), + $this->db->escape($row->updatevon), + $this->db->escape($row->insertamum), + $this->db->escape($row->insertvon), + ]; + + $undosql .= "INSERT INTO lehre.tbl_lehreinheit ( + lehreinheit_id, + lehrveranstaltung_id, + studiensemester_kurzbz, + lehrfach_id, + lehrform_kurzbz, + stundenblockung, + wochenrythmus, + start_kw, + raumtyp, + raumtypalternativ, + sprache, + lehre, + anmerkung, + unr, + lvnr, + updateamum, + updatevon, + insertamum, + insertvon + ) VALUES (" . implode(', ', $values) . ");\n"; + } + $lehreinheit_result = $this->delete($lehreinheit_id); + + $deleteSql = "DELETE FROM lehre.tbl_lehreinheitmitarbeiter WHERE lehreinheit_id = " . $this->db->escape($lehreinheit_id) ."; \n + DELETE FROM lehre.tbl_lehreinheitgruppe WHERE lehreinheit_id = " . $this->db->escape($lehreinheit_id) ."; \n + DELETE FROM lehre.tbl_lehreinheit WHERE lehreinheit_id = " . $this->db->escape($lehreinheit_id) .";"; + if (isError($lehreinheit_result)) + $addError($lehreinheit_result); + + $log_result = $this->LogModel->insert([ + 'sql' => $deleteSql, + 'sqlundo' => $undosql, + 'beschreibung' => 'Lehreinheit loeschen - ' . $lehreinheit_id, + 'mitarbeiter_uid' => getAuthUID(), + ]); + + if (isError($log_result)) + $addError($log_result); + + if (!empty($errorReasons)) + { + $this->db->trans_rollback(); + return error($errorReasons); + } + + $this->db->trans_commit(); + return success('Contract successfully updated.'); + } } diff --git a/application/models/education/Lehreinheitgruppe_model.php b/application/models/education/Lehreinheitgruppe_model.php index 2a6f9571a..5dd2fa66c 100644 --- a/application/models/education/Lehreinheitgruppe_model.php +++ b/application/models/education/Lehreinheitgruppe_model.php @@ -14,6 +14,7 @@ class Lehreinheitgruppe_model extends DB_Model $this->load->model('organisation/studiengang_model', 'StudiengangModel'); $this->load->model('organisation/gruppe_model', 'GruppeModel'); $this->load->model('person/benutzergruppe_model', 'BenutzergruppeModel'); + $this->load->model('ressource/stundenplandev_model', 'StundenplandevModel'); } /** @@ -23,7 +24,15 @@ class Lehreinheitgruppe_model extends DB_Model */ public function getDirectGroup($lehreinheit_id) { + $this->addSelect('tbl_lehreinheitgruppe.*'); + $this->addSelect('tbl_gruppe.*'); + $this->addSelect('uid'); + $this->addSelect('vorname'); + $this->addSelect('nachname'); $this->addJoin('public.tbl_gruppe', 'gruppe_kurzbz'); + $this->addJoin('public.tbl_benutzergruppe', 'gruppe_kurzbz', 'LEFT'); + $this->addJoin('public.tbl_benutzer', 'uid', 'LEFT'); + $this->addJoin('public.tbl_person', 'person_id', 'LEFT'); return $this->loadWhere( array( 'tbl_gruppe.direktinskription' => true, @@ -264,4 +273,203 @@ class Lehreinheitgruppe_model extends DB_Model } return $result; } + + public function addGroup($lehreinheit_id, $gid, $verband) + { + $lehreinheit = $this->LehreinheitModel->load($lehreinheit_id); + + if (!hasData($lehreinheit)) + return error ('No Lehreinheit found!'); + + if ($verband === false) + { + $gruppen_result = $this->GruppeModel->loadWhere(array('gid' => $gid)); + + if (!hasData($gruppen_result)) + return error('No group found for gid ' . $gid); + + $gruppen_array = getData($gruppen_result)[0]; + + if (!isEmptyString($gruppen_array->gruppe_kurzbz)) + { + $this->db->where('trim(gruppe_kurzbz)', $gruppen_array->gruppe_kurzbz); + } + else + { + $this->db->group_start(); + $this->db->where("trim(gruppe_kurzbz) = ''"); + $this->db->or_where("gruppe_kurzbz IS NULL"); + $this->db->group_end(); + } + } + else if ($verband === true) + { + $gruppen_result = $this->_ci->LehrverbandModel->loadWhere(array('gid' => $gid)); + + if (!hasData($gruppen_result)) + return error('No group found for gid ' . $gid); + + $gruppen_array = getData($gruppen_result)[0]; + + if (!isEmptyString($gruppen_array->verband)) + { + $this->db->where('verband', $gruppen_array->verband); + } + else + { + $this->db->group_start(); + $this->db->where("trim(verband) = ''"); + $this->db->or_where("verband IS NULL"); + $this->db->group_end(); + } + + if (!isEmptyString($gruppen_array->gruppe)) + { + $this->db->where('gruppe', $gruppen_array->gruppe); + } + else + { + $this->db->group_start(); + $this->db->where("trim(gruppe) = ''"); + $this->db->or_where("gruppe IS NULL"); + $this->db->group_end(); + } + } + else + return error('Wrong type of verband'); + + $this->db->where('lehreinheit_id', $lehreinheit_id); + $this->db->where('studiengang_kz', $gruppen_array->studiengang_kz); + + if (!isEmptyString($gruppen_array->semester)) + { + $this->db->where('semester', $gruppen_array->semester); + } + else + { + $this->db->group_start(); + $this->db->where("semester = ''"); + $this->db->or_where("semester IS NULL"); + $this->db->group_end(); + } + + $exist_result = $this->load(); + + if (!hasData($exist_result)) + { + $new_group_result = $this->insert(array( + 'lehreinheit_id' => $lehreinheit_id, + 'studiengang_kz' => $gruppen_array->studiengang_kz, + 'gruppe_kurzbz' => isset($gruppen_array->gruppe_kurzbz) ? $gruppen_array->gruppe_kurzbz : null, + 'semester' => $gruppen_array->semester, + 'verband' => isset($gruppen_array->verband) && !isEmptyString($gruppen_array->verband) ? $gruppen_array->verband : null, + 'gruppe' => isset($gruppen_array->gruppe) && !isEmptyString($gruppen_array->gruppe) ? $gruppen_array->gruppe : null, + 'insertamum' => date('Y-m-d H:i:s'), + 'insertvon' => getAuthUID() + )); + + if (isError($new_group_result)) + return error('Error when adding Group'); + + return success('Group assigned successfully to Lehreinheit'); + } + else + return error('Group already assigned'); + } + + public function deleteGroup($lehreinheit_id, $lehreinheitgruppe_id) + { + $lehreinheit = $this->LehreinheitModel->load($lehreinheit_id); + + if (!hasData($lehreinheit)) + return error ('No Lehreinheit found!'); + + $lehreinheitgruppe = $this->load($lehreinheitgruppe_id); + + if (!hasData($lehreinheitgruppe)) + return error ('No Lehreinheitgruppe found!'); + + $this->addSelect('stundenplandev_id'); + $this->addJoin('lehre.tbl_stundenplandev', + "tbl_stundenplandev.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id + AND tbl_stundenplandev.studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz + AND tbl_stundenplandev.semester = tbl_lehreinheitgruppe.semester + AND trim(COALESCE(tbl_stundenplandev.verband, '')) = trim(COALESCE(tbl_lehreinheitgruppe.verband, '')) + AND trim(COALESCE(tbl_stundenplandev.gruppe, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe, '')) + AND trim(COALESCE(tbl_stundenplandev.gruppe_kurzbz, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe_kurzbz, ''))" + ); + $stundenplan_result = $this->loadWhere(array('tbl_lehreinheitgruppe.lehreinheitgruppe_id' => $lehreinheitgruppe_id)); + + if (hasData($stundenplan_result)) + return error('Gruppe already verplant'); + + $delete_result = $this->delete($lehreinheitgruppe_id); + + if (isError($delete_result)) + return error('Error deleting Group'); + + return success('Group deleted'); + } + + public function getByLehreinheit($lehreinheit_id) + { + $lehreinheit = $this->LehreinheitModel->load($lehreinheit_id); + + if (!hasData($lehreinheit)) + return error ('No Lehreinheit found!'); + + $this->addSelect('tbl_lehreinheitgruppe.*'); + $this->addSelect('tbl_gruppe.direktinskription'); + $this->addSelect('tbl_gruppe.gruppe_kurzbz'); + $this->addSelect("CASE + WHEN tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL THEN + COALESCE ( + UPPER(tbl_studiengang.typ || tbl_studiengang.kurzbz) || + COALESCE(tbl_lehreinheitgruppe.semester::varchar, '') || + COALESCE(tbl_lehreinheitgruppe.verband::varchar, '') || + COALESCE(tbl_lehreinheitgruppe.gruppe, ''), + '') + ELSE tbl_lehreinheitgruppe.gruppe_kurzbz + END AS bezeichnung"); + $this->addSelect("CASE + WHEN tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL THEN + ( + SELECT bezeichnung + FROM public.tbl_lehrverband + WHERE studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz + AND semester = tbl_lehreinheitgruppe.semester + AND verband = tbl_lehreinheitgruppe.verband + AND gruppe = tbl_lehreinheitgruppe.gruppe + LIMIT 1 + ) + ELSE tbl_gruppe.beschreibung + END AS beschreibung"); + $this->addSelect("CASE + WHEN tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL THEN + ( + SELECT EXISTS ( + SELECT 1 + FROM lehre.tbl_stundenplandev + WHERE lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id + AND studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz + AND semester = tbl_lehreinheitgruppe.semester + AND TRIM(COALESCE(verband, '')) = TRIM(tbl_lehreinheitgruppe.verband) + AND TRIM(COALESCE(gruppe, '')) = TRIM(tbl_lehreinheitgruppe.gruppe) + AND (gruppe_kurzbz IS NULL OR gruppe_kurzbz = '') + ) + ) + ELSE + ( + SELECT EXISTS ( + SELECT 1 + FROM lehre.tbl_stundenplandev + WHERE lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id + AND gruppe_kurzbz = tbl_lehreinheitgruppe.gruppe_kurzbz + ) + ) + END AS verplant"); + $this->addJoin('tbl_studiengang', 'studiengang_kz', 'LEFT'); + $this->addJoin('public.tbl_gruppe', 'gruppe_kurzbz', 'LEFT'); + return $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'tbl_gruppe.direktinskription' => false)); + } } diff --git a/application/models/education/Lehreinheitmitarbeiter_model.php b/application/models/education/Lehreinheitmitarbeiter_model.php index ae1ac55d2..efdb2e74d 100644 --- a/application/models/education/Lehreinheitmitarbeiter_model.php +++ b/application/models/education/Lehreinheitmitarbeiter_model.php @@ -10,6 +10,14 @@ class Lehreinheitmitarbeiter_model extends DB_Model parent::__construct(); $this->dbTable = 'lehre.tbl_lehreinheitmitarbeiter'; $this->pk = array('mitarbeiter_uid', 'lehreinheit_id'); + $this->hasSequence = false; + + $this->load->model('accounting/Vertrag_model', 'VertragModel'); + $this->load->model('ressource/stundenplandev_model', 'StundenplandevModel'); + $this->load->model('ressource/stundenplan_model', 'StundenplanModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel'); + $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); } /** @@ -75,4 +83,67 @@ class Lehreinheitmitarbeiter_model extends DB_Model ]); } + public function getLektorenByLe($lehreinheit_id) + { + $this->addSelect('vorname, nachname, tbl_lehreinheitmitarbeiter.*, stundenplan.verplant'); + $this->addJoin('tbl_benutzer', 'uid = mitarbeiter_uid'); + $this->addJoin('tbl_person', 'person_id'); + + $this->addJoin('( + SELECT 1 as verplant, lehreinheit_id, mitarbeiter_uid + FROM lehre.tbl_stundenplandev + GROUP BY lehreinheit_id, mitarbeiter_uid + + ) stundenplan', 'stundenplan.mitarbeiter_uid = tbl_lehreinheitmitarbeiter.mitarbeiter_uid AND stundenplan.lehreinheit_id = tbl_lehreinheitmitarbeiter.lehreinheit_id', 'LEFT'); + + return $this->loadWhere(array('tbl_lehreinheitmitarbeiter.lehreinheit_id' => $lehreinheit_id)); + } + + public function getByLeLektor($lehreinheit_id, $mitarbeiter_uid) + { + $this->addSelect('vorname, nachname, tbl_lehreinheitmitarbeiter.*'); + $this->addJoin('tbl_benutzer', 'uid = mitarbeiter_uid'); + $this->addJoin('tbl_person', 'person_id'); + return $this->loadWhere(array('tbl_lehreinheitmitarbeiter.lehreinheit_id' => $lehreinheit_id, 'tbl_lehreinheitmitarbeiter.mitarbeiter_uid' => $mitarbeiter_uid)); + } + + public function deleteLektorFromLe($lehreinheit_id, $mitarbeiter_uid) + { + if (defined('FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN') && FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN) + { + $vertrag_result = $this->VertragModel->getVertrag($mitarbeiter_uid, $lehreinheit_id); + + if (hasData($vertrag_result)) + return error("Loeschen nur nach Stornierung des Vertrags möglich"); + } + + $stundenplandev_result = $this->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); + $stundenplan_result = $this->StundenplanModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); + + if (hasData($stundenplandev_result) || hasData($stundenplan_result)) + return error("Diese/r LektorIn kann nicht gelöscht werden da er schon verplant ist"); + + $result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); + + if (hasData($result)) + { + $le_mitarbeiter_array = getData($result)[0]; + + if ($le_mitarbeiter_array->vertrag_id !== null) + { + $vertrag_result = $this->VertragModel->deleteVertrag($le_mitarbeiter_array->vertrag_id); + if (isError($vertrag_result)) + return $vertrag_result; + } + + $delete_result = $this->delete(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); + + if (isError($delete_result)) + return $delete_result; + + return success($delete_result); + } + } + + } diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index 056fb45d7..955177273 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -988,4 +988,229 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($qry, $params); } + + public function getLvsByOrganization($oe_kurzbz) + { + $qry=" + SELECT + distinct on (lehrveranstaltung_id) + tbl_lehrveranstaltung.studiengang_kz as lv_studiengang_kz, tbl_lehrveranstaltung.semester as lv_semester, + tbl_lehrveranstaltung.kurzbz as lv_kurzbz, tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, tbl_lehrveranstaltung.ects as lv_ects, + tbl_lehrveranstaltung.lehreverzeichnis as lv_lehreverzeichnis, tbl_lehrveranstaltung.planfaktor as lv_planfaktor, + tbl_lehrveranstaltung.planlektoren as lv_planlektoren, tbl_lehrveranstaltung.planpersonalkosten as lv_planpersonalkosten, + tbl_lehrveranstaltung.plankostenprolektor as lv_plankostenprolektor, tbl_lehrveranstaltung.orgform_kurzbz as lv_orgform_kurzbz, + tbl_lehrveranstaltung.lehrveranstaltung_id, + tbl_lehrveranstaltung.lehrform_kurzbz as lehrform_kurzbz, + tbl_lehrveranstaltung.lehrform_kurzbz as lv_lehrform_kurzbz, + tbl_lehrveranstaltung.bezeichnung_english as lv_bezeichnung_english, + tbl_lehrveranstaltung.studiengang_kz, tbl_lehrveranstaltung.semester, tbl_lehrveranstaltung.anmerkung, tbl_lehrveranstaltung.sprache, tbl_lehrveranstaltung.semesterstunden, + tbl_lehrveranstaltung.lehre, tbl_lehrveranstaltung.aktiv, + '' as studienplan_id, '' as studienplan_bezeichnung, tbl_lehrveranstaltung.lehrtyp_kurzbz + FROM + lehre.tbl_lehrveranstaltung + WHERE + tbl_lehrveranstaltung.oe_kurzbz= ? + AND tbl_lehrveranstaltung.aktiv + "; + + return $this->execReadOnlyQuery($qry, array($oe_kurzbz)); + } + + public function getLvsByFachbereich($fachbereich, $studiensemester_kurbz, $mitarbeiter_uid = null) + { + $qry = ""; + if (!is_null($mitarbeiter_uid)) + { + $qry = $this->getLvsFromStudienplanByEmp(); + $params = array($fachbereich, $studiensemester_kurbz); + } + + $qry .= "SELECT + distinct on(lehrveranstaltung_id) + lv_studiengang_kz, lv_semester, lv_kurzbz, lv_bezeichnung, lv_ects, + lv_lehreverzeichnis, lv_planfaktor, lv_planlektoren, lv_planpersonalkosten, + lv_plankostenprolektor, lv_orgform_kurzbz, lehrveranstaltung_id, + lehrform_kurzbz, lv_lehrform_kurzbz, lv_bezeichnung_english, studiengang_kz, semester, anmerkung, sprache, semesterstunden, + lehre, aktiv, + '' as studienplan_id, '' as studienplan_bezeichnung, + (SELECT lehrtyp_kurzbz FROM lehre.tbl_lehrveranstaltung WHERE lehrveranstaltung_id=vw_lehreinheit.lehrveranstaltung_id) as lehrtyp_kurzbz + FROM + campus.vw_lehreinheit + WHERE studiensemester_kurzbz = ? + AND fachbereich_kurzbz = ?"; + + $params[] = array($studiensemester_kurbz, $fachbereich); + + if (!is_null($mitarbeiter_uid)) + { + $qry .= " AND mitarbeiter_uid = ?"; + $params[] = $mitarbeiter_uid; + } + else + { + $qry.=" AND lehrveranstaltung_id NOT IN (SELECT lehrveranstaltung_id + FROM + lehre.tbl_lehrveranstaltung + JOIN lehre.tbl_studienplan_lehrveranstaltung USING(lehrveranstaltung_id) + JOIN lehre.tbl_studienplan USING(studienplan_id) + JOIN lehre.tbl_studienordnung USING(studienordnung_id) + JOIN lehre.tbl_studienplan_semester USING(studienplan_id) + WHERE + tbl_lehrveranstaltung.oe_kurzbz=(Select oe_kurzbz from public.tbl_fachbereich where fachbereich_kurzbz= ?) + AND tbl_studienplan_semester.studiensemester_kurzbz= ?"; + + $params[] = array($fachbereich, $studiensemester_kurbz); + } + + return $this->execReadOnlyQuery($qry, $params); + } + + private function getLvsFromStudienplanByEmp() + { + return " + SELECT + distinct on (lehrveranstaltung_id) + tbl_lehrveranstaltung.studiengang_kz as lv_studiengang_kz, + tbl_lehrveranstaltung.semester as lv_semester, + tbl_lehrveranstaltung.kurzbz as lv_kurzbz, + tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, + tbl_lehrveranstaltung.ects as lv_ects, + tbl_lehrveranstaltung.lehreverzeichnis as lv_lehreverzeichnis, + tbl_lehrveranstaltung.planfaktor as lv_planfaktor, + tbl_lehrveranstaltung.planlektoren as lv_planlektoren, + tbl_lehrveranstaltung.planpersonalkosten as lv_planpersonalkosten, + tbl_lehrveranstaltung.plankostenprolektor as lv_plankostenprolektor, + tbl_lehrveranstaltung.orgform_kurzbz as lv_orgform_kurzbz, + tbl_lehrveranstaltung.lehrveranstaltung_id, + tbl_lehrveranstaltung.lehrform_kurzbz as lehrform_kurzbz, + tbl_lehrveranstaltung.lehrform_kurzbz as lv_lehrform_kurzbz, + tbl_lehrveranstaltung.bezeichnung_english as lv_bezeichnung_english, + tbl_lehrveranstaltung.studiengang_kz, + tbl_studienplan_lehrveranstaltung.semester, + tbl_lehrveranstaltung.anmerkung, + tbl_lehrveranstaltung.sprache, + tbl_lehrveranstaltung.semesterstunden, + tbl_lehrveranstaltung.lehre, + tbl_lehrveranstaltung.aktiv, + tbl_studienplan.studienplan_id::text, + tbl_studienplan.bezeichnung as studienplan_bezeichnung, + tbl_lehrveranstaltung.lehrtyp_kurzbz + FROM + lehre.tbl_lehrveranstaltung + JOIN lehre.tbl_studienplan_lehrveranstaltung USING(lehrveranstaltung_id) + JOIN lehre.tbl_studienplan USING(studienplan_id) + JOIN lehre.tbl_studienordnung USING(studienordnung_id) + JOIN lehre.tbl_studienplan_semester USING(studienplan_id) + WHERE + tbl_lehrveranstaltung.oe_kurzbz=(Select oe_kurzbz from public.tbl_fachbereich where fachbereich_kurzbz= ?) + AND tbl_studienplan_semester.studiensemester_kurzbz = ? + AND tbl_lehrveranstaltung.aktiv + UNION + "; + } + + public function getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester = null, $verband = null) + { + $qry = ""; + $params = array(); + + if (!empty($studienplan_ids)) + { + $qry = $this->getLvsFromStudienplanByStudienplanID($placeholders); + $params = $studienplan_ids; + } + + $qry .= " + SELECT DISTINCT on(lehrveranstaltung_id) lehrveranstaltung_id, + kurzbz as lv_kurzbz, + bezeichnung as lv_bezeichnung, + bezeichnung_english as lv_bezeichnung_english, + studiengang_kz, + semester, + tbl_lehrveranstaltung.sprache, + ects as lv_ects, + semesterstunden, + tbl_lehrveranstaltung.anmerkung, + tbl_lehrveranstaltung.lehre, + lehreverzeichnis as lv_lehreverzeichnis, + aktiv, + planfaktor as lv_planfaktor, + planlektoren as lv_planlektoren, + planpersonalkosten as lv_planpersonalkosten, + plankostenprolektor as lv_plankostenprolektor, + tbl_lehrveranstaltung.lehrform_kurzbz as lv_lehrform_kurzbz, + tbl_lehrveranstaltung.orgform_kurzbz, + ''::text as studienplan_id, + '' as studienplan_bezeichnung, + '' as studienplan_lehrveranstaltung_id_parent, + tbl_lehrveranstaltung.lehrtyp_kurzbz + FROM lehre.tbl_lehrveranstaltung + JOIN lehre.tbl_lehreinheit USING (lehrveranstaltung_id) + WHERE studiengang_kz = ? + AND studiensemester_kurzbz = ? + "; + + $params[] = $studiengang_kz; + $params[] = $studiensemester_kurzbz; + if (!is_null($semester)) + { + $qry .= ' AND semester = ?'; + $params[] = $semester; + } + if (!is_null($verband)) + { + $qry .= ' AND (orgform_kurzbz = ? OR orgform_kurzbz IS NULL)'; + $params[] = $verband; + } + + if (!empty($only_ids)) + { + + $qry .= ' AND NOT EXISTS (SELECT 1 FROM lehre.tbl_studienplan_lehrveranstaltung where studienplan_id IN ? + AND lehrveranstaltung_id = tbl_lehrveranstaltung.lehrveranstaltung_id AND tbl_lehrveranstaltung.aktiv)'; + + $params[] = $only_ids; + } + + return $this->execReadOnlyQuery($qry, $params); + } + private function getLvsFromStudienplanByStudienplanID($placeholders) + { + return " + SELECT + lehrveranstaltung_id, kurzbz as lv_kurzbz, tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, bezeichnung_english as lv_bezeichnung_english, studiengang_kz, + tbl_studienplan_lehrveranstaltung.semester, tbl_lehrveranstaltung.sprache, + ects as lv_ects, semesterstunden, anmerkung, lehre, lehreverzeichnis as lv_lehreverzeichnis, tbl_lehrveranstaltung.aktiv, + planfaktor as lv_planfaktor, planlektoren as lv_planlektoren, planpersonalkosten as lv_planpersonalkosten, + plankostenprolektor as lv_plankostenprolektor, lehrform_kurzbz as lv_lehrform_kurzbz, tbl_lehrveranstaltung.orgform_kurzbz, + tbl_studienplan_lehrveranstaltung.studienplan_id::text as studienplan_id, tbl_studienplan.bezeichnung as studienplan_bezeichnung, tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent::text, + tbl_lehrveranstaltung.lehrtyp_kurzbz + FROM + lehre.tbl_lehrveranstaltung + JOIN lehre.tbl_studienplan_lehrveranstaltung USING(lehrveranstaltung_id) + JOIN lehre.tbl_studienplan USING(studienplan_id) + WHERE + tbl_lehrveranstaltung.aktiv AND ((studienplan_id, tbl_studienplan_lehrveranstaltung.semester) IN ( " . implode(',', $placeholders) . ")) + UNION + "; + } + + public function getAllOe($lv_id, $stg_kz = null) + { + $qry = "SELECT DISTINCT oe_kurzbz + FROM lehre.tbl_studienplan_lehrveranstaltung + JOIN lehre.tbl_studienplan USING(studienplan_id) + JOIN lehre.tbl_studienordnung USING(studienordnung_id) + JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE lehrveranstaltung_id = ? "; + + $params = array($lv_id); + if (!is_null($stg_kz)) + { + $qry .= ' OR studiengang_kz = ?'; + $params[] = $stg_kz; + } + + return $this->execReadOnlyQuery($qry, $params); + } } diff --git a/application/models/organisation/Organisationseinheit_model.php b/application/models/organisation/Organisationseinheit_model.php index 1b1a826aa..b07a90c87 100644 --- a/application/models/organisation/Organisationseinheit_model.php +++ b/application/models/organisation/Organisationseinheit_model.php @@ -217,4 +217,34 @@ class Organisationseinheit_model extends DB_Model oe_kurzbz ILIKE '%". $this->escapeLike($eventQuery). "%' "); } + + /** + * Ermittelt die Stundenobergrenze fuer Lektoren + * Dabei wird im OE Baum nach oben nach Stundengrenzen gesucht und die niedrigste Stundengrenze ermittelt + * @param $oe_kurzbz Organisationseinheit + * @param $fixangestellt boolean legt fest ob die Grenze + * fuer Freie oder Fixangestellte Lektoren ermittelt werden soll + + */ + public function getStundengrenze($oe_kurzbz, $fixangestellt = true) + { + $fixfrei = $fixangestellt ? 'fix' : 'frei'; + + $qry = " + WITH RECURSIVE oes(oe_kurzbz, oe_parent_kurzbz) as + ( + SELECT oe_kurzbz, oe_parent_kurzbz FROM public.tbl_organisationseinheit + WHERE oe_kurzbz= ? + UNION ALL + SELECT o.oe_kurzbz, o.oe_parent_kurzbz FROM public.tbl_organisationseinheit o, oes + WHERE o.oe_kurzbz=oes.oe_parent_kurzbz + ) + SELECT oe_kurzbz, warn_semesterstunden_{$fixfrei} AS stunden + FROM oes + JOIN public.tbl_organisationseinheit USING (oe_kurzbz) + ORDER BY warn_semesterstunden_{$fixfrei} ASC + LIMIT 1"; + + return $this->execReadOnlyQuery($qry, array($oe_kurzbz)); + } } diff --git a/application/models/organisation/Studienplan_model.php b/application/models/organisation/Studienplan_model.php index e35ba52fb..5a9097d9a 100644 --- a/application/models/organisation/Studienplan_model.php +++ b/application/models/organisation/Studienplan_model.php @@ -134,4 +134,25 @@ class Studienplan_model extends DB_Model 'prestudent_id' => $prestudent_id ]); } + + public function loadStudienplanLehrveranstaltung($lv_id) + { + $qry = "SELECT studienplan_lehrveranstaltung_id, + semester, + pflicht, + studienplan_id, + koordinator, + studienplan_lehrveranstaltung_id_parent, + lehrveranstaltung_id, + insertamum, + insertvon, + updateamum, + updatevon, + sort, + curriculum, + export + FROM lehre.tbl_studienplan_lehrveranstaltung WHERE studienplan_lehrveranstaltung_id = ? "; + return $this->execReadOnlyQuery($qry, array($lv_id)); + } + } diff --git a/application/models/person/Notiz_model.php b/application/models/person/Notiz_model.php index 2e99d1cdd..e13c6ccb9 100644 --- a/application/models/person/Notiz_model.php +++ b/application/models/person/Notiz_model.php @@ -151,36 +151,36 @@ class Notiz_model extends DB_Model * bestellung_id, lehreinheit_id, anrechnung_id, uid) * @param $id the corresponding id, part of public.tbl_notizzuordnung */ - public function getNotizWithDocEntries($id, $type) + public function getNotizWithDocEntries($id, $type, $withoutTags = true) { - $qry = " - SELECT - n.*, count(dms_id) as countDoc, z.notizzuordnung_id, - (CASE - WHEN n.updateamum >= n.insertamum THEN n.updateamum - ELSE n.insertamum - END) AS lastUpdate, - regexp_replace(n.text, '<[^>]*>', '', 'g') as text_stripped, - TO_CHAR(n.start::timestamp, 'DD.MM.YYYY') AS start_format, - TO_CHAR(n.ende::timestamp, 'DD.MM.YYYY') AS ende_format, - z.notiz_id, z.person_id as id, ? as type_id - - FROM - public.tbl_notiz n - JOIN - public.tbl_notizzuordnung z USING (notiz_id) - LEFT JOIN - public.tbl_notiz_dokument dok USING (notiz_id) - LEFT JOIN - campus.tbl_dms_version USING (dms_id) - WHERE - z.$type = ? - GROUP BY - notiz_id, z.notizzuordnung_id - "; + $this->addSelect("tbl_notiz.*, + count(dms_id) as countDoc, + z.notizzuordnung_id, + (CASE + WHEN tbl_notiz.updateamum >= tbl_notiz.insertamum THEN tbl_notiz.updateamum + ELSE tbl_notiz.insertamum + END) AS lastUpdate, + regexp_replace(tbl_notiz.text, '<[^>]*>', '', 'g') as text_stripped, + TO_CHAR(tbl_notiz.start::timestamp, 'DD.MM.YYYY') AS start_format, + TO_CHAR(tbl_notiz.ende::timestamp, 'DD.MM.YYYY') AS ende_format, + z.notiz_id, + z.person_id as id, + {$type} as type_id + "); - return $this->execQuery($qry, array($type, $id)); + $this->addJoin('public.tbl_notizzuordnung z', 'notiz_id'); + $this->addJoin('public.tbl_notiz_dokument dok', 'notiz_id', 'LEFT'); + $this->addJoin('campus.tbl_dms_version', 'dms_id', 'LEFT'); + $this->db->where("z.{$type}", $id); + + if ($withoutTags) + $this->db->where('tbl_notiz.typ IS NULL'); + + $this->addGroupBy('notiz_id'); + $this->addGroupBy('z.notizzuordnung_id'); + + return $this->load(); } diff --git a/application/models/ressource/Mitarbeiter_model.php b/application/models/ressource/Mitarbeiter_model.php index 836f5d65a..337997b8e 100644 --- a/application/models/ressource/Mitarbeiter_model.php +++ b/application/models/ressource/Mitarbeiter_model.php @@ -278,4 +278,18 @@ class Mitarbeiter_model extends DB_Model return $this->execQuery($qry, $parametersArray); } + + public function isLehrauftragFirma($mitarbeiter_uid) + { + $this->addSelect('firma_id'); + $this->addJoin('public.tbl_benutzer', 'uid = mitarbeiter_uid'); + $this->addJoin('public.tbl_person', 'person_id'); + $this->addJoin('public.tbl_adresse', 'person_id', 'LEFT'); + $this->addOrder('zustelladresse', 'DESC'); + $this->addOrder('firma_id'); + $this->addLimit(1); + $firma_result = $this->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid)); + $firma = getData($firma_result)[0]->firma_id; + return !is_null($firma); + } } diff --git a/application/models/ressource/Stundenplandev_model.php b/application/models/ressource/Stundenplandev_model.php index 800540d60..82b3779ab 100644 --- a/application/models/ressource/Stundenplandev_model.php +++ b/application/models/ressource/Stundenplandev_model.php @@ -10,6 +10,9 @@ class Stundenplandev_model extends DB_Model parent::__construct(); $this->dbTable = 'lehre.tbl_stundenplandev'; $this->pk = 'stundenplandev_id'; + + $this->load->model('education/lehreinheit_model', 'LehreinheitModel'); + $this->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel'); } @@ -157,4 +160,84 @@ class Stundenplandev_model extends DB_Model return $this->execQuery($qry, $params); } + public function deleteGroupPlanning($lehreinheit_id, $lehreinheitgruppe_id) + { + $lehreinheit = $this->LehreinheitModel->load($lehreinheit_id); + + if (!hasData($lehreinheit)) + return error ('No Lehreinheit found!'); + + $lehreinheitgruppe = $this->LehreinheitgruppeModel->load($lehreinheitgruppe_id); + + if (!hasData($lehreinheitgruppe)) + return error ('No Lehreinheitgruppe found!'); + + $this->addJoin('lehre.tbl_stundenplan_betriebsmittel', 'stundenplandev_id'); + $this->addJoin('lehre.tbl_lehreinheitgruppe', 'lehreinheit_id'); + $this->db->where('tbl_lehreinheitgruppe.lehreinheitgruppe_id', $lehreinheitgruppe_id); + + $this->db->group_start(); + $this->db->group_start(); + $this->db->where('tbl_lehreinheitgruppe.gruppe_kurzbz IS NOT NULL', null, false); + $this->db->where('tbl_lehreinheitgruppe.gruppe_kurzbz = tbl_stundenplandev.gruppe_kurzbz', null, false); + $this->db->group_end(); + $this->db->or_group_start(); + $this->db->where('tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL', null, false); + $this->db->where('tbl_lehreinheitgruppe.studiengang_kz = tbl_stundenplandev.studiengang_kz', null, false); + $this->db->where('tbl_lehreinheitgruppe.semester = tbl_stundenplandev.semester', null, false); + $this->db->where('tbl_lehreinheitgruppe.verband = tbl_stundenplandev.verband', null, false); + $this->db->where('tbl_lehreinheitgruppe.gruppe = tbl_stundenplandev.gruppe', null, false); + $this->db->group_end(); + $this->db->group_end(); + + $betriebsmittel_result = $this->load(); + $betriebsmittel_array = hasData($betriebsmittel_result) ? getData($betriebsmittel_result) : array(); + if (sizeof($betriebsmittel_array) > 0) + { + return error ('Gruppe kann nicht entfernt werden da bereits Ressourcen zugeordnet wurden'); + } + + $this->addSelect('stundenplandev_id'); + $this->addJoin('lehre.tbl_lehreinheitgruppe', + "tbl_stundenplandev.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id + AND tbl_stundenplandev.studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz + AND tbl_stundenplandev.semester = tbl_lehreinheitgruppe.semester + AND trim(COALESCE(tbl_stundenplandev.verband, '')) = trim(COALESCE(tbl_lehreinheitgruppe.verband, '')) + AND trim(COALESCE(tbl_stundenplandev.gruppe, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe, '')) + AND trim(COALESCE(tbl_stundenplandev.gruppe_kurzbz, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe_kurzbz, ''))" + ); + $stundenplan_result = $this->loadWhere(array('tbl_lehreinheitgruppe.lehreinheitgruppe_id' => $lehreinheitgruppe_id)); + + if (hasData($stundenplan_result)) + { + $stundenplan_ids = array_column(getData($stundenplan_result), 'stundenplandev_id'); + $this->db->where_in('stundenplandev_id', $stundenplan_ids); + $delete_result = $this->db->delete('lehre.tbl_stundenplandev'); + + if ($delete_result) + return success('Group deleted successfully from Stundenplandev'); + else + return error('Error deleting Group from Stundenplandev'); + } + } + + public function deleteLektorPlanning($lehreinheit_id, $mitarbeiter_uid) + { + $this->addDistinct('mitarbeiter_uid'); + $this->addSelect('mitarbeiter_uid'); + $stundenplan_result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); + $stundenplan_array = hasData($stundenplan_result) ? (getData($stundenplan_result)) : array(); + + if (sizeof($stundenplan_array) <= 1) + return error('Diese/r LektorIn kann nicht aus dem LVPlan entfernt werden da dies der/die letzte verplante LektorIn ist'); + + $this->addJoin('lehre.tbl_stundenplan_betriebsmittel', 'stundenplandev_id'); + $betriebsmittel_result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'tbl_stundenplandev.mitarbeiter_uid' => $mitarbeiter_uid)); + $betriebsmittel_array = hasData($betriebsmittel_result) ? getData($betriebsmittel_result) : array(); + + if (sizeof($betriebsmittel_array) > 0) + return error('Gruppe kann nicht entfernt werden da bereits Ressourcen zugeordnet wurden'); + + return $this->delete(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid)); + } } diff --git a/application/models/ressource/Stundensatz_model.php b/application/models/ressource/Stundensatz_model.php index 10f5a6aa1..f34ad07ed 100644 --- a/application/models/ressource/Stundensatz_model.php +++ b/application/models/ressource/Stundensatz_model.php @@ -42,4 +42,20 @@ class Stundensatz_model extends DB_Model return $this->execQuery($qry, $params); } + + public function getDefaultStundensatz($mitarbeiter_uid, $beginn, $ende = null, $typ = null) + { + $stundensatz_result = $this->getStundensatzByDatum($mitarbeiter_uid, $beginn, $ende, $typ); + $default_stundensatz = hasData($stundensatz_result) ? getData($stundensatz_result)[0]->stundensatz : null; + if (defined('FAS_LV_LEKTORINNENZUTEILUNG_FIXANGESTELLT_STUNDENSATZ') && !FAS_LV_LEKTORINNENZUTEILUNG_FIXANGESTELLT_STUNDENSATZ) + { + $this->load->model('vertragsbestandteil/Dienstverhaeltnis_model','DienstverhaeltnisModel'); + $echterdv_result = $this->DienstverhaeltnisModel->existsDienstverhaeltnis($mitarbeiter_uid, $beginn, $ende, 'echterdv'); + if (hasData($echterdv_result)) + { + $default_stundensatz = null; + } + } + return $default_stundensatz; + } } \ No newline at end of file diff --git a/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php index f81a2d518..b055ee954 100644 --- a/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php +++ b/application/models/vertragsbestandteil/Dienstverhaeltnis_model.php @@ -253,4 +253,25 @@ EOSQL; } return $dvs; } + + public function existsDienstverhaeltnis($mitarbeiter_uid, $start, $ende = null, $vertragsart_kurzbz = null) + { + $this->addOrder('von', 'DESC'); + $this->db->where('mitarbeiter_uid', $mitarbeiter_uid); + if (!is_null($vertragsart_kurzbz)) + $this->db->where('vertragsart_kurzbz', $this->escape($vertragsart_kurzbz)); + + $this->db->where('von <=', $ende); + + if (!is_null($ende)) + { + $this->db->group_start(); + $this->db->where('bis >=', $start); + $this->db->or_where('bis IS NULL', null, false); + $this->db->group_end(); + } + + $this->addLimit(1); + return $this->load(); + } } diff --git a/application/views/LVVerwaltung.php b/application/views/LVVerwaltung.php new file mode 100644 index 000000000..4cebae839 --- /dev/null +++ b/application/views/LVVerwaltung.php @@ -0,0 +1,39 @@ + 'LVVerwaltung', + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'vue3' => true, + 'primevue3' => true, + 'tabulator6' => true, + 'tinymce5' => true, + 'tags' => true, + + 'customCSSs' => [ + 'public/css/components/vue-datepicker.css', + 'public/css/components/primevue.css', + 'public/css/Studentenverwaltung.css', + 'public/css/Lvverwaltung.css' + + ], + 'customJSModules' => [ + 'public/js/apps/LVVerwaltung.js' + ] + ); + + $this->load->view('templates/FHC-Header', $includesArray); + +?> +
+ + + +
+load->view('templates/FHC-Footer', $includesArray); ?> + diff --git a/public/css/Lvverwaltung.css b/public/css/Lvverwaltung.css new file mode 100644 index 000000000..1ca3f0be1 --- /dev/null +++ b/public/css/Lvverwaltung.css @@ -0,0 +1,27 @@ +textarea[name="anmerkung"] { + position: absolute; + max-height: 300px; +} + +.lv_table_icon::before +{ + font-family: 'Font Awesome 6 Free'; + font-weight: 900; + margin-left: 5px; + display: inline-block; +} + +.lv_table_icon.icon-modul::before +{ + content: '\f468'; +} + +.lv_table_icon.icon-lv::before +{ + content: '\f466'; +} + +.lv_table_icon.icon-::before +{ + content: '\f073'; +} \ No newline at end of file diff --git a/public/js/api/factory/notiz.js b/public/js/api/factory/notiz.js index 074d4b6a5..ce14269d6 100644 --- a/public/js/api/factory/notiz.js +++ b/public/js/api/factory/notiz.js @@ -16,7 +16,10 @@ */ import person from "./notiz/person.js"; +import lehreinheit from "./notiz/lehreinheit.js"; + export default { - person + person, + lehreinheit }; diff --git a/public/js/api/factory/notiz/lehreinheit.js b/public/js/api/factory/notiz/lehreinheit.js new file mode 100644 index 000000000..d93bb50f9 --- /dev/null +++ b/public/js/api/factory/notiz/lehreinheit.js @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import Person from './person.js'; + +export default { + + ...Person, + getNotizen(id, type) { + return { + method: 'get', + url: 'api/frontend/v1/notiz/notizLehreinheit/getNotizen/' + encodeURIComponent(id) + '/' + encodeURIComponent(type) + }; + }, +}; diff --git a/public/js/api/lehrveranstaltung.js b/public/js/api/lehrveranstaltung.js new file mode 100644 index 000000000..0499572ba --- /dev/null +++ b/public/js/api/lehrveranstaltung.js @@ -0,0 +1,28 @@ +export default { + + getByLV(lehrveranstaltung_id) + { + return { + method: 'get', + url: '/api/frontend/v1/Lehrveranstaltung/loadByLV/' + encodeURIComponent(lehrveranstaltung_id) + }; + }, + getByStg(studiengang_kz, semester) + { + return ("/api/frontend/v1/Lehrveranstaltung/loadByStudiengang/" + encodeURIComponent(studiengang_kz) + "/" + encodeURIComponent(semester)); + }, + + getByEmpStg(mitarbeiter_uid, stg) + { + return ("/api/frontend/v1/Lehrveranstaltung/loadByEmployee/" + encodeURIComponent(mitarbeiter_uid) + "/" + encodeURIComponent(stg)); + }, + + getTable(url) + { + return { + method: 'get', + url: url + }; + }, + +} \ No newline at end of file diff --git a/public/js/api/lehrveranstaltung/details.js b/public/js/api/lehrveranstaltung/details.js new file mode 100644 index 000000000..db251330a --- /dev/null +++ b/public/js/api/lehrveranstaltung/details.js @@ -0,0 +1,30 @@ +export default { + getStudiensemester() + { + return { + method: 'get', + url: '/api/frontend/v1/lv/setup/getStudiensemester/' + }; + }, + getSprache() + { + return { + method: 'get', + url: '/api/frontend/v1/lv/setup/getSprache/' + }; + }, + getLehrform() + { + return { + method: 'get', + url: '/api/frontend/v1/lv/setup/getLehrform/' + }; + }, + getRaumtyp() + { + return { + method: 'get', + url: '/api/frontend/v1/lv/setup/getRaumtyp/' + }; + }, +} diff --git a/public/js/api/lehrveranstaltung/direktgruppe.js b/public/js/api/lehrveranstaltung/direktgruppe.js new file mode 100644 index 000000000..9cd72fcc7 --- /dev/null +++ b/public/js/api/lehrveranstaltung/direktgruppe.js @@ -0,0 +1,26 @@ +export default { + add(newData) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/DirektGruppe/add/', + params: newData + }; + }, + delete(deleteData) + { + + return { + method: 'post', + url: '/api/frontend/v1/lv/DirektGruppe/delete/', + params: deleteData + }; + }, + getByLehreinheit(lehreinheit_id) + { + return { + method: 'get', + url: '/api/frontend/v1/lv/DirektGruppe/getByLehreinheit/' + encodeURIComponent(lehreinheit_id) + }; + }, +} diff --git a/public/js/api/lehrveranstaltung/gruppe.js b/public/js/api/lehrveranstaltung/gruppe.js new file mode 100644 index 000000000..12c55509c --- /dev/null +++ b/public/js/api/lehrveranstaltung/gruppe.js @@ -0,0 +1,56 @@ +export default { + + delete(deleteData) + { + + return { + method: 'post', + url: '/api/frontend/v1/lv/gruppe/delete/', + params: deleteData + }; + }, + + add(newData) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/gruppe/add/', + params: newData + }; + }, + getByLehreinheit(lehreinheit_id) + { + return { + method: 'get', + url: '/api/frontend/v1/lv/gruppe/getByLehreinheit/' + encodeURIComponent(lehreinheit_id) + }; + }, + + deleteFromLVPlan(deleteData) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/gruppe/deleteLVPlan/', + params: deleteData + }; + }, + + +/*------------- details -------- */ + getAll() + { + return { + method: 'get', + url: '/api/frontend/v1/lv/gruppe/getAll/' + }; + }, + + getBenutzer() + { + return { + method: 'get', + url: '/api/frontend/v1/lv/gruppe/getBenutzer/' + }; + } + +} diff --git a/public/js/api/lehrveranstaltung/lehreinheit.js b/public/js/api/lehrveranstaltung/lehreinheit.js new file mode 100644 index 000000000..d8f12e27a --- /dev/null +++ b/public/js/api/lehrveranstaltung/lehreinheit.js @@ -0,0 +1,41 @@ +export default { + copy(data) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/lehreinheit/copy/', + params: data + }; + }, + delete(data) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/lehreinheit/delete/', + params: data + }; + }, + add(newData) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/lehreinheit/add/', + params: newData + }; + }, + get(lehreinheit) + { + return { + method: 'get', + url: '/api/frontend/v1/lv/lehreinheit/get/' + encodeURIComponent(lehreinheit) + }; + }, + update(updatedData) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/lehreinheit/update/', + params: updatedData + }; + }, +} diff --git a/public/js/api/lehrveranstaltung/lektor.js b/public/js/api/lehrveranstaltung/lektor.js new file mode 100644 index 000000000..e8c2fb673 --- /dev/null +++ b/public/js/api/lehrveranstaltung/lektor.js @@ -0,0 +1,78 @@ +export default { + + getLehrfunktionen() + { + return { + method: 'get', + url: '/api/frontend/v1/lv/lektor/getLehrfunktionen/' + }; + }, + + + getLektoren() + { + return { + method: 'get', + url: '/api/frontend/v1/lv/lektor/getLektoren/' + }; + }, + + + getByLehreinheit(lehreinheit_id) + { + return { + method: 'get', + url: '/api/frontend/v1/lv/lektor/getLektorenByLE/' + encodeURIComponent(lehreinheit_id) + }; + }, + + + add(newData) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/lektor/add/', + params: newData + }; + }, + + update(updatedData) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/lektor/update/', + params: updatedData + }; + }, + + + deletePerson(deleteData) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/lektor/deletePerson/', + params: deleteData + }; + }, + deleteFromLVPlan(deleteData) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/lektor/deleteLVPlan/', + params: deleteData + }; + }, + getLektorDaten(lehreinheit_id, mitarbeiter_uid) + { + return { + method: 'get', + url: '/api/frontend/v1/lv/lektor/getLektorDaten/' + encodeURIComponent(lehreinheit_id) + '/' + encodeURIComponent(mitarbeiter_uid) + }; + }, + + + + + + +} diff --git a/public/js/api/lehrveranstaltung/setup.js b/public/js/api/lehrveranstaltung/setup.js new file mode 100644 index 000000000..78f78b05b --- /dev/null +++ b/public/js/api/lehrveranstaltung/setup.js @@ -0,0 +1,9 @@ +export default { + getTabs() + { + return { + method: 'get', + url: '/api/frontend/v1/lv/setup/getTabs/' + }; + }, +} diff --git a/public/js/api/lehrveranstaltung/studiengangtree.js b/public/js/api/lehrveranstaltung/studiengangtree.js new file mode 100644 index 000000000..fb63db729 --- /dev/null +++ b/public/js/api/lehrveranstaltung/studiengangtree.js @@ -0,0 +1,43 @@ +/** + * Copyright (C) 2025 fhcomplete.org + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +export default { + get(path) { + let url = 'api/frontend/v1/lv/StgTree'; + if (path) + url += '/' + path; + return { + method: 'get', + url + }; + }, + favorites: { + get() { + return { + method: 'get', + url: 'api/frontend/v1/lv/favorites' + }; + }, + set(favorites) { + return { + method: 'post', + url: 'api/frontend/v1/lv/favorites/set', + params: { favorites } + }; + } + } +}; \ No newline at end of file diff --git a/public/js/api/lehrveranstaltung/tag.js b/public/js/api/lehrveranstaltung/tag.js new file mode 100644 index 000000000..3d5a5f2ea --- /dev/null +++ b/public/js/api/lehrveranstaltung/tag.js @@ -0,0 +1,54 @@ +export default { + + getTag(data) + { + return { + method: 'get', + url: 'api/frontend/v1/lv/Tags/getTag', + params: data + }; + }, + + getTags(data) + { + return { + method: 'get', + url: 'api/frontend/v1/lv/Tags/getTags' + }; + }, + + addTag(data) + { + return { + method: 'post', + url: 'api/frontend/v1/lv/Tags/addTag', + params: data + }; + }, + + updateTag(data) + { + return { + method: 'post', + url: 'api/frontend/v1/lv/Tags/updateTag', + params: data + }; + }, + doneTag(data) + { + return { + method: 'post', + url: 'api/frontend/v1/lv/Tags/doneTag', + params: data + }; + }, + + deleteTag(data) + { + return { + method: 'post', + url: 'api/frontend/v1/lv/Tags/deleteTag', + params: data + }; + }, +}; \ No newline at end of file diff --git a/public/js/api/lehrveranstaltung/vertrag.js b/public/js/api/lehrveranstaltung/vertrag.js new file mode 100644 index 000000000..601f4b7e3 --- /dev/null +++ b/public/js/api/lehrveranstaltung/vertrag.js @@ -0,0 +1,22 @@ +export default { + + getByLeEmp(lehreinheit_id, mitarbeiter_uid) + { + return { + method: 'get', + url: '/api/frontend/v1/lv/lektor/getLektorDaten/' + encodeURIComponent(lehreinheit_id) + '/' + encodeURIComponent(mitarbeiter_uid), + }; + }, + + cancelByLeEmp(needUpdate) + { + return { + method: 'post', + url: '/api/frontend/v1/lv/lektor/cancelVertrag/', + params: needUpdate + }; + }, + + + +} diff --git a/public/js/apps/LVVerwaltung.js b/public/js/apps/LVVerwaltung.js new file mode 100644 index 000000000..c582f817e --- /dev/null +++ b/public/js/apps/LVVerwaltung.js @@ -0,0 +1,46 @@ +import LVVerwaltung from "../components/LVVerwaltung/LVVerwaltung.js"; +import Phrasen from "../plugins/Phrasen.js"; + +const ciPath = FHC_JS_DATA_STORAGE_OBJECT.app_root.replace(/(https:|)(^|\/\/)(.*?\/)/g, '') + FHC_JS_DATA_STORAGE_OBJECT.ci_router; + +const router = VueRouter.createRouter({ + history: VueRouter.createWebHistory(`/${ciPath}/LVVerwaltung`), + routes: [ + { + name: 'index', + path: `/`, + component: LVVerwaltung + }, + { + name: `byEmp`, + path: `/emp/:emp/:stg?`, + component: LVVerwaltung + }, + /*{ + name: `byFachbereich`, + path: `/fachbereich/:fachbereich/:emp?`, + component: LVVerwaltung + },*/ + { + name: `byStg`, + path: `/stg/:stg/:semester?`, + component: LVVerwaltung + }, + { + path: '/:pathMatch(.*)*', + redirect: '/' + } + ] +}); + +const app = Vue.createApp(); + +app + .use(router) + .use(primevue.config.default, { + zIndex: { + overlay: 1100 + } + }) + .use(Phrasen) + .mount('#main'); diff --git a/public/js/components/LVVerwaltung/Details/Direktinskription.js b/public/js/components/LVVerwaltung/Details/Direktinskription.js new file mode 100644 index 000000000..c7b8e5894 --- /dev/null +++ b/public/js/components/LVVerwaltung/Details/Direktinskription.js @@ -0,0 +1,155 @@ +import {CoreFilterCmpt} from "../../filter/Filter.js"; +import FormForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; +import ApiDirektGruppe from "../../../api/lehrveranstaltung/direktgruppe.js"; +export default{ + name: "LVDirektGruppen", + components: { + CoreFilterCmpt, + FormForm, + FormInput + }, + props: { + lehreinheit_id: Number + }, + inject: { + dropdowns: { + from: 'dropdowns' + }, + }, + computed: { + tabulatorOptions() { + return { + ajaxURL: 'dummy', + ajaxRequestFunc: () => this.$api.call(ApiDirektGruppe.getByLehreinheit(this.lehreinheit_id)), + ajaxResponse: (url, params, response) => { return response.data || [] }, + columns:[ + {title: this.$p.t('person', 'uid'), field:"uid"}, + {title: this.$p.t('person', 'vorname'), field:"vorname"}, + {title: this.$p.t('person', 'nachname'), field:"nachname"}, + {title: this.$p.t('lehre', 'gruppe'), field:"gruppe_kurzbz"}, + { + title: this.$p.t('global', 'actions'), field: 'actions', + minWidth: 150, + formatter: (cell, formatterParams, onRendered) => { + let container = document.createElement('div'); + let button = document.createElement('button'); + container.className = "d-flex gap-1"; + + button.className = 'btn btn-outline-secondary btn-action'; + button.innerHTML = ''; + button.title = this.$p.t('ui', 'loeschen'); + button.addEventListener('click', (event) => { + event.stopPropagation(); + this.deleteDirektGroup(cell.getData().gruppe_kurzbz, cell.getData().uid) + }); + container.append(button); + return container; + }, + frozen: true + }, + ], + layout: 'fitDataFill', + selectable: true, + persistenceID: 'lvverwaltung_direkt_gruppen_2025_05_27_v1', + height: 'auto', + } + } + }, + data() { + return{ + lastSelected: null, + gruppen: [], + tabulatorEvents: [], + showAutocomplete: false, + selectedUser: null, + filteredUsers: [], + abortController: null, + searchTimeout: null, + } + }, + watch: { + lehreinheit_id(n) { + this.$refs.table.reloadTable(); + } + }, + methods:{ + reload() { + this.$refs.table.reloadTable(); + }, + + deleteDirektGroup(gruppe_kurzbz, uid) + { + let deleteData = { + 'gruppe_kurzbz': gruppe_kurzbz, + 'uid': uid, + 'lehreinheit_id': this.lehreinheit_id + } + + this.$api.call(ApiDirektGruppe.delete(deleteData)) + .then(response => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete')); + }) + .catch(this.$fhcAlert.handleSystemError) + .finally(()=> { + this.reload(); + }) + }, + searchUser(event) + { + const query = event.query.toLowerCase().trim(); + this.filteredUsers = this.dropdowns.benutzer_array.filter(user => { + + const fullName = `${user.vorname.toLowerCase()} ${user.nachname.toLowerCase()}`; + const reverseFullName = `${user.nachname.toLowerCase()} ${user.vorname.toLowerCase()}`; + return fullName.includes(query) || reverseFullName.includes(query) || user.uid.toLowerCase().includes(query) || user.studiengang.toLowerCase().includes(query); + }).map(user => ({ + label: user.studiengang + ? `${user.nachname} ${user.vorname} ${user.uid} ${user.studiengang} ${user.semester}` + : `${user.nachname} ${user.vorname} ${user.uid}`, + uid: user.uid + })); + }, + addUser() + { + let newData = { + 'uid': this.selectedUser.uid, + 'lehreinheit_id': this.lehreinheit_id + } + return this.$api.call(ApiDirektGruppe.add(newData)) + .then(result => { + this.reload() + this.selectedUser = '' + }) + .catch(this.$fhcAlert.handleSystemError); + }, + }, + template: ` + + + + + ` +}; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/Details/Form.js b/public/js/components/LVVerwaltung/Details/Form.js new file mode 100644 index 000000000..eed65f7ad --- /dev/null +++ b/public/js/components/LVVerwaltung/Details/Form.js @@ -0,0 +1,209 @@ +import CoreForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; + +export default { + name: "LVDetailsForm", + components: { + FormInput, + CoreForm + }, + props: { + data: { + type: Object, + required: true + } + }, + inject: { + dropdowns: { + from: 'dropdowns' + }, + showLVID: { + from: 'permissionLehrveranstaltung', + default: false + }, + showGewichtung: { + from: 'configShowGewichtung', + default: true + } + }, + computed: { + formattedAnmerkung: { + get() { + return (this.data.anmerkung || '').replace(/\\n/g, '\n'); + }, + set(value) { + this.data.anmerkung = (value || '').replace(/\n/g, '\\n'); + } + } + }, + template: ` +
+
+ + + +
+
+ + + + + + +
+ +
+ + + + +
+ +
+ + + + +
+ +
+ + + + + + +
+ +
+ + + +
+
+` +}; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/Details/Gruppen.js b/public/js/components/LVVerwaltung/Details/Gruppen.js new file mode 100644 index 000000000..62dae172f --- /dev/null +++ b/public/js/components/LVVerwaltung/Details/Gruppen.js @@ -0,0 +1,195 @@ +import {CoreFilterCmpt} from "../../filter/Filter.js"; +import FormForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; +import ApiGruppe from "../../../api/lehrveranstaltung/gruppe.js"; +export default{ + name: "LVGruppen", + components: { + CoreFilterCmpt, + FormForm, + FormInput + }, + props: { + lehreinheit_id: Number + }, + inject: { + dropdowns: { + from: 'dropdowns' + }, + showLVPlanGruppenDel: { + from: 'permissionGruppenEntfernen', + default: false + }, + }, + computed: { + tabulatorOptions() { + return { + ajaxURL: 'dummy', + ajaxRequestFunc: () => this.$api.call(ApiGruppe.getByLehreinheit(this.lehreinheit_id)), + ajaxResponse: (url, params, response) => response.data, + columns:[ + {title: this.$p.t('global', 'bezeichnung'), field:"bezeichnung"}, + {title: this.$p.t('global', 'beschreibung'), field:"beschreibung"}, + {title: this.$p.t('lehre', 'studiengang'), field:"studiengang"}, + {title: "ID", field:"id", visible:false}, + { + title: this.$p.t('lehre', 'verplant'), + field:"verplant", + formatter:"tickCross", + hozAlign:"center", + formatterParams: { + tickElement: '', + crossElement: '' + } + }, + { + title: this.$p.t('global', 'actions'), field: 'actions', + minWidth: 150, + formatter: (cell, formatterParams, onRendered) => { + let container = document.createElement('div'); + let button = document.createElement('button'); + container.className = "d-flex gap-1"; + + button.className = 'btn btn-outline-secondary btn-action'; + button.innerHTML = ''; + button.title = this.$p.t('ui', 'loeschen'); + button.addEventListener('click', (event) => { + event.stopPropagation(); + this.deleteGroup(cell.getData().lehreinheitgruppe_id) + }); + container.append(button); + + if (this.showLVPlanGruppenDel) + { + button = document.createElement('button'); + container.className = "d-flex gap-2"; + button.className = 'btn btn-outline-secondary btn-action'; + button.innerHTML = ''; + button.title = this.$p.t('lehre', 'auslvplanentfernen'); + button.disabled = !cell.getData().verplant; + button.addEventListener('click', (event) => { + event.stopPropagation(); + this.deleteLVPlan(cell.getData().lehreinheitgruppe_id) + }); + container.append(button); + } + return container; + }, + frozen: true + }, + ], + layout: 'fitDataFill', + selectable: true, + persistenceID: 'lvverwaltung_gruppen_2025_05_27_v1', + height: 'auto', + } + } + }, + data() { + return{ + tabulatorEvents: [], + showAutocomplete: false, + filteredGroups: [], + selectedGroup: null + } + }, + watch: { + lehreinheit_id() { + this.$refs.table.reloadTable(); + } + }, + methods:{ + searchGroup(event) + { + const query = event.query.toLowerCase().trim(); + this.filteredGroups = this.dropdowns.gruppen_array.filter(gruppe => { + return gruppe.gruppe_kurzbz.toLowerCase().includes(query); + }).map(gruppe => ({ + label: gruppe.bezeichnung + ? `${gruppe.gruppe_kurzbz.trim()} (${gruppe.bezeichnung})` + : gruppe.gruppe_kurzbz.trim(), + gid: gruppe.gid, + gruppe_kurzbz: gruppe.gruppe_kurzbz.trim(), + lehrverband: gruppe.lehrverband, + })); + }, + reload() { + this.$refs.table.reloadTable(); + }, + addGroup() + { + let newData = { + 'gid': this.selectedGroup.gid, + 'lehreinheit_id': this.lehreinheit_id, + 'lehrverband': this.selectedGroup.lehrverband, + 'gruppe_kurzbz' : this.selectedGroup.gruppe_kurzbz + } + + return this.$api.call(ApiGruppe.add(newData)) + .then(result => { + this.reload() + this.selectedGroup = '' + }) + .catch(this.$fhcAlert.handleSystemError); + }, + deleteLVPlan(lehreinheitgruppe_id) + { + let deleteData = { + 'lehreinheitgruppe_id': lehreinheitgruppe_id, + 'lehreinheit_id': this.lehreinheit_id + } + + this.$api.call(ApiGruppe.deleteFromLVPlan(deleteData)) + .then(response => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete')); + }) + .catch(this.$fhcAlert.handleSystemError) + .finally(()=> { + this.reload(); + }) + }, + deleteGroup(lehreinheitgruppe_id) + { + let deleteData = { + 'lehreinheitgruppe_id': lehreinheitgruppe_id, + 'lehreinheit_id': this.lehreinheit_id + } + + this.$api.call(ApiGruppe.delete(deleteData)) + .then(response => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete')); + }) + .catch(this.$fhcAlert.handleSystemError) + .finally(()=> { + this.reload(); + }) + }, + }, + template: ` + + + + + ` +}; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/LVVerwaltung.js b/public/js/components/LVVerwaltung/LVVerwaltung.js new file mode 100644 index 000000000..772af5a47 --- /dev/null +++ b/public/js/components/LVVerwaltung/LVVerwaltung.js @@ -0,0 +1,282 @@ +import CoreSearchbar from "../searchbar/searchbar.js"; +import VerticalSplit from "../verticalsplit/verticalsplit.js"; +import StvVerband from "../Stv/Studentenverwaltung/Verband.js"; +import StvStudiensemester from "../Stv/Studentenverwaltung/Studiensemester.js"; +import LvTable from "./Setup/Table.js"; +import LvTabs from "./Setup/Tabs.js"; + +import ApiDetails from "../../api/lehrveranstaltung/details.js"; +import ApiLektor from "../../api/lehrveranstaltung/lektor.js"; +import ApiGruppe from "../../api/lehrveranstaltung/gruppe.js"; +import ApiStudiengangTree from "../../api/lehrveranstaltung/studiengangtree.js"; +import ApiSearchbar from "../../api/factory/searchbar.js"; + + +export default { + name: "LVVerwaltung", + components: { + CoreSearchbar, + VerticalSplit, + StvVerband, + StvStudiensemester, + LvTable, + LvTabs, + }, + props: { + defaultSemester: String, + lvRoot: String, + permissions: Object, + config: Object + }, + computed: { + type(){ + return this.$route.params.type + } + }, + provide() { + return { + currentSemester: Vue.computed(() => this.studiensemesterKurzbz), + dropdowns: this.dropdowns, + configShowVertragsdetails: this.config.showVertragsdetails, + configShowGewichtung: this.config.showGewichtung, + lehreinheitAnmerkungDefault: this.config.lehreinheitAnmerkungDefault, + lehreinheitRaumtypDefault: this.config.lehreinheitRaumtypDefault, + lehreinheitRaumtypAlternativeDefault: this.config.lehreinheitRaumtypAlternativeDefault, + + permissionLehrveranstaltung: this.permissions['lehre/lehrveranstaltung'], + permissionGruppenEntfernen: this.permissions['lv-plan/gruppenentfernen'], + permissionLektorEntfernen: this.permissions['lv-plan/lektorentfernen'], + } + }, + mounted() { + this.updateFilter(this.$route); + }, + watch: { + '$route'(to) { + this.updateFilter(to); + }, + }, + data() { + return { + selected: [], + studiensemesterKurzbz: this.defaultSemester, + stg: "", + filter: {}, + endpoint: ApiStudiengangTree, + dropdowns: { + studiensemester_array: [], + sprachen_array: [], + lehrform_array: [], + raumtyp_array: [], + lektor_array: [], + gruppen_array: [], + benutzer_array: [], + }, + selectedStudiengang: '', + searchbaroptions: { + cssclass: "position-relative", + calcheightonly: true, + types: [ + "mitarbeiter" + ], + actions: { + employee: { + defaultaction: { + type: "function", + action: (data) => { + this.onSelectEmployee(data.uid); + } + }, + childactions: [ + ] + }, + } + }, + } + }, + methods: { + updateFilter(route) + { + let filter = { ...route.params, ...route.query }; + if (!filter.activeFilter) + { + if (filter.emp) + { + filter.activeFilter = 'employee'; + } + else if (filter.stg) + { + filter.activeFilter = 'verband'; + } + } + this.filter = filter; + }, + handleRowClicked(data) + { + this.selected = data + }, + onSelectEmployee(emp) + { + let stg = this.stg === '' ? null : this.stg; + + this.$router.push({ + name: 'byEmp', + params: { emp, stg, activeFilter: 'employee'}, + }); + }, + + onSelectVerband({link}) + { + let stg = null; + let semester = null; + + if (typeof link === 'number') + stg = link; + else if (typeof link === 'string') + { + [stg, semester] = link.split('/'); + } + + this.stg = stg; + + if (this.filter && this.filter.emp) + { + this.$router.push({ + name: 'byEmp', + params: { emp: this.filter.emp, stg, activeFilter: 'employee' }, + }); + } + else + { + this.$router.push({ + name: 'byStg', + params: { stg, semester, activeFilter: 'verband' }, + }); + } + + this.selected = []; + }, + resetEmployeeFilter() + { + const newParams = { ...this.$route.params, activeFilter: 'verband' }; + if (newParams.stg === '') + this.$router.replace({ name: 'index' }); + else + { + delete newParams.emp; + newParams.semester = null; + this.$router.replace({ name: 'byStg', params: newParams }); + + } + }, + searchfunction(params) { + return this.$api.call(ApiSearchbar.search(params)); + }, + studiensemesterChanged(newValue) { + this.studiensemesterKurzbz = newValue; + this.$refs.lvTable.reload(); + this.selected = []; + }, + }, + created() { + if (this.$route.params.stg !== undefined) + { + this.selectedStudiengang = this.$route.params?.semester !== '' && this.$route.params?.semester + ? `${this.$route.params.stg}/${this.$route.params.semester}` + : this.$route.params.stg; + } + + this.$p.loadCategory(['lehre', 'person']) + + this.$api.call(ApiDetails.getStudiensemester()) + .then(result => { + this.dropdowns.studiensemester_array = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$api.call(ApiDetails.getSprache()) + .then(result => { + this.dropdowns.sprachen_array = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$api.call(ApiDetails.getLehrform()) + .then(result => { + this.dropdowns.lehrform_array = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$api.call(ApiDetails.getRaumtyp()) + .then(result => { + this.dropdowns.raumtyp_array = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$api.call(ApiLektor.getLehrfunktionen()) + .then(result => { + this.dropdowns.lehrfunktion_array = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$api.call(ApiLektor.getLektoren()) + .then(result => { + this.dropdowns.lektor_array = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$api.call(ApiGruppe.getAll()) + .then(result => { + this.dropdowns.gruppen_array = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + this.$api.call(ApiGruppe.getBenutzer()) + .then(result => { + this.dropdowns.benutzer_array = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + }, + + template: ` +
+ +
+
+ + +
+ + + + +
+
+
+
` +}; diff --git a/public/js/components/LVVerwaltung/Lektor/Daten.js b/public/js/components/LVVerwaltung/Lektor/Daten.js new file mode 100644 index 000000000..bb40f56fe --- /dev/null +++ b/public/js/components/LVVerwaltung/Lektor/Daten.js @@ -0,0 +1,270 @@ +import {CoreFilterCmpt} from "../../filter/Filter.js"; +import CoreForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; +import ApiLektor from "../../../api/lehrveranstaltung/lektor.js"; + +export default{ + name: "LVLektorDaten", + components: { + CoreFilterCmpt, + CoreForm, + FormInput + }, + props: { + lehreinheit_id: Number, + mitarbeiter_uid: String + }, + emits: [ + 'changedLektor', + 'changedCosts', + ], + inject: { + dropdowns: { + from: 'dropdowns' + } + }, + + data() { + return{ + original: null, + data: null, + changed: {}, + internal_mitarbeiter_uid: null, + filteredLektor: [], + } + }, + computed: { + changedLength() { + return Object.keys(this.changed).length; + }, + berechneteGesamtkosten() { + if (!this.data) return 0; + + const stunden = Number(this.data.semesterstunden) || 0; + const stundensatz = Number(this.data.stundensatz) || 0; + + return (stunden * stundensatz).toFixed(2); + } + }, + watch: { + lehreinheit_id: + { + deep: true, + handler(newVal, oldVal) { + this.data = null; + this.original = null; + this.internal_mitarbeiter_uid = null; + } + }, + mitarbeiter_uid: + { + deep: true, + handler(newVal, oldVal) { + this.internal_mitarbeiter_uid = newVal; + + if (newVal === null) + this.data = null; + else if (newVal !== undefined && this.lehreinheit_id !== undefined) + this.getLektorData(); + } + + }, + data: { + handler(newValue) { + if (newValue === null) + { + this.changed = {} + return + } + let changed = {}; + + let keys = Object.keys(this.original); + + for (let key of keys) + { + if (this.original[key] !== newValue[key]) + changed[key] = newValue[key]; + } + this.changed = changed; + }, + deep: true + }, + }, + methods: { + getLektorData() + { + if (!this.lehreinheit_id || !this.internal_mitarbeiter_uid) + return; + + return this.$api.call(ApiLektor.getLektorDaten(this.lehreinheit_id, this.internal_mitarbeiter_uid)) + .then(result => { + this.data = result.data; + this.original = { ...this.data }; + }) + .catch(this.$fhcAlert.handleSystemError); + }, + updateDaten() + { + if (!this.changedLength) + return; + + if (this.changed.mitarbeiter_uid && this.changed.mitarbeiter_uid.uid) + { + this.changed.mitarbeiter_uid = this.changed.mitarbeiter_uid.uid; + } + this.$refs.form.clearValidation(); + + let updatedData = { + lehreinheit_id: this.lehreinheit_id, + mitarbeiter_uid: this.mitarbeiter_uid, + formData: this.changed + } + this.$refs.form.call(ApiLektor.update(updatedData)) + .then(result => { + let error = result.data?.error; + if (error) + this.$fhcAlert.alertWarning(error) + this.original = {...this.data}; + + if (this.changed.mitarbeiter_uid) + { + this.$emit('changedLektor', this.changed.mitarbeiter_uid); + } + if (this.changed.semesterstunden || this.changed.stundensatz) + { + this.$emit('changedCosts'); + } + this.changed = {}; + + }) + .catch(this.$fhcAlert.handleSystemError); + }, + searchLektor(event) + { + const query = event.query.toLowerCase().trim(); + this.filteredLektor = this.dropdowns.lektor_array.filter(lektor => { + const fullName = `${lektor.vorname.toLowerCase()} ${lektor.nachname.toLowerCase()}`; + const reverseFullName = `${lektor.nachname.toLowerCase()} ${lektor.vorname.toLowerCase()}`; + return fullName.includes(query) || reverseFullName.includes(query) || lektor.uid.toLowerCase().includes(query); + }).map(lektor => ({ + label: `${lektor.nachname} ${lektor.vorname} (${lektor.uid})`, + uid: lektor.uid + })); + }, + + }, + created() { + this.getLektorData() + }, + template: ` + +
+ +
+
+ {{$p.t('lehre', 'daten')}} + + +
+
+ ` +}; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/Lektor/Table.js b/public/js/components/LVVerwaltung/Lektor/Table.js new file mode 100644 index 000000000..373a8955c --- /dev/null +++ b/public/js/components/LVVerwaltung/Lektor/Table.js @@ -0,0 +1,223 @@ +import {CoreFilterCmpt} from "../../filter/Filter.js"; +import FormForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; +import ApiLektor from "../../../api/lehrveranstaltung/lektor.js"; + + +export default{ + name: "LVLektorTable", + components: { + CoreFilterCmpt, + FormForm, + FormInput + }, + props: { + lehreinheit_id: Number, + selected: String + }, + inject: { + dropdowns: { + from: 'dropdowns' + }, + showLVPlanLektorDel: { + from: 'permissionLektorEntfernen', + default: false + }, + }, + emits: ['update:selected'], + + data() { + return { + tabulatorEvents: [ + { + event: 'rowSelectionChanged', + handler: this.lektorSelected + } + ], + showAutocomplete: false, + filteredLektor: [], + selectedLektor: '' + } + }, + computed: { + tabulatorOptions() { + return { + + ajaxURL: 'dummy', + ajaxRequestFunc: () => this.$api.call(ApiLektor.getByLehreinheit(this.lehreinheit_id)), + ajaxResponse: (url, params, response) => { return response.data || [] }, + columns:[ + {title: this.$p.t('person', 'nachname'), field:"nachname"}, + {title: this.$p.t('person', 'vorname'), field:"vorname"}, + {title: this.$p.t('person', 'uid'), field:"mitarbeiter_uid"}, + {title: this.$p.t('lehre', 'lehreinheit_id'), field:"lehreinheit_id"}, + { + title: this.$p.t('lehre', 'verplant'), + field:"verplant", + formatter:"tickCross", + hozAlign:"center", + formatterParams: { + tickElement: '', + crossElement: '' + } + }, + { + title: this.$p.t('global', 'actions'), field: 'actions', + minWidth: 150, + formatter: (cell, formatterParams, onRendered) => { + let container = document.createElement('div'); + let button = document.createElement('button'); + + container.className = "d-flex gap-2"; + + button.className = 'btn btn-outline-secondary btn-action'; + button.innerHTML = ''; + button.title = this.$p.t('ui', 'loeschen'); + button.addEventListener('click', (event) => { + event.stopPropagation(); + this.deletePerson(cell.getData().mitarbeiter_uid, cell.getData().lehreinheit_id); + }); + + container.append(button); + if (this.showLVPlanLektorDel) + { + button = document.createElement('button'); + button.className = 'btn btn-outline-secondary btn-action'; + button.innerHTML = ''; + button.disabled = !cell.getData().verplant; + button.title = this.$p.t('ui', 'auslvplanentfernen'); + button.addEventListener('click', (event) => { + event.stopPropagation(); + this.deleteLVPlan(cell.getData().mitarbeiter_uid, cell.getData().lehreinheit_id) + }); + container.append(button); + } + + return container; + }, + frozen: true + }, + ], + layout: 'fitDataFill', + height: 'auto', + selectable: true, + selectableRangeMode: 'click', + selectableRows:1, + persistenceID: 'lehrveranstaltungen_lektor_table_2025_05_27_v1', + }}, + }, + mounted(){ + }, + watch: { + lehreinheit_id() { + this.$refs.table.tabulator.setData('api/frontend/v1/lv/lektor/getLektorenByLE/' + encodeURIComponent(this.lehreinheit_id)); + }, + }, + methods:{ + lektorSelected(data) + { + if (data.length > 0) + { + let mitarbeiter_uid = data[0].mitarbeiter_uid; + this.$emit('update:selected', mitarbeiter_uid); + } + else + { + this.$emit('update:selected', null); + } + }, + reload() { + this.$refs.table.reloadTable(); + }, + + deleteLVPlan(uid, lehreinheit_id) + { + let deleteData = { + 'mitarbeiter_uid': uid, + 'lehreinheit_id': lehreinheit_id, + } + + this.$api.call(ApiLektor.deleteFromLVPlan(deleteData)) + .then(response => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete')); + }) + .catch(this.$fhcAlert.handleSystemError) + .finally(()=> { + this.reload(); + }) + }, + deletePerson(uid, lehreinheit_id) + { + let deleteData = { + 'mitarbeiter_uid': uid, + 'lehreinheit_id': lehreinheit_id, + } + + this.$api.call(ApiLektor.deletePerson(deleteData)) + .then(response => { + this.$fhcAlert.alertSuccess(this.$p.t('ui', 'successDelete')); + this.reload(); + }) + .catch(this.$fhcAlert.handleSystemError) + .finally(()=> { + + }) + }, + searchLektor(event) + { + const query = event.query.toLowerCase().trim(); + this.filteredLektor = this.dropdowns.lektor_array.filter(lektor => { + const fullName = `${lektor.vorname.toLowerCase()} ${lektor.nachname.toLowerCase()}`; + const reverseFullName = `${lektor.nachname.toLowerCase()} ${lektor.vorname.toLowerCase()}`; + return fullName.includes(query) || reverseFullName.includes(query) || lektor.uid.toLowerCase().includes(query); + }).map(lektor => ({ + label: `${lektor.nachname} ${lektor.vorname} (${lektor.uid})`, + uid: lektor.uid + })); + }, + addLektor() + { + let newData = { + 'mitarbeiter_uid': this.selectedLektor.uid, + 'lehreinheit_id': this.lehreinheit_id + } + + this.$api.call(ApiLektor.add(newData)) + .then(result => { + this.reload() + this.selectedLektor = '' + }) + .catch(this.$fhcAlert.handleSystemError); + }, + + }, + template: ` + + + + +` +}; + + diff --git a/public/js/components/LVVerwaltung/Lektor/Vertrag.js b/public/js/components/LVVerwaltung/Lektor/Vertrag.js new file mode 100644 index 000000000..f36fad8e0 --- /dev/null +++ b/public/js/components/LVVerwaltung/Lektor/Vertrag.js @@ -0,0 +1,161 @@ +import {CoreFilterCmpt} from "../../filter/Filter.js"; +import CoreForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; +import ApiVertrag from "../../../api/lehrveranstaltung/vertrag.js"; + +export default{ + name: "LVLektorVertrag", + components: { + CoreFilterCmpt, + CoreForm, + FormInput + }, + emits: [ + 'canceledVertrag' + ], + props: { + lehreinheit_id: Number, + mitarbeiter_uid: String + }, + + inject: { + dropdowns: { + from: 'dropdowns' + }, + showVertragsdetails: { + from: 'configShowVertragsdetails', + default: false + } + }, + + data() { + return{ + data: null, + internal_mitarbeiter_uid: null, + } + }, + watch: { + lehreinheit_id: + { + deep: true, + handler(newVal, oldVal) { + this.data = null; + this.internal_mitarbeiter_uid = null; + } + + }, + mitarbeiter_uid: + { + deep: true, + handler(newVal, oldVal) { + this.internal_mitarbeiter_uid = newVal; + + if (newVal === null) + this.data = null; + else if (newVal !== undefined && this.lehreinheit_id !== undefined) + this.getLektorVertrag(); + } + }, + }, + computed: { + vertragsstatus() { + if (!this.data || !this.data.vertrag) return; + + const betragVertrag = Number(this.data.vertrag.betrag) || 0; + const stundenVertrag = Number(this.data.vertrag.vertragsstunden) || 0; + + const semStunden = Number(this.data.semesterstunden) || 0; + const stundensatz = Number(this.data.stundensatz) || 0; + + const kostenAktuell = semStunden * stundensatz; + + return (stundenVertrag !== semStunden || betragVertrag !== kostenAktuell) ? 'Geändert' : (this.data.vertrag.vertragsstatus || ''); + }, + }, + methods: { + getLektorVertrag () + { + if (this.showVertragsdetails === false) + return; + + if (!this.lehreinheit_id || !this.internal_mitarbeiter_uid) + return; + + this.$api.call(ApiVertrag.getByLeEmp(this.lehreinheit_id, this.internal_mitarbeiter_uid)) + .then(result => { + this.data = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + }, + + cancelVertrag() + { + let needUpdate = { + vertrag_id: this.data.vertrag.vertrag_id, + mitarbeiter_uid: this.mitarbeiter_uid, + lehreinheit_id: this.lehreinheit_id + } + this.$api.call(ApiVertrag.cancelByLeEmp(needUpdate)) + .then(result => { + this.data.vertrag = null; + this.$emit('canceledVertrag'); + }) + .catch(this.$fhcAlert.handleSystemError); + }, + }, + // language=HTML + template: ` + +
+ {{$p.t('lehre', 'vertragsdetails')}} + {{ data === null ? ' – Noch kein Vertrag' : '' }} + + +
+
+ ` +}; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/Setup/Table.js b/public/js/components/LVVerwaltung/Setup/Table.js new file mode 100644 index 000000000..9b0ae71f3 --- /dev/null +++ b/public/js/components/LVVerwaltung/Setup/Table.js @@ -0,0 +1,683 @@ +import {CoreFilterCmpt} from "../../filter/Filter.js"; +import BsModal from "../../Bootstrap/Modal.js"; +import DetailsForm from "../Details/Form.js"; +import CoreTag from '../../Tag/Tag.js'; +import { tagHeaderFilter } from '../../../../js/tabulator/filters/extendedHeaderFilter.js'; +import { extendedHeaderFilter } from "../../../../js/tabulator/filters/extendedHeaderFilter.js"; + +import ApiLv from "../../../api/lehrveranstaltung.js"; +import ApiTag from "../../../api/lehrveranstaltung/tag.js"; +import ApiLehreinheit from "../../../api/lehrveranstaltung/lehreinheit.js"; + +export default { + name: "LVVerwaltungTable", + components: { + CoreFilterCmpt, + BsModal, + DetailsForm, + CoreTag + + }, + props: { + selected: Object, + filter: { + type: Object, + default: () => ({}) + } + }, + inject: { + currentSemester: { + from: 'currentSemester' + }, + lehreinheitAnmerkungDefault: { + from: 'lehreinheitAnmerkungDefault', + default: '' + }, + lehreinheitRaumtypDefault: { + from: 'lehreinheitRaumtypDefault', + default: '' + }, + lehreinheitRaumtypAlternativeDefault: { + from: 'lehreinheitRaumtypAlternativeDefault', + default: '' + } + }, + emits: [ + 'update:selected', + 'row-clicked' + ], + watch: { + filter: { + handler() { + if (this.$refs.table && this.$refs.table.tabulator) + { + this.expanded = []; + this.reload(); + } + }, + deep: true, + + } + }, + data() { + return { + fieldTitleMap: { + lv_kurzbz: ['lehre', 'kurzbz'], + tags: ['ui', 'tags'], + lehrveranstaltung_id: ['lehre', 'lehrveranstaltung_id'], + lv_bezeichnung: ['ui', 'bezeichnung'], + lv_bezeichnung_english: ['lehre', 'bezeichnungeng'], + lv_studiengang_kz: ['lehre', 'studiengangskennzahlLehre'], + studiengang: ['lehre', 'studiengang'], + semester: ['lehre', 'semester'], + sprache: ['global', 'sprache'], + lv_ects: ['lehre', 'ects'], + semesterstunden: ['lehre', 'semesterstunden'], + anmerkung: ['global', 'anmerkung'], + lehre: ['lehre', 'lehre'], + lehreverzeichnis: ['ui', 'lehreverzeichnis'], + aktiv: ['person', 'aktiv'], + planfaktor: ['ui', 'planfaktor'], + planlektoren: ['ui', 'planlektoren'], + planpersonalkosten: ['ui', 'planpersonalkosten'], + plankostenprolektor: ['ui', 'plankostenprolektor'], + orgform_kurzbz: ['lehre', 'organisationsform'], + studienplan_id: ['ui', 'studienplan_id'], + studienplan_bezeichnung: ['ui', 'studienplan_bezeichnung'], + lehrtyp_kurzbz: ['ui', 'lehrtyp_kurzbz'], + lehrform_kurzbz: ['lehre', 'lehrform'], + le_planstunden: ['lehre', 'leplanstunden'], + lehreinheit_id: ['lehre', 'lehreinheit_id'], + stundenblockung: ['lehre', 'stundenblockung'], + wochenrythmus: ['lehre', 'wochenrhytmus'], + startkw: ['lehre', 'startkw'], + raumtyp: ['lehre', 'raumtyp'], + raumtypalternativ: ['lehre', 'raumtypalternativ'], + gruppen: ['lehre', 'gruppen'], + lektoren: ['lehre', 'lehrende'], + }, + + expanded: [], + selectedColumnValues: [], + tagEndpoint: ApiTag, + iconPath: FHC_JS_DATA_STORAGE_OBJECT.app_root + '/skin/images/lehrtyp_', + tabulatorEvents: [ + { + event: 'rowSelectionChanged', + handler: this.rowSelectionChanged + }, + + { + event: 'dataProcessed', + handler: (data) => { + this.reexpandRows() + this.$emit('update:selected', {}) + } + }, + { + event: 'dataTreeRowExpanded', + handler: (data) => { + this.getExpandedRows() + } + },{ + event: 'dataTreeRowCollapsed', + handler: (data) => { + this.getExpandedRows() + } + } + + ], + formData: {}, + lv_info: false, + lv_info_default: { + stundenblockung: 2, + wochenrythmus: 1, + studiensemester_kurzbz: this.currentSemester, + lehrform_kurzbz: 'UE', + anmerkung: this.lehreinheitAnmerkungDefault.replace("'","\'"), + raumtyp: this.lehreinheitRaumtypDefault, + raumtypalternativ: this.lehreinheitRaumtypAlternativeDefault, + lehrfach_id: '' + + } + } + }, + computed: { + tabulatorOptions() { + return { + index: 'uniqueindex', + ajaxURL: 'dummy', + ajaxRequestFunc: async (url, config, params) => { + let realUrl = this.buildApiUrl(); + if (realUrl) + return this.$api.call(ApiLv.getTable(this.buildApiUrl())); + }, + ajaxResponse: (url, params, response) => { return response?.data || [] }, + dataTree: true, + initialSort:[ + {column: 'lv_bezeichnung', dir: 'desc'}, + ], + dataTreeElementColumn: "lv_kurzbz", + dataTreeFilter: true, + dataTreeStartExpanded: false, + dataTreeCollapseElement: '', + dataTreeExpandElement: '', + columnDefaults: { + tooltip: true, + headerFilter: "input", + headerFilterFunc: extendedHeaderFilter + }, + layout: 'fitDataStretch', + layoutColumnsOnNewData: false, + height: '100%', + selectableRowsRangeMode: 'click', + selectableRows: true, + rowContextMenu: (component, e) => { + + return [ + { + label: "LV-Teil kopieren", + menu: [ + { + label: "Alles", + action: (e, row) => + { + this.copyLehreinheit(row, "alle"); + }, + }, + { + label: "Nur LV-Teil", + action: (e, row) => + { + this.copyLehreinheit(row, "lvteil"); + }, + }, + { + label: "Nur mit Gruppen", + action: (e, row) => + { + this.copyLehreinheit(row, "halb"); + }, + }, + { + label: "Nur mit Lehrenden", + action: (e, row) => + { + this.copyLehreinheit(row, "lektoren"); + }, + }, + ], + }, + { + label: "Entfernen", + action: (e, row) => { + this.deleteLehreinheit(row) + }, + }, + ]; + }, + + persistenceID: 'lehrveranstaltungen_2025_05_27_v1', + columns: [ + { + title: this.$p.t('lehre', 'kurzbz'), + field: "lv_kurzbz", + headerFilterFuncParams: {field: 'lv_kurzbz'}, + headerFilter: true, + formatter: (cell, formatterParams) => { + const rowData = cell.getRow().getData(); + const iconKey = (rowData.lehrtyp_kurzbz || '').toLowerCase(); + + const span = document.createElement('span'); + span.classList.add('lv_table_icon', `icon-${iconKey}`); + span.title = iconKey || 'LV-Teil'; + return span; + }, + + cellClick: (e, cell) => { + cell.getRow().treeToggle(); + } + }, + { + title: 'Tags', + field: 'tags', + tooltip: false, + headerFilter: "input", + headerFilterFunc: tagHeaderFilter, + headerFilterFuncParams: {field: 'tags'}, + formatter: (cell) => { + let tags = cell.getValue(); + if (!tags) return; + + let container = document.createElement('div'); + container.className = "d-flex gap-1"; + + let parsedTags = JSON.parse(tags); + let maxVisibleTags = 2; + + const rowData = cell.getRow().getData(); + if (rowData._tagExpanded === undefined) { + rowData._tagExpanded = false; + } + + const renderTags = () => { + container.innerHTML = ''; + parsedTags = parsedTags.filter(item => item !== null); + const tagsToShow = rowData._tagExpanded ? parsedTags : parsedTags.slice(0, maxVisibleTags); + + tagsToShow.forEach(tag => { + if (!tag) return; + let tagElement = document.createElement('span'); + tagElement.innerText = tag.beschreibung; + tagElement.title = tag.notiz; + tagElement.className = "tag " + tag.style; + if (tag.done) tagElement.className += " tag_done"; + + tagElement.addEventListener('click', (event) => { + event.stopPropagation(); + event.preventDefault(); + this.$refs.tagComponent.editTag(tag.id); + }); + + container.appendChild(tagElement); + }); + + if (parsedTags.length > maxVisibleTags) { + let toggle = document.createElement('button'); + toggle.innerText = (rowData._tagExpanded ? '- ' : '+ ') + (parsedTags.length - maxVisibleTags); + toggle.className = "display_all"; + toggle.title = rowData._tagExpanded ? "Tags ausblenden" : "Tags einblenden"; + + toggle.addEventListener('click', () => { + rowData._tagExpanded = !rowData._tagExpanded; + renderTags(); + }); + + container.appendChild(toggle); + } + }; + + renderTags(); + return container; + }, + width: 150, + }, + { + title: this.$p.t('lehre', 'lehrveranstaltung_id'), + field: "lehrveranstaltung_id", + headerFilterFuncParams: {field: 'lehrveranstaltung_id'}, + headerFilter: true + }, + {title: this.$p.t('ui', 'bezeichnung'), field: "lv_bezeichnung", headerFilter: true, headerFilterFuncParams: {field: 'lv_bezeichnung'}}, + {title: this.$p.t('lehre', 'bezeichnungeng'), field: "lv_bezeichnung_english", headerFilter: true, headerFilterFuncParams: {field: 'lv_bezeichnung_english'}}, + { + title: this.$p.t('lehre', 'studiengangskennzahlLehre'), + field: "lv_studiengang_kz", + headerFilter: true, + headerFilterFuncParams: {field: 'lv_studiengang_kz'} + }, + {title: this.$p.t('lehre', 'studiengang'), field: "studiengang", headerFilter: true, headerFilterFuncParams: {field: 'studiengang'}}, + {title: this.$p.t('lehre', 'semester'), field: "semester", headerFilter: true, headerFilterFuncParams: {field: 'semester'}}, + {title: this.$p.t('global', 'sprache'), field: "sprache", headerFilter: true, headerFilterFuncParams: {field: 'sprache'}}, + {title: this.$p.t('lehre', 'ects'), field: "lv_ects", headerFilter: true, headerFilterFuncParams: {field: 'lv_ects'}}, + {title: this.$p.t('lehre', 'semesterstunden'), field: "semesterstunden", headerFilter: true, headerFilterFuncParams: {field: 'semesterstunden'}}, + {title: this.$p.t('global', 'anmerkung'), field: "anmerkung", headerFilter: true, headerFilterFuncParams: {field: 'anmerkung'}}, + {title: this.$p.t('lehre', 'lehre'), field: "lehre", headerFilter: true, headerFilterFuncParams: {field: 'lehre'}}, + {title: "Lehreverzeichnis", field: "lehreverzeichnis", headerFilter: true, headerFilterFuncParams: {field: 'lehreverzeichnis'}}, + {title: this.$p.t('person', 'aktiv'), field: "aktiv", headerFilter: true, headerFilterFuncParams: {field: 'aktiv'}}, + {title: "Planfaktor", field: "planfaktor", headerFilter: true, headerFilterFuncParams: {field: 'planfaktor'}}, + {title: "Planlektoren", field: "planlektoren", headerFilter: true, headerFilterFuncParams: {field: 'planlektoren'}}, + {title: "planpersonalkosten", field: "planpersonalkosten", headerFilter: true, headerFilterFuncParams: {field: 'planpersonalkosten'}}, + {title: "plankostenprolektor", field: "plankostenprolektor", headerFilter: true, headerFilterFuncParams: {field: 'plankostenprolektor'}}, + {title: this.$p.t('ui', 'organisationsform'), field: "orgform_kurzbz", headerFilter: true, headerFilterFuncParams: {field: 'orgform_kurzbz'}}, + {title: this.$p.t('ui', 'studienplan_id'), field: "studienplan_id", headerFilter: true, headerFilterFuncParams: {field: 'studienplan_id'}}, + {title: "studienplan_bezeichnung", field: "studienplan_bezeichnung", headerFilter: true, headerFilterFuncParams: {field: 'studienplan_bezeichnung'}}, + {title: "lehrtyp_kurzbz", field: "lehrtyp_kurzbz", headerFilter: true, headerFilterFuncParams: {field: 'lehrtyp_kurzbz'}}, + {title: this.$p.t('lehre', 'lehrform'), field: "lehrform_kurzbz", headerFilter: true, headerFilterFuncParams: {field: 'lehrform_kurzbz'}}, + {title: this.$p.t('lehre', 'leplanstunden'), field: "le_planstunden", headerFilter: true, headerFilterFuncParams: {field: 'le_planstunden'}}, + {title: this.$p.t('lehre', 'lehreinheit_id'), field: "lehreinheit_id", headerFilter: true, headerFilterFuncParams: {field: 'lehreinheit_id'}}, + {title: this.$p.t('lehre', 'stundenblockung'), field: "stundenblockung", headerFilter: true, headerFilterFuncParams: {field: 'stundenblockung'}}, + {title: this.$p.t('lehre', 'wochenrhytmus'), field: "wochenrythmus", headerFilter: true, headerFilterFuncParams: {field: 'wochenrythmus'}}, + {title: this.$p.t('lehre', 'startkw'), field: "startkw", headerFilter: true, headerFilterFuncParams: {field: 'startkw'}}, + {title: this.$p.t('lehre', 'raumtyp'), field: "raumtyp", headerFilter: true, headerFilterFuncParams: {field: 'raumtyp'}}, + {title: this.$p.t('lehre', 'raumtypalternativ'), field: "raumtypalternativ", headerFilter: true, headerFilterFuncParams: {field: 'raumtypalternativ'}}, + {title: this.$p.t('lehre', 'gruppen'), field: "gruppen", headerFilter: true, headerFilterFuncParams: {field: 'gruppen'}}, + {title: this.$p.t('lehre', 'lehrende'), field: "lektoren", headerFilter: true, headerFilterFuncParams: {field: 'lektoren'}}, + ], + } + + } + }, + + mounted() { + if (this.shouldAutoLoad()) + { + this.reload(); + } + }, + methods: { + shouldAutoLoad() { + return this.filter && this.filter.activeFilter; + }, + async reload() + { + + if (this.shouldAutoLoad) + { + this.$refs.table.reloadTable(); + } + }, + rowSelectionChanged(data) { + this.selectedRows = this.$refs.table.tabulator.getSelectedRows(); + this.selectedColumnValues = this.selectedRows.filter(row => row.getData().lehreinheit_id !== undefined).map(row => row.getData().lehreinheit_id); + + if (data[0]?.lehreinheit_id !== undefined && this.selectedColumnValues.length === 1) + { + this.$emit('update:selected', [data[0]]); + this.lv_info = false + } + else if (data[0]?.lehrveranstaltung_id) + { + this.$emit('update:selected', {}); + this.getLVInfos(data[0]); + } + }, + getLVInfos(data) + { + this.$api.call(ApiLv.getByLV(data.lehrveranstaltung_id)) + .then(result => { + + if (result.data?.lehrfach_id === undefined + && Array.isArray(result.data?.lehrfaecher)) + { + const match = result.data.lehrfaecher?.find( + lf => lf.lehrfach?.startsWith(result.data.lvbezeichnung) + ); + if (match) + { + result.data.lehrfach_id = match.lehrveranstaltung_id; + } + } + this.lv_info = {...this.lv_info_default, ...result.data}; + }) + .catch(this.$fhcAlert.handleSystemError); + }, + buildApiUrl() + { + if (this.filter.activeFilter === 'employee' && this.filter.emp) + { + return this.$api.getUri(ApiLv.getByEmpStg( + this.filter.emp, + this.filter.stg + )); + } + + if (this.filter.activeFilter === 'verband' && this.filter.stg) + { + return this.$api.getUri(ApiLv.getByStg( + this.filter.stg, + this.filter.semester + )); + } + }, + resetEmployeeFilter() + { + const newFilter = { ...this.filter }; + delete newFilter.emp; + newFilter.activeFilter = 'verband'; + }, + buildParams() + { + const params = {}; + for (const [key, value] of Object.entries(this.filter)) { + if (value !== undefined && value !== null) { + params[key] = value; + } + } + return params; + }, + showLehreinheitModal() { + this.resetModal(); + this.$refs.lehreinheitModal.show(); + }, + addNewLehreinheit() + { + return this.$api.call(ApiLehreinheit.add(this.lv_info)) + .then(result => { + this.$refs.lehreinheitModal.hide() + this.reload() + }) + .catch(this.$fhcAlert.handleSystemError); + }, + resetModal() + { + this.lv_info_default = { + stundenblockung: 2, + wochenrythmus: 1, + studiensemester_kurzbz: this.currentSemester, + lehrform_kurzbz: 'UE', + anmerkung: this.lehreinheitAnmerkungDefault.replace("'","\'"), + raumtyp: this.lehreinheitRaumtypDefault, + raumtypalternativ: this.lehreinheitRaumtypAlternativeDefault, + lehrfach_id: '' + } + }, + addedTag(addedTag) + { + const table = this.$refs.table.tabulator; + + this.selectedRows.forEach(row => + { + if (Array.isArray(addedTag.response)) + { + addedTag.response.forEach(tag => { + + const all = this.getAllRows(table.getRows()); + const targetRow = all.find(row => row.getData().lehreinheit_id === tag.lehreinheit_id); + if (targetRow) + { + const rowData = targetRow.getData(); + let tags = []; + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + const tagExists = tags.some((t) => t.id === tag.id); + if (!tagExists) + { + addedTag.id = tag.id; + tags.push({ ...addedTag }); + targetRow.update({ tags: JSON.stringify(tags) }); + targetRow.reformat(); + } + } + }); + } + }); + }, + deletedTag(deletedTag) { + const table = this.$refs.table.tabulator; + const all = this.getAllRows(table.getRows()); + + const targetRow = all.find(row => { + const rowData = row.getData(); + + let tags = []; + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + return tags.some(tag => tag.id === deletedTag); + }); + + if (targetRow) { + const rowData = targetRow.getData(); + let tags = []; + + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + const filteredTags = tags.filter(t => t.id !== deletedTag); + const updatedTags = JSON.stringify(filteredTags); + + if (updatedTags !== rowData.tags) { + targetRow.update({ + tags: updatedTags + }); + + targetRow.reformat(); + } + } + }, + + updatedTag(updatedTag) { + const table = this.$refs.table.tabulator; + const all = this.getAllRows(table.getRows()); + + const targetRow = all.find(row => { + const rowData = row.getData(); + let tags = []; + + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + return tags.some(t => t?.id === updatedTag.id); + }); + + if (targetRow) + { + const rowData = targetRow.getData(); + let tags = []; + try { + tags = JSON.parse(rowData.tags || '[]'); + } catch (e) {} + + let changed = false; + + const tagIndex = tags.findIndex(tag => tag?.id === updatedTag.id); + if (tagIndex !== -1) { + tags[tagIndex] = { ...updatedTag }; + changed = true; + } + + if (changed) + { + targetRow.update({ + tags: JSON.stringify(tags), + }); + targetRow.reformat(); + } + } + }, + async copyLehreinheit(row, art) + { + let data = { + lehreinheit_id: row.getData().lehreinheit_id, + art: art + } + + return this.$api.call(ApiLehreinheit.copy(data)) + .then(result => { + this.reload() + }) + .catch(this.$fhcAlert.handleSystemError) + }, + + async getExpandedRows() { + this.expanded = []; + let rows = this.$refs.table.tabulator.getRows(); + let allRows = this.getAllRows(rows); + allRows.forEach(row => { + if (row.getTreeChildren().length > 0 && row.isTreeExpanded()) + { + this.expanded.push(row.getData().uniqueindex); + } + }); + }, + reexpandRows() { + const all = this.getAllRows(this.$refs.table.tabulator.getRows()); + + const matchingRows = all.filter(row => + this.expanded.includes(row.getData().uniqueindex) + ); + + matchingRows.forEach((row, index) => { + row._row.modules.dataTree.open = true; + + if (index === matchingRows.length - 1) + { + row.treeExpand(); + } + }); + }, + deleteLehreinheit(row) + { + let deleteData = { + lehreinheit_id: row.getData().lehreinheit_id, + } + return this.$api.call(ApiLehreinheit.delete(deleteData)) + .then(result => { + this.reload() + }) + .catch(this.$fhcAlert.handleSystemError); + }, + getAllRows(rows) + { + let result = []; + rows.forEach(row => + { + result.push(row); + let children = row.getTreeChildren(); + if(children && children.length > 0) + { + result = result.concat(this.getAllRows(children)); + } + }); + return result; + }, + }, + template: ` + + + + + + + + + + + + + +` +}; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/Setup/Tabs.js b/public/js/components/LVVerwaltung/Setup/Tabs.js new file mode 100644 index 000000000..af14fbf32 --- /dev/null +++ b/public/js/components/LVVerwaltung/Setup/Tabs.js @@ -0,0 +1,62 @@ +import FhcTabs from "../../Tabs.js"; +import Setup from "../../../api/lehrveranstaltung/setup.js"; + +export default { + name: "LVVerwaltungTabs", + components: { + FhcTabs + }, + data() { + return { + configLVTabs: {}, + }; + }, + props: { + lv: Object + }, + computed: { + config() { + if (!this.lv || !this.lv.length) + return {}; + + return this.configLVTabs; + } + }, + methods: { + reload() { + if (this.$refs.tabs?.$refs?.current?.reload) + { + this.$refs.tabs.$refs.current.reload(); + } + } + }, + created() { + this.$api.call(Setup.getTabs()) + .then(result => { + this.configLVTabs = result.data; + }) + .catch(this.$fhcAlert.handleSystemError); + + }, + template: ` +
+
+ Bitte eine Lehreinheit auswählen! +
+
+ +
+
+ Loading... +
+
+ ` +}; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/Tabs/Details.js b/public/js/components/LVVerwaltung/Tabs/Details.js new file mode 100644 index 000000000..ce0102177 --- /dev/null +++ b/public/js/components/LVVerwaltung/Tabs/Details.js @@ -0,0 +1,133 @@ +import CoreForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; +import GruppenTable from '../Details/Gruppen.js'; +import GruppenDirektTable from '../Details/Direktinskription.js'; +import DetailsForm from '../Details/Form.js' +import ApiLehreinheit from "../../../api/lehrveranstaltung/lehreinheit.js"; + +export default { + name: "LVTabDetails", + components: { + CoreForm, + FormInput, + GruppenTable, + GruppenDirektTable, + DetailsForm + }, + props: { + modelValue: Object, + config: { + type: Object, + default: {} + }, + }, + inject: { + dropdowns: { + from: 'dropdowns' + } + }, + watch: { + modelValue(newValue) + { + this.updateLE(newValue) + }, + data: { + handler(newValue) { + if (newValue === null) + { + this.changed = {} + return + } + let changed = {}; + + let keys = Object.keys(this.original); + + for (let key of keys) { + if (this.original[key] !== newValue[key]) + { + changed[key] = newValue[key]; + } + } + this.changed = changed; + }, + deep: true + } + }, + data() { + return { + original: null, + data: null, + changed: {} + } + }, + computed: { + changedLength() { + return Object.keys(this.changed).length; + } + }, + + methods: { + updateLE(le) { + if (le?.lehreinheit_id === undefined) + { + this.data = null; + return; + } + return this.$api.call(ApiLehreinheit.get(le.lehreinheit_id)) + .then(result => { + this.data = result.data; + this.original = {...(this.original || {}), ...this.data}; + }) + .catch(this.$fhcAlert.handleSystemError); + }, + save() { + if (!this.changedLength) + return; + this.$refs.form.clearValidation(); + + let updatedData = { + lehreinheit_id: this.modelValue.lehreinheit_id, + formData: this.changed + } + return this.$refs.form.call(ApiLehreinheit.update(updatedData)) + .then(result => { + this.original = {...this.data}; + this.changed = {}; + this.$refs.form.setFeedback(true, result.data); + }) + .catch(this.$fhcAlert.handleSystemError); + + }, + reload(){ + this.updateLE(this.modelValue); + } + }, + created() { + this.updateLE(this.modelValue); + }, + template: ` + +
+ +
+
+ {{this.$p.t('lehre', 'lehreinheit')}} + +
+
+
+
+
+ {{this.$p.t('lehre', 'gruppen')}} + +
+
+ {{this.$p.t('lehre', 'assignedPersons')}} + +
+
+ +
` +}; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/Tabs/Lektor.js b/public/js/components/LVVerwaltung/Tabs/Lektor.js new file mode 100644 index 000000000..99e1edb9e --- /dev/null +++ b/public/js/components/LVVerwaltung/Tabs/Lektor.js @@ -0,0 +1,70 @@ +import CoreForm from '../../Form/Form.js'; +import FormInput from '../../Form/Input.js'; +import LektorTable from '../Lektor/Table.js' +import LektorDaten from '../Lektor/Daten.js' +import LektorVertrag from '../Lektor/Vertrag.js' +export default { + name: "LVTabLektor", + components: { + CoreForm, + FormInput, + LektorTable, + LektorDaten, + LektorVertrag + }, + props: { + modelValue: Object, + config: { + type: Object, + default: {} + }, + }, + data() { + return { + mitarbeiter_uid: null + } + }, + methods: { + changedLektor(uid) { + const lektorTable = this.$refs.lektor_table; + const tabulator = lektorTable.$refs.table.tabulator; + + const selectUID = () => { + let row = tabulator.getRows().find(r => r.getData().mitarbeiter_uid === uid); + if (row) + { + row.select(); + } + tabulator.off('dataProcessed', selectUID); + }; + tabulator.on('dataProcessed', selectUID); + lektorTable.reload(); + }, + changedCosts() { + this.$refs.lektor_vertrag?.getLektorVertrag(); + }, + canceledVertrag() { + this.$refs.lektor_daten?.getLektorData(); + } + }, + template: ` +
+
+
+ {{ $p.t('lehre', 'lektorInnen')}} + +
+
+ +
+
+
+
+
+
+ +
+
+
+ ` +}; \ No newline at end of file diff --git a/public/js/components/LVVerwaltung/Tabs/Notiz.js b/public/js/components/LVVerwaltung/Tabs/Notiz.js new file mode 100644 index 000000000..6bccf5c52 --- /dev/null +++ b/public/js/components/LVVerwaltung/Tabs/Notiz.js @@ -0,0 +1,33 @@ +import CoreNotiz from "../../Notiz/Notiz.js"; +import ApiNotizLehreinheit from '../../../api/factory/notiz/lehreinheit.js'; +export default { + name: "LVTabNotiz", + components: { + CoreNotiz + }, + props: { + modelValue: Object + }, + data() { + return { + endpoint: ApiNotizLehreinheit + }; + }, + template: ` +
+ + +
+ ` +}; \ No newline at end of file diff --git a/public/js/components/Stv/Studentenverwaltung.js b/public/js/components/Stv/Studentenverwaltung.js index 248cfd55c..cc224480f 100644 --- a/public/js/components/Stv/Studentenverwaltung.js +++ b/public/js/components/Stv/Studentenverwaltung.js @@ -24,6 +24,7 @@ import StvStudiensemester from "./Studentenverwaltung/Studiensemester.js"; import ApiSearchbar from "../../api/factory/searchbar.js"; import ApiStv from "../../api/factory/stv.js"; +import ApiStvVerband from '../../api/factory/stv/verband.js'; export default { @@ -70,6 +71,7 @@ export default { }, data() { return { + endpoint: ApiStvVerband, selected: [], searchbaroptions: { cssclass: "position-relative", @@ -220,7 +222,7 @@ export default {
- +
diff --git a/public/js/components/Stv/Studentenverwaltung/Verband.js b/public/js/components/Stv/Studentenverwaltung/Verband.js index 8ae2b6b40..c60242511 100644 --- a/public/js/components/Stv/Studentenverwaltung/Verband.js +++ b/public/js/components/Stv/Studentenverwaltung/Verband.js @@ -5,8 +5,6 @@ import PvTree from "../../../../../index.ci.php/public/js/components/primevue/tr import PvTreetable from "../../../../../index.ci.php/public/js/components/primevue/treetable/treetable.esm.min.js"; import PvColumn from "../../../../../index.ci.php/public/js/components/primevue/column/column.esm.min.js"; -import ApiStvVerband from '../../../api/factory/stv/verband.js'; - export default { components: { PvTree, @@ -16,11 +14,22 @@ export default { emits: [ 'selectVerband' ], + props: { + endpoint: { + type: Object, + required: true, + }, + preselectedKey: { + type: String, + default: null + } + }, data() { return { loading: true, nodes: [], selectedKey: [], + expandedKeys: {}, filters: {}, // TODO(chris): filter only 1st level? favnodes: [], favorites: {on: false, list: []} @@ -44,7 +53,7 @@ export default { return res.pop(); return null; }, - onExpandTreeNode(node) { + async onExpandTreeNode(node) { if (!node.children) { if (node.data.link) { let activeEl = null; @@ -55,8 +64,8 @@ export default { }); this.loading = true; - this.$api - .call(ApiStvVerband.get(node.data.link)) + return this.$api + .call(this.endpoint.get(node.data.link)) .then(result => result.data) .then(result => { const subNodes = result.map(this.mapResultToTreeData); @@ -68,7 +77,7 @@ export default { let treeitem = this.$refs.tree.$el.querySelector('[data-tree-item-key="' + node.key + '"]'); treeitem = treeitem.closest('[role="row"]'); - + this.$nextTick(() => { if (activeEl == document.activeElement) treeitem.dispatchEvent(new KeyboardEvent('keydown', { @@ -108,7 +117,7 @@ export default { } this.favorites.on = !this.favorites.on; this.$api - .call(ApiStvVerband.favorites.set( + .call(this.endpoint.favorites.set( JSON.stringify(this.favorites) )); this.loading = false; @@ -135,7 +144,7 @@ export default { for (let parent in sortedInParents) promises.push( this.$api - .call(ApiStvVerband.get(parent == '_' ? '' : parent)) + .call(this.endpoint.get(parent == '_' ? '' : parent)) .then(res => res.data) .then(res => res.filter(node => sortedInParents[parent].includes(node.link + ''))) ); @@ -160,9 +169,9 @@ export default { this.favnodes.push((await this.loadNodes([key.data.link])).pop()); this.favorites.list.push(key.data.link + ''); } - + this.$api - .call(ApiStvVerband.favorites.set( + .call(this.endpoint.favorites.set( JSON.stringify(this.favorites) )); }, @@ -181,19 +190,54 @@ export default { let items = e.target.querySelectorAll('[data-link-fav-add][tabindex="-1"]'); items.forEach(el => el.tabIndex = 0); } + }, + async setPreselection() + { + if (!this.preselectedKey) + return; + + let rawKey = this.preselectedKey + + if (!rawKey || typeof rawKey !== 'string') + return; + + const parts = this.preselectedKey.split('/'); + let currentKey = parts[0]; + let currentNode = this.findNodeByKey(currentKey); + + if (!currentNode) + return; + + for (let i = 1; i < parts.length; i++) + { + this.expandedKeys[currentNode.key] = true; + + await this.onExpandTreeNode(currentNode); + + currentKey += '-' + parts[i]; + currentNode = this.findNodeByKey(currentKey); + + if (!currentNode) + { + return; + } + } + + this.selectedKey = { [currentNode.key]: true }; } }, mounted() { this.$api - .call(ApiStvVerband.get()) + .call(this.endpoint.get()) .then(result => { this.nodes = result.data.map(this.mapResultToTreeData); + this.setPreselection(); this.loading = false; }) .catch(this.$fhcAlert.handleSystemError); this.$api - .call(ApiStvVerband.favorites.get()) + .call(this.endpoint.favorites.get()) .then(result => { if (result.data) { let f = JSON.parse(result.data); @@ -218,6 +262,7 @@ export default { :value="filteredNodes" @node-expand="onExpandTreeNode" selection-mode="single" + v-model:expanded-keys="expandedKeys" v-model:selection-keys="selectedKey" @node-select="onSelectTreeNode" scrollable diff --git a/public/js/components/Tag/Tag.js b/public/js/components/Tag/Tag.js index c7552a5a9..a3243ed47 100644 --- a/public/js/components/Tag/Tag.js +++ b/public/js/components/Tag/Tag.js @@ -57,7 +57,7 @@ export default { init() { if (!this.endpoint) return; - this.endpoint.getTags() + this.$api.call(this.endpoint.getTags()) .then(response => response.data) .then(response => { this.tags = response @@ -71,7 +71,7 @@ export default { 'id': tag_id }; - this.endpoint.getTag(getData) + this.$api.call(this.endpoint.getTag(getData)) .then(result => result.data) .then(result => this.openModal(result)) }, @@ -118,7 +118,7 @@ export default { { postData.id = this.selectedTagId; this.tagData.id = this.selectedTagId; - this.endpoint.updateTag(postData); + this.$api.call(this.endpoint.updateTag(postData)); this.$emit("updated", this.tagData); this.$refs.tagModal.hide(); } @@ -130,7 +130,7 @@ export default { return; } - this.endpoint.addTag(postData) + this.$api.call(this.endpoint.addTag(postData)) .then(response => response.data) .then(response => { if (typeof response === 'number') { @@ -156,7 +156,7 @@ export default { id: this.selectedTagId, done: !this.tagData.done } - this.endpoint.doneTag(postData) + this.$api.call(this.endpoint.doneTag(postData)) this.$emit("updated", this.tagData); this.$refs.tagModal.hide(); }, @@ -165,7 +165,7 @@ export default { let postData = { id: this.selectedTagId } - this.endpoint.deleteTag(postData) + this.$api.call(this.endpoint.deleteTag(postData)) this.$emit("deleted", this.selectedTagId) this.$refs.tagModal.hide(); }, diff --git a/public/js/tabulator/filters/extendedHeaderFilter.js b/public/js/tabulator/filters/extendedHeaderFilter.js index e15f8d9ac..5dfcce205 100644 --- a/public/js/tabulator/filters/extendedHeaderFilter.js +++ b/public/js/tabulator/filters/extendedHeaderFilter.js @@ -39,7 +39,7 @@ function parseFilterExpression(expression) return collections; } -export function extendedHeaderFilter(headerValue, rowValue) +export function extendedHeaderFilter(headerValue, rowValue, rowData, filterParams) { if (typeof headerValue === 'boolean') { @@ -48,52 +48,79 @@ export function extendedHeaderFilter(headerValue, rowValue) const collections = parseFilterExpression(headerValue); - try { + function matchValue(value) + { + try { + return collections.some(collection => { - return collections.some(collection => { + let positives = collection.positives.length === 0 || collection.positives.every(condition => { - let positives = collection.positives.length === 0 || collection.positives.every(condition => { + if (condition.type === 'comparison') + { + let value = parseFloat(rowValue); + if (isNaN(value)) return false; - if (condition.type === 'comparison') - { - let value = parseFloat(rowValue); - if (isNaN(value)) return false; - - switch (condition.operator) { - case '<': - return value < condition.number; - case '>': - return value > condition.number; - case '<=': - return value <= condition.number; - case '>=': - return value >= condition.number; - case '=': - return value === condition.number; - case '!=': - return value !== condition.number; - default: - return false; + switch (condition.operator) { + case '<': + return value < condition.number; + case '>': + return value > condition.number; + case '<=': + return value <= condition.number; + case '>=': + return value >= condition.number; + case '=': + return value === condition.number; + case '!=': + return value !== condition.number; + default: + return false; + } } - } - else if (condition.type === 'regex') - { - return condition.regex.test(rowValue); - } - return false; + else if (condition.type === 'regex') + { + return condition.regex.test(rowValue); + } + return false; + }); + + let negatives = collection.negatives.every(condition => { + return !condition.regex.test(rowValue); + }); + + return positives && negatives; }); + } catch (e) { - let negatives = collection.negatives.every(condition => { - return !condition.regex.test(rowValue); - }); - - return positives && negatives; - }); - } catch (e) { - + } } + + if (matchValue(rowValue)) + return true; + + if (rowData && filterParams) + { + const childrenField = filterParams?.children || '_children'; + const field = filterParams?.field; + + const children = rowData[childrenField]; + if (Array.isArray(children)) + { + for (let child of children) + { + let childValue = child[field]; + if (extendedHeaderFilter(headerValue, childValue, child, filterParams)) + { + return true; + } + } + } + } + + return false; } -export function tagHeaderFilter(headerValue, rowValue) { +export function tagHeaderFilter(headerValue, rowValue, rowData, filterParams) +{ let data; @@ -120,6 +147,5 @@ export function tagHeaderFilter(headerValue, rowValue) { combinedText = String(data); } - return extendedHeaderFilter(headerValue, combinedText) -} - + return extendedHeaderFilter(headerValue, combinedText, rowData, filterParams) +} \ No newline at end of file diff --git a/system/dbupdate_3.4.php b/system/dbupdate_3.4.php index 0e2b4e7c6..fbdc1f4ae 100644 --- a/system/dbupdate_3.4.php +++ b/system/dbupdate_3.4.php @@ -74,6 +74,7 @@ require_once('dbupdate_3.4/55968_index_anrechnung.php'); require_once('dbupdate_3.4/25999_locale_update.php'); require_once('dbupdate_3.4/55289_pep_fine_tuning.php'); require_once('dbupdate_3.4/55614_perm_verwaltetoe.php'); +require_once('dbupdate_3.4/60882_lehrfaecherverteilung_favorites.php'); // *** Pruefung und hinzufuegen der neuen Attribute und Tabellen echo '

Pruefe Tabellen und Attribute!

'; diff --git a/system/dbupdate_3.4/60882_lehrfaecherverteilung_favorites.php b/system/dbupdate_3.4/60882_lehrfaecherverteilung_favorites.php new file mode 100644 index 000000000..55fb55b80 --- /dev/null +++ b/system/dbupdate_3.4/60882_lehrfaecherverteilung_favorites.php @@ -0,0 +1,16 @@ +db_query("SELECT 1 FROM public.tbl_variablenname WHERE name = 'lv_favorites';")) +{ + if ($db->db_num_rows($result) == 0) + { + $qry = "INSERT INTO public.tbl_variablenname(name, defaultwert) VALUES('lv_favorites', null);"; + + if (!$db->db_query($qry)) + echo 'public.tbl_variablenname '.$db->db_last_error().'
'; + else + echo 'public.tbl_variablenname: Added name "lv_favorites"
'; + } +} diff --git a/system/phrasesupdate.php b/system/phrasesupdate.php index 0203b3c2f..c158e3971 100644 --- a/system/phrasesupdate.php +++ b/system/phrasesupdate.php @@ -41873,8 +41873,729 @@ and represent the current state of research on the topic. The prescribed citatio 'insertvon' => 'system' ) ) - ) + ), // PROJEKTARBEITSBEURTEILUNG SS2025 ENDE --------------------------------------------------------------------------- + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'gewicht', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Gewicht', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Weight', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'newlehreinheit', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Neuer LV-Teil', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'New teaching unit', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'bezeichnungeng', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Bezeichnung Englisch', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'title english', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'detailanmerkung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Info an LV-Planung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Info to LV Planning', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'unr', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'UNR', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'UNR', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'las', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehrauftragsstunden (LAS)', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Teaching hours (LAS)', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'lehre', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehre', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Teaching', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'raumtyp', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Raumtyp', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Room', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'lehrende', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehrende', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'lecturers', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'raumtypalternativ', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Raumtyp Alternativ', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Room Alternative', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'startkw', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Start KW', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Start CW', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'stundenblockung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Stunden Block', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Hours Block', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'wochenrhythmus', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Wochenrhythmus', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Weekly rhythm', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'lehrfunktion', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehrfunktion', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Teaching function', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'anmerkung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Info an DepL/KFL', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Info to DepL/KFL', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'planstunden', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'LV-Plan Stunden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Course-Plan Hours', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'leplanstunden', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Planstunden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Plan Hours', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'default', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Default', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Default', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'stundensatz', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Stundensatz', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Hourly Rate', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'bismelden', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'BIS-Melden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Report BIS', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'gesamtkosten', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Gesamtkosten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Total costs', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'daten', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Daten', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Data', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'lehreinheit_id', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehreinheit ID', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Teaching Unit ID', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'verplant', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Verplant', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Planned', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'addLektor', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'LektorIn hinzufügen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Add lector', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'gruppen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Gruppen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Groups', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'addGroup', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Gruppe hinzufügen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Add group', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'assignPerson', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Person zuordnen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Assign person', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'assignedPersons', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Direkt zugeordnete Personen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Directly assigned persons', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'geaendert', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Geändert', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Changed', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'vertragurfassung', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Vertragsdetails lt. Urfassung', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Contract details as per original version', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'vertragsdetails', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Vertragsdetails', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Contract details', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'semesterstunden', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Semesterstunden', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Semester hours', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'vertragsstatus', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Vertragsstatus', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Contract status', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'auslvplanentfernen', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Stunden aus LV-Plan entfernen', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Remove hours from course plan', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + array( + 'app' => 'core', + 'category' => 'lehre', + 'phrase' => 'lehrfach', + 'insertvon' => 'system', + 'phrases' => array( + array( + 'sprache' => 'German', + 'text' => 'Lehrfach', + 'description' => '', + 'insertvon' => 'system' + ), + array( + 'sprache' => 'English', + 'text' => 'Course', + 'description' => '', + 'insertvon' => 'system' + ) + ) + ), + ); From 3e3fa9c1eb286a960df67ce613e3ee82a02d0e12 Mon Sep 17 00:00:00 2001 From: ma0048 Date: Tue, 3 Jun 2025 08:57:28 +0200 Subject: [PATCH 03/88] svnr aus dem fas entfernt --- .../api/frontend/v1/stv/Student.php | 1 - .../api/frontend/v1/stv/Students.php | 1 - cis/infoterminal/index.php | 1 - content/dokumentenakt.pdf.php | 3 - .../statistik/studentenexportextended.xls.php | 9 +-- content/student/studentDBDML.php | 2 - content/student/studentdetailoverlay.xul.php | 3 +- content/student/studentenoverlay.xul.php | 5 -- content/student/studentoverlay.js.php | 6 -- include/prestudent.class.php | 1 - include/student.class.php | 4 +- .../Studentenverwaltung/Details/Details.js | 10 --- .../Stv/Studentenverwaltung/List.js | 1 - public/js/infocenter/stammdaten.js | 1 - rdf/ausbildungsvertrag.xml.php | 6 -- rdf/student.rdf.php | 9 +-- rdf/studienblatt.xml.php | 4 - .../personen/import/interessentenimport.php | 3 +- vilesci/personen/personen_details.php | 33 +++++++-- vilesci/personen/preinteressent_anlegen.php | 73 +++++++------------ vilesci/personen/preinteressent_detail.php | 3 - vilesci/statistik/oehwaehlerverzeichnis.php | 1 - vilesci/statistik/studierendenliste_oeh.php | 1 - 23 files changed, 59 insertions(+), 122 deletions(-) diff --git a/application/controllers/api/frontend/v1/stv/Student.php b/application/controllers/api/frontend/v1/stv/Student.php index f24ef62bb..817d5adbc 100644 --- a/application/controllers/api/frontend/v1/stv/Student.php +++ b/application/controllers/api/frontend/v1/stv/Student.php @@ -186,7 +186,6 @@ class Student extends FHCAPI_Controller 'gebdatum', 'gebort', 'geburtsnation', - 'svnr', 'ersatzkennzeichen', 'staatsbuergerschaft', 'matr_nr', diff --git a/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index 5fb7b592c..c843eddd2 100644 --- a/application/controllers/api/frontend/v1/stv/Students.php +++ b/application/controllers/api/frontend/v1/stv/Students.php @@ -618,7 +618,6 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect('wahlname'); $this->PrestudentModel->addSelect('vornamen'); $this->PrestudentModel->addSelect('titelpost'); - $this->PrestudentModel->addSelect('svnr'); $this->PrestudentModel->addSelect('ersatzkennzeichen'); $this->PrestudentModel->addSelect('gebdatum'); $this->PrestudentModel->addSelect('geschlecht'); diff --git a/cis/infoterminal/index.php b/cis/infoterminal/index.php index 1b4c7d637..04c591ee1 100644 --- a/cis/infoterminal/index.php +++ b/cis/infoterminal/index.php @@ -843,7 +843,6 @@ function meine_uid_informationen_detail($db,$uid,$count=0) $aktiv=$db->db_result($erg,0,"aktiv"); - $svnr=$db->db_result($erg,0,"svnr"); $titelpre=$db->db_result($erg,0,"titelpre"); $titelpost=$db->db_result($erg,0,"titelpost"); diff --git a/content/dokumentenakt.pdf.php b/content/dokumentenakt.pdf.php index a27b8d562..a737ee72d 100644 --- a/content/dokumentenakt.pdf.php +++ b/content/dokumentenakt.pdf.php @@ -307,8 +307,6 @@ foreach($prestudent_ids as $pid) $nation->load($prestudent->zgvnation); $zgvnation = $nation->kurztext; - $svnr = ($prestudent->svnr == '')?($prestudent->ersatzkennzeichen != ''?'Ersatzkennzeichen: '.$prestudent->ersatzkennzeichen:''):$prestudent->svnr; - foreach($adresse->result as $row_adresse) { if($row_adresse->heimatadresse) @@ -439,7 +437,6 @@ foreach($prestudent_ids as $pid) 'zustell_ort' => $zustellOrt, 'zustell_bundesland' => $zustellBundesland, 'geburtsnation' => $geburtsnation, - 'svnr' => $svnr, 'staatsbuergerschaft' => $staatsbuergerschaft, 'geschlecht' => $prestudent->geschlecht, 'telefonnummer' => $telefonnummer, diff --git a/content/statistik/studentenexportextended.xls.php b/content/statistik/studentenexportextended.xls.php index 89acbe18f..5ab34d026 100644 --- a/content/statistik/studentenexportextended.xls.php +++ b/content/statistik/studentenexportextended.xls.php @@ -125,8 +125,6 @@ $worksheet->write($zeile, ++$i, "PERSONENKENNZEICHEN", $format_bold); $maxlength[$i] = 19; $worksheet->write($zeile, ++$i, "STAATSBÜRGERSCHAFT", $format_bold); $maxlength[$i] = 16; -$worksheet->write($zeile, ++$i, "SVNR", $format_bold); -$maxlength[$i] = 4; $worksheet->write($zeile, ++$i, "PERSON_ID", $format_bold); $maxlength[$i] = 6; $worksheet->write($zeile, ++$i, "ERSATZKENNZEICHEN", $format_bold); @@ -396,12 +394,7 @@ function draw_content($row) $worksheet->write($zeile, $i, $row->staatsbuergerschaft); $i++; - //SVNR - if (mb_strlen($row->svnr) > $maxlength[$i]) - $maxlength[$i] = mb_strlen($row->svnr); - $worksheet->write($zeile, $i, $row->svnr); - $i++; - + //Person_id if (mb_strlen($row->person_id) > $maxlength[$i]) $maxlength[$i] = mb_strlen($row->person_id); diff --git a/content/student/studentDBDML.php b/content/student/studentDBDML.php index e1bcffd84..041af9c20 100644 --- a/content/student/studentDBDML.php +++ b/content/student/studentDBDML.php @@ -594,7 +594,6 @@ if(!$error) $student->anmerkungen = $_POST['anmerkung']; $student->homepage = $_POST['homepage']; $student->matr_nr = $_POST['matr_nr']; - $student->svnr = $_POST['svnr']; $student->ersatzkennzeichen = $_POST['ersatzkennzeichen']; $student->familienstand = $_POST['familienstand']; $student->geschlecht = $_POST['geschlecht']; @@ -746,7 +745,6 @@ if(!$error) $person->gebzeit = $_POST['geburtszeit']; $person->anmerkungen = $_POST['anmerkung']; $person->homepage = $_POST['homepage']; - $person->svnr = $_POST['svnr']; $person->ersatzkennzeichen = $_POST['ersatzkennzeichen']; $person->familienstand = $_POST['familienstand']; $person->geschlecht = $_POST['geschlecht']; diff --git a/content/student/studentdetailoverlay.xul.php b/content/student/studentdetailoverlay.xul.php index 132667395..36740d209 100644 --- a/content/student/studentdetailoverlay.xul.php +++ b/content/student/studentdetailoverlay.xul.php @@ -134,8 +134,7 @@ echo ''; -