Compare commits

...

29 Commits

Author SHA1 Message Date
Ivymaster 48b836c466 BUG: add fix for room deletion with attached sub rooms 2026-05-20 13:18:16 +02:00
Ivymaster 363cb90019 Add dedicated room req class, add tabulator backend sortings and other stuff 2026-05-20 13:01:24 +02:00
Ivymaster eca9b22f7d Add tristate filter in Room manager table, add parent room short code in vilesci legacy code 2026-05-07 13:35:50 +02:00
Ivymaster 667726e23b BUG: add fix for orgUnit dropdown filtering on roomManager view 2026-05-07 11:35:53 +02:00
Ivymaster f3f960ccc4 Add permission change on RoomManager overview link in navigation 2026-05-06 12:50:41 +02:00
Ivymaster 86b4ffabc4 Add minor styling change in legacy vilesci room management view 2026-05-06 11:43:51 +02:00
Ivymaster 081703e0f8 Add navigation component to RoomManager 2026-05-06 11:41:10 +02:00
Ivymaster 05814383d4 Add pagination and backend filtering for rooms in RoomManagerOverview component 2026-05-05 15:16:25 +02:00
Ivymaster a44d0f65b3 Add components and endpoints for room type CRD and room to room type relation CRD 2026-05-04 16:28:09 +02:00
Ivymaster fe507e4185 Add new endpoint and vuejs components for room managment 2026-04-29 13:08:33 +02:00
Andreas Österreicher 552faefa51 Merge branch 'feature-76108/microdegree_abschlussurkunde' 2026-04-27 08:55:08 +02:00
Harald Bamberger 954397f028 Merge branch 'feature-70376/Lohnguide' 2026-04-22 18:52:51 +02:00
Harald Bamberger 80faa61c91 Merge branch 'master' into feature-70376/Lohnguide 2026-04-22 18:46:57 +02:00
Werner Masik 961ede66a9 lohnguide db update changed 2026-04-22 18:40:22 +02:00
Andreas Österreicher 6fec8382b5 Merge branch 'feature-76554/Personalmeldung_alt_bei_Lehre_nicht_melderelevant_rausfiltern' 2026-04-22 09:15:23 +02:00
Andreas Österreicher 4eb076d115 Fixed Saving of Entwicklungsteam 2026-04-21 17:34:36 +02:00
Harald Bamberger 7427aa87ea Merge branch 'feature-76545/findAbgabenNewOrUpdatedSinceByAbgabedatumFixTimestampDateComparison' 2026-04-21 17:01:04 +02:00
Johann Hoffmann 85043e57db added missing parenthesis 2026-04-21 17:00:07 +02:00
Johann Hoffmann 5beddbccb4 changed the where clause to a simpler = CURRENT_DATE comparison -> works the same if the job runs daily and fetches updates of one day/date; has to be changed back in case we want to find updates in a range larger than 1 day in an interval larger than 1 day; 2026-04-21 14:18:45 +02:00
kindlm e2ae9b88c8 Merge remote-tracking branch 'origin/master' 2026-04-21 12:56:30 +02:00
kindlm ca3abf9154 Small Style-Fix in Testtool
To make headings stand out more clearly from the buttons
2026-04-21 12:56:02 +02:00
Alexei Karpenko f863c6d728 personalmeldung legacy system: melderelevant is checked for lehre, bugfix: lehre is correctly added if studiengang already has sws 2026-04-20 18:24:30 +02:00
Harald Bamberger 92a2053b42 Merge branch 'feature-40870/BUG_Studstatus_unpause_order_should_be_DESC' 2026-04-20 17:30:14 +02:00
kindlm 70602be54e SaveSort und Filter-Reset in RaumÜbersicht 2026-04-20 11:30:17 +02:00
kindlm dac71f597a Spalte Anmeldedatum in RT-Übersicht
Spalte Frage_ID in RT-Administration
JQuery und Tabelsorter aus Include in Service_Uebersicht
2026-04-20 11:24:59 +02:00
Johann Hoffmann 3a646ffe77 adapt AbgabeJob relevant queries so they compare with the pgsql date function CURRENT_DATE instead of NOW() to avoid the cutoff from uploads the happened "yesterday but more than 24 hours ago"; also added another "abgabedatum < CURRENT_DATE" condition, to avoid sending this exact case as updates 2 days in a row; 2026-04-20 11:06:06 +02:00
ma0048 3ce3eff022 fehlendes mapping hinzugefuegt 2026-04-14 09:30:45 +02:00
ma0048 ea0a249612 micro degree abschlussdokumente hinzugefuegt 2026-04-13 09:14:27 +02:00
cgfhtw d542cf7720 s&d 2024-08-14 16:20:47 +02:00
44 changed files with 4198 additions and 211 deletions
+17
View File
@@ -45,6 +45,14 @@ $config['navigation_header'] = array(
'expand' => true,
'sort' => 30,
'requiredPermissions' => 'admin:w'
),
'roomManagerOverview' => array(
'link' => site_url('RoomManager'),
'icon' => '',
'description' => 'Raumverwaltung',
'expand' => true,
'sort' => 40,
'requiredPermissions' => 'basis/ort:r'
)
)
),
@@ -383,3 +391,12 @@ $config['navigation_menu']['apps'] = [
'requiredPermissions' => array('lehre/lehrauftrag_bestellen:r', 'lehre/lehrauftrag_erteilen:r')
]
];
$config['navigation_menu']['RoomManager/index'] = array(
'lvTemplateUebersicht' => array(
'link' => site_url('RoomManager'),
'description' => 'Raumverwaltung übersicht',
'icon' => '',
'sort' => 1
)
);
+2
View File
@@ -122,6 +122,8 @@ $route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/person/(:num)'] = 'api/f
// load routes from extensions, also look for environment-specific configs
$subdirs = ['application/config/extensions', 'application/config/' . ENVIRONMENT . '/extensions'];
$route['RoomManager/.*'] = 'RoomManager/index';
foreach($subdirs as $subdir)
{
if(is_dir($subdir))
+62
View File
@@ -0,0 +1,62 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*/
class RoomManager extends Auth_Controller
{
private $_uid; // uid of the logged user
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'index' => array('basis/ort:r')
)
);
$this->load->library('PermissionLib');
$this->load->library('AuthLib');
$this->loadPhrases(
array(
'ui',
'global',
'person',
'abschlusspruefung',
'password',
'lehre'
)
);
$this->_setAuthUID();
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function index()
{
return $this->load->view('room_manager/index', [
'permissions' => [
'basis/ort_w' => $this->permissionlib->isBerechtigt('basis/ort', 'suid'),
],
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid) show_error('User authentification failed');
}
}
+320 -7
View File
@@ -31,21 +31,180 @@ class Ort extends FHCAPI_Controller
*/
public function __construct()
{
// NOTE(chris): additional permission checks will be done in SearchBarLib
parent::__construct([
'getAllRooms' => array('basis/ort:r'),
'getRooms' => self::PERM_LOGGED,
'getTypes' => self::PERM_LOGGED,
'ContentID' => self::PERM_LOGGED,
'getOrtKurzbzContent' => self::PERM_LOGGED,
'getRooms' => self::PERM_LOGGED,
'getTypes' => self::PERM_LOGGED
'getRoom' => self::PERM_LOGGED,
'createRoom' => array('basis/ort:rw'),
'updateRoom' => array('basis/ort:rw'),
'deleteRoom' => array('basis/ort:rw'),
]);
$this->load->library('form_validation');
$this->load->library('requests/RoomRequest');
$this->load->model('ressource/Ort_model', 'OrtModel');
$this->load->model('ressource/Reservierung_model', 'ReservierungModel');
$this->config->load('raumsuche');
$this->loadPhrases([
'global',
'ui',
'lehre',
'gruppenmanagement',
'person',
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getAllRooms()
{
$paginationSize = $this->input->get('pagination[size]', TRUE);
$paginationPage = $this->input->get('pagination[page]', TRUE);
$filter = $this->input->get('filter', TRUE);
$filterData = [];
$query = "SELECT
COUNT(*) OVER() AS full_count,
public.tbl_ort.*,
org.bezeichnung as org_bezeichnung,
org.organisationseinheittyp_kurzbz as org_organisationseinheittyp_kurzbz
FROM public.tbl_ort
LEFT JOIN public.tbl_ort as pr ON pr.ort_kurzbz = public.tbl_ort.parent_ort_kurzbz
LEFT JOIN public.tbl_organisationseinheit as org ON org.oe_kurzbz = public.tbl_ort.oe_kurzbz";
$queryWhereFragments = [];
$searchableIdAttributes = ['standort_id', 'gebteil', 'oe_kurzbz'];
$searchableTextAttributes = ['ort_kurzbz', 'parent_ort_kurzbz', 'bezeichnung', 'planbezeichnung', 'oe_bezeichnung'];
$searchableBooleanAttributes = ['lehre', 'reservieren', 'aktiv'];
$searchableNumericAttributes = ['max_person', 'arbeitsplaetze', 'kosten', 'stockwerk'];
$searchableNumericSpanAttributes = ['m2'];
$searchableCustomAttributes = [
[
'raw_sql_fragment' => "CONCAT(public.tbl_ort.ort_kurzbz, ' - ', public.tbl_ort.bezeichnung)",
'filter_parameter' => 'ort_kurzbz_bezeichnung_concat',
],
[
'raw_sql_fragment' => "CONCAT('[', org.organisationseinheittyp_kurzbz, '] ', org.bezeichnung)",
'filter_parameter' => 'org_organisationseinheittyp_kurzbz_org_bezeichnung_concat',
]
];
foreach ($searchableIdAttributes as $attribute) {
if (isset($filter[$attribute]) && $filter[$attribute] !== '') {
$queryWhereFragments[] = "public.tbl_ort.$attribute = ?";
$filterData[] = trim($filter[$attribute]);
}
}
foreach ($searchableTextAttributes as $attribute) {
$tableAttribute = "public.tbl_ort.$attribute";
if ($attribute === 'oe_bezeichnung') {
$tableAttribute = "org.bezeichnung";
}
if (isset($filter[$attribute]) && $filter[$attribute] !== '') {
$queryWhereFragments[] = "$tableAttribute ILIKE ?";
$filterData[] = '%' . trim($filter[$attribute]) . '%';
}
}
foreach ($searchableBooleanAttributes as $attribute) {
if (isset($filter[$attribute]) && $filter[$attribute] !== '') {
$queryWhereFragments[] = "public.tbl_ort.$attribute = ?";
$filterData[] = $filter[$attribute] === 'true' ? true : false;
}
}
foreach ($searchableNumericAttributes as $attribute) {
if (isset($filter[$attribute]) && $filter[$attribute] !== '') {
$queryWhereFragments[] = "public.tbl_ort.$attribute = ?";
$filterData[] = trim($filter[$attribute]);
}
}
foreach ($searchableNumericSpanAttributes as $attribute) {
if (isset($filter[$attribute]) && $filter[$attribute] !== '') {
$queryWhereFragments[] = "public.tbl_ort.$attribute >= ? AND public.tbl_ort.$attribute <= ?";
$filterData[] = trim($filter[$attribute]) - 1;
$filterData[] = trim($filter[$attribute]) + 1;
}
}
foreach ($searchableCustomAttributes as $customAttribute) {
if (isset($filter[$customAttribute['filter_parameter']]) && $filter[$customAttribute['filter_parameter']] !== '') {
$queryWhereFragments[] = $customAttribute['raw_sql_fragment'] . " ILIKE ?";
$filterData[] = '%' . trim($filter[$customAttribute['filter_parameter']]) . '%';
}
}
if (count($queryWhereFragments) > 0) {
$query .= ' WHERE ' . implode(' AND ', $queryWhereFragments);
}
$sortableAttributes = ['ort_kurzbz', 'bezeichnung', 'planbezeichnung', 'max_person', 'arbeitsplaetze', 'm2', 'lehre', 'reservieren', 'aktiv', 'stockwerk', 'kosten', 'parent_ort_kurzbz', 'org_bezeichnung'];
$sortableConcatAttributes = [
[
'raw_sql_fragment' => "CONCAT('[', org.organisationseinheittyp_kurzbz, '] ', org.bezeichnung)",
'sort_parameter' => 'org_organisationseinheittyp_kurzbz_org_bezeichnung_concat',
]
];
$sorter = $this->input->get('sort', TRUE);
foreach ($sortableAttributes as $attribute) {
if (isset($sorter[$attribute]) && in_array(strtolower($sorter[$attribute]), ['asc', 'desc'])) {
if ($attribute === 'org_bezeichnung') {
$query .= " ORDER BY org.bezeichnung " . strtoupper($sorter[$attribute]);
} else {
$query .= " ORDER BY public.tbl_ort.$attribute " . strtoupper($sorter[$attribute]);
}
}
}
foreach ($sortableConcatAttributes as $customAttribute) {
if (isset($sorter[$customAttribute['sort_parameter']]) && in_array(strtolower($sorter[$customAttribute['sort_parameter']]), ['asc', 'desc'])) {
$query .= " ORDER BY " . $customAttribute['raw_sql_fragment'] . " " . strtoupper($sorter[$customAttribute['sort_parameter']]);
}
}
if (!isset($sorter)) {
$query .= ' ORDER BY public.tbl_ort.ort_kurzbz ASC';
}
if ($paginationSize && $paginationPage) {
$query .= " LIMIT ? OFFSET ?";
}
$queryData = array_merge($filterData);
if ($paginationSize && $paginationPage) {
$queryData = array_merge($filterData, [$paginationSize, ($paginationPage - 1) * $paginationSize]);
}
$result = $this->OrtModel->execReadOnlyQuery($query, $queryData);
$queryData = hasData($result) ? getData($result) : [];
if ($paginationSize && $paginationPage) {
$totalItems = count($queryData) > 0 ? $queryData[0]->full_count : 0;
$pageCount = ceil($totalItems / $paginationSize);
$this->addTabulatorPaginationData($pageCount);
}
$this->terminateWithSuccess($queryData);
}
/**
* Retrieves all Ort entries filtered by the provided parameters
*/
@@ -54,7 +213,7 @@ class Ort extends FHCAPI_Controller
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('datum','Datum','required');
$this->form_validation->set_rules('von','Uhrzeit Von','required|regex_match[/^[0-9]{2}:[0-9]{2}$/]');
$this->form_validation->set_rules('von','Uhrzeit Von','required|regexresponse_match[/^[0-9]{2}:[0-9]{2}$/]');
$this->form_validation->set_rules('bis','Uhrzeit Bis','required|regex_match[/^[0-9]{2}:[0-9]{2}$/]');
if($this->form_validation->run() == FALSE) {
$this->terminateWithValidationErrors($this->form_validation->error_array());
@@ -66,7 +225,6 @@ class Ort extends FHCAPI_Controller
$typ = $this->input->get('typ', TRUE);
$personenanzahl = $this->input->get('personenanzahl', TRUE);
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID())->retval;
@@ -100,8 +258,7 @@ class Ort extends FHCAPI_Controller
)
";
$params = array_merge($params, [$datum, $vonStunde, $bisStunde, $datum, $vonStunde, $bisStunde]);
// $this->addMeta('qry', $qry);
// $this->addMeta('params', $params);
$result = $this->OrtModel->execReadOnlyQuery($qry, $params);
$this->terminateWithSuccess($result);
@@ -174,5 +331,161 @@ class Ort extends FHCAPI_Controller
$this->terminateWithSuccess($content);
}
public function getRoom($ort_kurzbz)
{
$result = $this->OrtModel->load($ort_kurzbz);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$result = hasData($result) ? current(getData($result)) : null;
return $this->terminateWithSuccess($result);
}
public function createRoom()
{
if (!$this->roomrequest->validate()) {
$this->terminateWithValidationErrors($this->roomrequest->errors());
return;
}
$this->db->trans_start();
$data = [
"parent_ort_kurzbz" => $this->input->post('parent_ort_kurzbz'),
"oe_kurzbz" => $this->input->post('oe_kurzbz'),
"content_id" => !empty($this->input->post('content_id')) ? $this->input->post('content_id') : null,
"standort_id" => $this->input->post('standort_id'),
"ort_kurzbz" => $this->input->post('ort_kurzbz'),
"bezeichnung" => $this->input->post('bezeichnung'),
"planbezeichnung" => $this->input->post('planbezeichnung'),
"aktiv" => $this->input->post('aktiv') ? true : false,
"lehre" => $this->input->post('lehre') ? true : false,
"reservieren" => $this->input->post('reservieren') ? true : false,
"max_person" => $this->input->post('max_person'),
"stockwerk" => $this->input->post('stockwerk'),
"lageplan" => $this->input->post('lageplan'),
"dislozierung" => $this->input->post('dislozierung'),
"kosten" => $this->input->post('kosten'),
"ausstattung" => $this->input->post('ausstattung'),
"telefonklappe" => $this->input->post('telefonklappe'),
"m2" => $this->input->post('m2'),
"gebteil" => $this->input->post('gebteil'),
"arbeitsplaetze" => $this->input->post('arbeitsplaetze'),
'insertamum' => date('c'),
'insertvon' => getAuthUid(),
'updateamum' => date('c'),
'updatevon' => getAuthUid()
];
$this->OrtModel->db->set($data);
$result = $this->OrtModel->db->insert($this->OrtModel->getDbTable());
$this->db->trans_complete();
return $this->terminateWithSuccess($result);
}
public function updateRoom($ort_kurzbz)
{
if (!$this->roomrequest->validate("update")) {
$this->terminateWithValidationErrors($this->roomrequest->errors());
return;
}
$this->db->trans_start();
$fields = [
"parent_ort_kurzbz",
"oe_kurzbz",
"content_id",
"standort_id",
"bezeichnung",
"planbezeichnung",
"aktiv",
"lehre",
"reservieren",
"max_person",
"stockwerk",
"lageplan",
"dislozierung",
"kosten",
"ausstattung",
"telefonklappe",
"m2",
"gebteil",
"arbeitsplaetze"
];
foreach ($fields as $field) {
if (array_key_exists($field, $this->input->post())) {
$data[$field] = $this->input->post($field);
}
}
$data['updateamum'] = date('c');
$data['updatevon'] = getAuthUid();
$this->OrtModel->db->set($data);
$this->OrtModel->db->where('ort_kurzbz', $ort_kurzbz);
$result = $this->OrtModel->db->update($this->OrtModel->getDbTable());
$this->db->trans_complete();
return $this->terminateWithSuccess($result);
}
public function deleteRoom($ort_kurzbz)
{
$this->db->trans_start();
$reservationsQuery = "SELECT COUNT(*) FROM campus.tbl_reservierung WHERE ort_kurzbz = ?";
$reservationsResult = $this->OrtModel->execReadOnlyQuery($reservationsQuery, [$ort_kurzbz]);
if (isError($reservationsResult)) {
$this->terminateWithError(getError($reservationsResult), self::ERROR_TYPE_GENERAL);
}
$reservationsCount = hasData($reservationsResult) ? getData($reservationsResult)[0]->count : 0;
if ($reservationsCount > 0) {
$this->terminateWithError($this->p->t('ui', 'error_existingReservationsForRoomsUponDeletion'), self::ERROR_TYPE_GENERAL);
}
$softwareImageOrtQuery = "SELECT COUNT(*) FROM extension.tbl_softwareimage_ort WHERE ort_kurzbz = ?";
$softwareImageOrtResult = $this->OrtModel->db->query($softwareImageOrtQuery, [$ort_kurzbz]);
if ($softwareImageOrtResult === false) {
$this->terminateWithError($this->p->t('ui', 'error_existingSoftwareImageForRoomTypeUponDeletion'), self::ERROR_TYPE_GENERAL);
}
$softwareImageOrtCount = $softwareImageOrtResult->row()->count;
if ($softwareImageOrtCount > 0) {
$this->terminateWithError($this->p->t('ui', 'error_existingSoftwareImageForRoomTypeUponDeletion'), self::ERROR_TYPE_GENERAL);
}
$subRoomsCountQuery = "SELECT COUNT(*) FROM public.tbl_ort WHERE parent_ort_kurzbz = ?";
$subRoomsCountQuery = $this->OrtModel->execReadOnlyQuery($subRoomsCountQuery, [$ort_kurzbz]);
$subRoomsCount = hasData($subRoomsCountQuery) ? getData($subRoomsCountQuery)[0]->count : 0;
if ($subRoomsCount > 0) {
$this->terminateWithError($this->p->t('ui', 'error_existingSubRoomsForRoomUponDeletion'), self::ERROR_TYPE_GENERAL);
}
$result = $this->OrtModel->delete([
"ort_kurzbz" => $ort_kurzbz
]);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->db->trans_complete();
return $this->terminateWithSuccess(true);
}
}
@@ -0,0 +1,123 @@
<?php
/**
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class RoomToRoomTypeApi extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
// NOTE(chris): additional permission checks will be done in SearchBarLib
parent::__construct([
'getRoomToRoomTypeRelationsByRoomShortCode' => array('basis/ort:r'),
'createRoomToRoomTypeRelation' => array('basis/ort:rw'),
'deleteRoomToRoomTypeRelation' => array('basis/ort:rw'),
]);
$this->load->library('form_validation');
$this->load->model('ressource/Ortraumtyp_model', 'OrtRoomTypeModel');
$this->loadPhrases([
'global',
'ui',
'lehre'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getRoomToRoomTypeRelationsByRoomShortCode($roomShortCode) {
$this->OrtRoomTypeModel->db->select('public.tbl_ortraumtyp.*, public.tbl_raumtyp.beschreibung as raumtyp_beschreibung');
$this->OrtRoomTypeModel->db->join('public.tbl_raumtyp', 'public.tbl_raumtyp.raumtyp_kurzbz = public.tbl_ortraumtyp.raumtyp_kurzbz', 'left');
$this->OrtRoomTypeModel->db->order_by('hierarchie', 'ASC');
$result = $this->OrtRoomTypeModel->loadWhere(['ort_kurzbz' => $roomShortCode]);
return $this->terminateWithSuccess($this->getDataOrTerminateWithError($result));
}
public function createRoomToRoomTypeRelation() {
$this->form_validation->set_rules('roomShortCode', 'roomShortCode', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'kurzbz')])
]);
$this->form_validation->set_rules('roomTypeShortCode', 'roomTypeShortCode', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'kurzbz')])
]);
$this->form_validation->set_rules('hierarchy', 'hierarchy', 'required|integer', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('ui', 'hierarchy')]),
'integer' => $this->p->t('ui', 'error_fieldInteger', ['field' => $this->p->t('ui', 'hierarchy')])
]);
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$existingRelationResponse = $this->OrtRoomTypeModel->loadWhere([
'ort_kurzbz' => $this->input->post('roomShortCode'),
'hierarchie' => $this->input->post('hierarchy'),
]);
if (hasData($existingRelationResponse)) {
$this->terminateWithError($this->p->t('ui', 'error_roomToRoomTypeRelationAlreadyExists'), self::ERROR_TYPE_GENERAL);
}
$data = [
'ort_kurzbz' => $this->input->post('roomShortCode'),
'raumtyp_kurzbz' => $this->input->post('roomTypeShortCode'),
'hierarchie' => $this->input->post('hierarchy'),
];
$this->OrtRoomTypeModel->db->set($data);
$result = $this->OrtRoomTypeModel->db->insert($this->OrtRoomTypeModel->getDbTable());
if ($result === false) {
return $this->terminateWithError($this->OrtRoomTypeModel->getLastError());
}
return $this->terminateWithSuccess(['message' => 'Room to Room Type relation created successfully.']);
}
public function deleteRoomToRoomTypeRelation() {
$this->form_validation->set_rules('roomShortCode', 'roomShortCode', 'required');
$this->form_validation->set_rules('roomTypeShortCode', 'roomTypeShortCode', 'required');
$this->form_validation->set_rules('hierarchy', 'hierarchy', 'required|integer');
if ($this->form_validation->run() === false) {
return $this->terminateWithError(validation_errors());
}
$result = $this->OrtRoomTypeModel->db->delete($this->OrtRoomTypeModel->getDbTable(), [
'ort_kurzbz' => $this->input->post('roomShortCode'),
'raumtyp_kurzbz' => $this->input->post('roomTypeShortCode'),
'hierarchie' => $this->input->post('hierarchy'),
]);
if ($result === false) {
return $this->terminateWithError($this->OrtRoomTypeModel->getLastError());
}
return $this->terminateWithSuccess(['message' => 'Room to Room Type relation deleted successfully.']);
}
}
@@ -0,0 +1,83 @@
<?php
/**
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class RoomTypeApi extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getAllRoomTypes' => array('basis/ort:r'),
'createRoomType' => array('basis/ort:rw'),
]);
$this->load->library('form_validation');
$this->load->model('ressource/Raumtyp_model', 'RoomTypeModel');
$this->loadPhrases([
'global',
'ui',
'lehre'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getAllRoomTypes() {
$this->RoomTypeModel->addOrder('raumtyp_kurzbz', 'ASC');
$result = $this->RoomTypeModel->load();
return $this->terminateWithSuccess($this->getDataOrTerminateWithError($result));
}
public function createRoomType() {
$this->form_validation->set_rules('kurzbezeichnung', 'kurzbezeichnung', 'required|max_length[255]|is_unique[tbl_raumtyp.raumtyp_kurzbz]', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'kurzbz')]),
'is_unique' => $this->p->t('ui', 'error_fieldUnique', ['field' => $this->p->t('lehre', 'kurzbz')]),
]);
$this->form_validation->set_rules('beschreibung', 'beschreibung', 'max_length[255]');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$data = [
'raumtyp_kurzbz' => $this->input->post('kurzbezeichnung'),
'beschreibung' => $this->input->post('beschreibung'),
];
$this->RoomTypeModel->db->set($data);
$result = $this->RoomTypeModel->db->insert($this->RoomTypeModel->getDbTable());
if ($result === false) {
return $this->terminateWithError($this->RoomTypeModel->getLastError());
}
return $this->terminateWithSuccess();
}
}
@@ -0,0 +1,56 @@
<?php
/**
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class LocationApi extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getLocationsByCompanyType'=> self::PERM_LOGGED,
]);
$this->load->library('form_validation');
$this->load->model('organisation/standort_model', 'StandortModel');
$this->loadPhrases([
'global',
'ui',
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getLocationsByCompanyType() {
$companyType = $this->input->get('companyType');
if (!isset($companyType)) {
$this->terminateWithError('companyType parameter is required', REST_Controller::HTTP_BAD_REQUEST);
return;
}
$result = $this->StandortModel->getByCompanyType($companyType);
return $this->terminateWithSuccess($this->getDataOrTerminateWithError($result));
}
}
@@ -0,0 +1,55 @@
<?php
/**
* Copyright (C) 2024 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 <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class OrganizationalUnitApi extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getAllOrganizationalUnits'=> array('basis/organisationseinheit:r'),
]);
$this->load->library('form_validation');
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$this->loadPhrases([
'global'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getAllOrganizationalUnits()
{
$entitledOrganizationalUnitsShortCodes = $this->permissionlib->getOE_isEntitledFor('basis/organisationseinheit');
$this->OrganisationseinheitModel->db->where_in('oe_kurzbz', $entitledOrganizationalUnitsShortCodes);
$result = $this->OrganisationseinheitModel->load();
$organization_units_result = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($organization_units_result);
}
}
+5
View File
@@ -154,6 +154,11 @@ class FHCAPI_Controller extends Auth_Controller
$this->returnObj['meta'][$key] = $value;
}
public function addTabulatorPaginationData($lastPage = 1)
{
$this->returnObj['last_page'] = $lastPage;
}
/**
* @param string $key
* @return mixed
+1 -1
View File
@@ -128,7 +128,7 @@ class AntragLib
return $this->_ci->StudierendenantragstatusModel->resumeAntraegeForAbmeldungStgl($antrag_id);
}
// NOTE(chris): get last status that is not pause
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum');
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum', 'DESC');
$this->_ci->StudierendenantragstatusModel->addLimit(1);
$result = $this->_ci->StudierendenantragstatusModel->loadWhere([
'studierendenantrag_id' => $antrag_id,
@@ -0,0 +1,104 @@
<?php
/**
* FH-Complete
*
* @package FHC-Helper
* @author FHC-Team
* @copyright Copyright (c) 2022 fhcomplete.net
* @license GPLv3
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class CustomFormValidationLib extends CI_Form_validation
{
public function __construct($rules = array())
{
parent::__construct($rules);
$this->_ci =& get_instance();
}
function explicit_integer($value)
{
if ($value === null) {
return true;
}
if ($value === '') {
return false;
}
if (filter_var($value, FILTER_VALIDATE_INT) !== false) {
return true;
}
return false;
}
function explicit_numeric($value)
{
if ($value === null) {
return true;
}
if ($value === '') {
return false;
}
if (is_numeric($value)) {
return true;
}
return false;
}
function explicit_boolean($value)
{
if ($value === null) {
return true;
}
if ($value === '') {
return false;
}
if ($value === 'true' || $value === 'false' || $value === true || $value === false || $value === 1 || $value === 0) {
return true;
}
return false;
}
function does_exist($value, $params)
{
if ($value === null ) {
return true;
}
if ($value === '') {
return false;
}
$parts = explode('.', $params);
if (count($parts) !== 3) {
return false;
}
$subDatabase = $parts[0];
$table = $parts[1];
$field = $parts[2];
$result = $this->_ci->db->select('COUNT(*) as count')
->from("$subDatabase.$table")
->where($field, $value)
->get();
if ($result === false) {
return false;
}
return $result->row()->count > 0;
}
}
@@ -0,0 +1,92 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class RoomRequest
{
protected $_ci;
public function __construct()
{
$this->_ci =& get_instance();
$this->_ci->load->library('CustomFormValidationLib');
}
public function validate($method = 'create')
{
if ($method === 'create') {
$this->_ci->customformvalidationlib->set_rules('ort_kurzbz', 'kurzbezeichnung', 'required|is_unique[tbl_ort.ort_kurzbz]|max_length[16]|regex_match[/^[a-zA-Z0-9_.]+$/]', [
'required' => $this->_ci->p->t('ui', 'error_fieldRequired', ['field' => $this->_ci->p->t('gruppenmanagement', 'kurzbezeichnung')]),
'is_unique' => $this->_ci->p->t('ui', 'error_fieldUnique', ['field' => $this->_ci->p->t('gruppenmanagement', 'kurzbezeichnung')]),
'max_length' => $this->_ci->p->t('ui', 'error_fieldMaxLength', ['field' => $this->_ci->p->t('gruppenmanagement', 'kurzbezeichnung'), 'max' => 16]),
'regex_match' => $this->_ci->p->t('ui', 'error_fieldInvalidFormat', ['field' => $this->_ci->p->t('gruppenmanagement', 'kurzbezeichnung')])
]);
}
$this->_ci->customformvalidationlib->set_rules('parent_ort_kurzbz', 'parent_ort_kurzbz', 'does_exist[public.tbl_ort.ort_kurzbz]|max_length[16]', [
'does_exist' => $this->_ci->p->t('ui', 'error_entryDoesExists', ['entry' => $this->_ci->p->t('ui', 'parentRoom')]),
'max_length' => $this->_ci->p->t('ui', 'error_fieldMaxLength', ['field' => $this->_ci->p->t('ui', 'parentRoom'), 'max' => 16])
]);
$this->_ci->customformvalidationlib->set_rules('oe_kurzbz', 'oe_kurzbz', 'does_exist[public.tbl_organisationseinheit.oe_kurzbz]|max_length[32]', [
'does_exist' => $this->_ci->p->t('ui', 'error_entryDoesExists', ['entry' => $this->_ci->p->t('lehre', 'organisationseinheit')]),
'max_length' => $this->_ci->p->t('ui', 'error_fieldMaxLength', ['field' => $this->_ci->p->t('lehre', 'organisationseinheit'), 'max' => 32])
]);
$this->_ci->customformvalidationlib->set_rules('standort_id', 'standort_id', 'explicit_integer|does_exist[public.tbl_standort.standort_id]', [
'does_exist' => $this->_ci->p->t('ui', 'error_entryDoesExists', ['entry' => $this->_ci->p->t('person', 'standort')]),
]);
$this->_ci->customformvalidationlib->set_rules('content_id', 'content_id', 'explicit_integer|does_exist[campus.tbl_content.content_id]', [
'explicit_integer' => $this->_ci->p->t('ui', 'error_fieldInteger', ['field' => $this->_ci->p->t('ui', 'contentId')]),
'does_exist' => $this->_ci->p->t('ui', 'error_entryDoesExists', ['entry' => $this->_ci->p->t('ui', 'contentId')])
]);
$this->_ci->customformvalidationlib->set_rules('lehre', 'lehre', 'explicit_boolean', [
'explicit_boolean' => $this->_ci->p->t('ui', 'error_fieldBoolean', ['field' => $this->_ci->p->t('ui', 'lehre')])
]);
$this->_ci->customformvalidationlib->set_rules('reservieren', 'reservieren', 'explicit_boolean', [
'explicit_boolean' => $this->_ci->p->t('ui', 'error_fieldBoolean', ['field' => $this->_ci->p->t('ui', 'reservieren')])
]);
$this->_ci->customformvalidationlib->set_rules('aktiv', 'aktiv', 'explicit_boolean', [
'explicit_boolean' => $this->_ci->p->t('ui', 'error_fieldBoolean', ['field' => $this->_ci->p->t('person', 'aktiv')])
]);
$this->_ci->customformvalidationlib->set_rules('bezeichnung', 'bezeichnung', 'max_length[64]', [
'max_length' => $this->_ci->p->t('ui', 'error_fieldMaxLength', ['field' => $this->_ci->p->t('ui', 'bezeichnung'), 'max' => 64])
]);
$this->_ci->customformvalidationlib->set_rules('planbezeichnung', 'planbezeichnung', 'max_length[8]', [
'max_length' => $this->_ci->p->t('ui', 'error_fieldMaxLength', ['field' => $this->_ci->p->t('ui', 'planbezeichnung'), 'max' => 8])
]);
$this->_ci->customformvalidationlib->set_rules('max_person', 'maxPerson', 'explicit_integer', [
'explicit_integer' => $this->_ci->p->t('ui', 'error_fieldInteger', ['field' => $this->_ci->p->t('ui', 'maxPersons')])
]);
$this->_ci->customformvalidationlib->set_rules('stockwerk', 'stockwerk', 'explicit_integer', [
'explicit_integer' => $this->_ci->p->t('ui', 'error_fieldInteger', ['field' => $this->_ci->p->t('ui', 'stockwerk')])
]);
$this->_ci->customformvalidationlib->set_rules('m2', 'm2', 'explicit_numeric', [
'explicit_numeric' => $this->_ci->p->t('ui', 'error_fieldNumeric', ['field' => $this->_ci->p->t('ui', 'quadratmeter')])
]);
$this->_ci->customformvalidationlib->set_rules('dislozierung', 'dislozierung', 'explicit_numeric', [
'explicit_numeric' => $this->_ci->p->t('ui', 'error_fieldNumeric', ['field' => $this->_ci->p->t('ui', 'dislozierung')])
]);
$this->_ci->customformvalidationlib->set_rules('kosten', 'kosten', 'explicit_numeric', [
'explicit_numeric' => $this->_ci->p->t('ui', 'error_fieldNumeric', ['field' => $this->_ci->p->t('ui', 'kosten')])
]);
$this->_ci->customformvalidationlib->set_rules('telefonklappe', 'telefonklappe', 'max_length[8]', [
'max_length' => $this->_ci->p->t('ui', 'error_fieldMaxLength', ['field' => $this->_ci->p->t('person', 'telefonklappe'), 'max' => 8])
]);
$this->_ci->customformvalidationlib->set_rules('gebteil', 'gebteil', 'max_length[32]', [
'max_length' => $this->_ci->p->t('ui', 'error_fieldMaxLength', ['field' => $this->_ci->p->t('ui', 'gebaudeteil'), 'max' => 32])
]);
$this->_ci->customformvalidationlib->set_rules('arbeitsplaetze', 'arbeitsplaetze', 'explicit_integer', [
'explicit_integer' => $this->_ci->p->t('ui', 'error_fieldInteger', ['field' => $this->_ci->p->t('ui', 'arbeitsplaetze')])
]);
return $this->_ci->customformvalidationlib->run();
}
public function errors()
{
return $this->_ci->customformvalidationlib->error_array();
}
}
@@ -79,10 +79,10 @@ class Paabgabe_model extends DB_Model
JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid)
JOIN public.tbl_person USING (person_id)
WHERE (campus.tbl_paabgabe.insertamum >= NOW() - INTERVAL ?
OR campus.tbl_paabgabe.updateamum >= NOW() - INTERVAL ?)
AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?";
WHERE (campus.tbl_paabgabe.insertamum::date = CURRENT_DATE - INTERVAL ?
OR campus.tbl_paabgabe.updateamum::date = CURRENT_DATE - INTERVAL ?)
AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?";
return $this->execQuery($query, [$interval, $interval, $relevantTypes]);
}
@@ -108,7 +108,7 @@ class Paabgabe_model extends DB_Model
JOIN public.tbl_person ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
WHERE campus.tbl_paabgabe.abgabedatum IS NOT NULL
AND campus.tbl_paabgabe.abgabedatum >= NOW() - INTERVAL ?";
AND campus.tbl_paabgabe.abgabedatum = CURRENT_DATE - INTERVAL ?";
if($relevantTypes !== null) {
$query .= " AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?";
@@ -35,5 +35,15 @@ class Standort_model extends DB_Model
return $this->loadWhere(array("firma_id" => $firma_id));
}
public function getByCompanyType($companyType)
{
$query = "SELECT s.* FROM public.tbl_standort s
JOIN public.tbl_firma f ON s.firma_id = f.firma_id
JOIN public.tbl_adresse a ON s.adresse_id = a.adresse_id
WHERE f.firmentyp_kurzbz = ?;";
return $this->execReadOnlyQuery($query, [$companyType]);
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
$includesArray = array(
'title' => ucfirst($this->p->t('ui', 'roomManagerPageTitle')),
'vue3' => true,
'axios027' => true,
'bootstrap5' => true,
'tabulator5' => true,
'fontawesome6' => true,
'primevue3' => true,
'navigationcomponent' => true,
'filtercomponent' => true,
'vuedatepicker11' => true,
'customJSs' => array(
'vendor/moment/luxonjs/luxon.min.js'
),
'customJSModules' => array(
'public/js/apps/RoomManagerApp.js'
),
'customCSSs' => array(
'public/css/components/primevue.css',
'public/css/components/verticalsplit.css',
'public/extensions/FHC-Core-Developer/css/FhcMain.css',
'public/css/components/calendar.css',
'public/css/components/vue-datepicker.css',
'public/css/roomManagerOverview.css'
)
);
$this->load->view('templates/FHC-Header', $includesArray);
?>
<div id="main">
<core-navigation-cmpt></core-navigation-cmpt>
<router-view
cis-root="<?= CIS_ROOT; ?>"
:permissions="<?= htmlspecialchars(json_encode($permissions)); ?>"
>
</router-view>
</div>
<?php $this->load->view('templates/FHC-Footer', $includesArray); ?>
+6 -4
View File
@@ -46,12 +46,13 @@ echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<link rel="stylesheet" href="../../../skin/tablesort.css" type="text/css"/>
<link rel="stylesheet" href="../../../skin/style.css.php" type="text/css">
<link rel="stylesheet" type="text/css" href="../../../skin/jquery-ui-1.9.2.custom.min.css">
<script type="text/javascript" src="../../../vendor/jquery/jquery1/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="../../../vendor/christianbach/tablesorter/jquery.tablesorter.min.js"></script>
<script type="text/javascript" src="../../../vendor/components/jqueryui/jquery-ui.min.js"></script>
<script type="text/javascript" src="../../../include/js/jquery.ui.datepicker.translation.js"></script>
<script type="text/javascript" src="../../../vendor/jquery/sizzle/sizzle.js"></script>';
include('../../../include/meta/jquery.php');
include('../../../include/meta/jquery-tablesorter.php');
const MOODLE_ADDON_KURZBZ = 'moodle';
// Load Addons to get Moodle_Path
@@ -71,7 +72,7 @@ echo '
$("#myTable").tablesorter(
{
sortList: [[0,0],[1,0]],
widgets: [\'zebra\']
widgets: [\'zebra\',\'filter\']
});
}
);
@@ -151,8 +152,9 @@ foreach($service->result as $row)
$person = new person();
$person->getPersonFromBenutzer($row->operativ_uid);
$operativ = $person->nachname.' '.$person->vorname;
$oeBez = new organisationseinheit($row->oe_kurzbz);
echo '<tr>';
echo '<td>',$row->oe_kurzbz,'</td>';
echo '<td>',$oeBez->bezeichnung,'</td>';
echo '<td><b>'.$row->bezeichnung.'</b></td>';
echo '<td>',$row->beschreibung,'</td>';
echo '<td><nobr><a href="../profile/index.php?uid='.$row->design_uid.'">',$design,'</a></nobr></td>';
+1 -1
View File
@@ -293,7 +293,7 @@ else if (isset($_SESSION['pruefling_id']))
}
$lastsemester = $row->semester;
echo '<table border="0" cellspacing="0" cellpadding="0" id="Gebiet" style="display: visible; border-collapse: separate; border-spacing: 0 3px;">';
echo '<table border="0" cellspacing="0" cellpadding="0" id="Gebiet" style="display: visible; border-collapse: separate; border-spacing: 0 3px; margin-top: 5px;">';
echo '<tr><td class="HeaderTesttool">'. ($row->semester == '1' ? $p->t('testtool/basisgebiete') : $p->t('testtool/quereinstiegsgebiete')).'</td></tr>';
}
@@ -342,6 +342,8 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
<vbox>
<checkbox id="mitarbeiter-entwicklungsteam-detail-checkbox-neu" checked="true" hidden="true" />
<textbox id="mitarbeiter-entwicklungsteam-detail-textbox-studiengang" hidden="true" />
<textbox id="mitarbeiter-entwicklungsteam-detail-entwicklungsteam_id" hidden="true" />
<groupbox id="mitarbeiter-entwicklungsteam-detail-groupbox" flex="1">
<caption label="Details" />
<grid id="mitarbeiter-entwicklungsteam-detail-grid" style="margin:4px;" flex="1">
@@ -1708,6 +1708,7 @@ function MitarbeiterEntwicklungsteamSelect()
document.getElementById('mitarbeiter-entwicklungsteam-detail-textbox-studiengang').value=studiengang_kz;
document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-beginn').value=beginn;
document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-ende').value=ende;
document.getElementById('mitarbeiter-entwicklungsteam-detail-entwicklungsteam_id').value=entwicklungsteam_id;
MitarbeiterEntwicklungsteamDetailDisableFields(false);
}
@@ -1725,6 +1726,7 @@ function MitarbeiterEntwicklungsteamSpeichern()
studiengang_kz_old = document.getElementById('mitarbeiter-entwicklungsteam-detail-textbox-studiengang').value;
beginn = document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-beginn').value;
ende = document.getElementById('mitarbeiter-entwicklungsteam-detail-datum-ende').value;
entwicklungsteam_id = document.getElementById('mitarbeiter-entwicklungsteam-detail-entwicklungsteam_id').value;
if(studiengang_kz=='')
{
+8
View File
@@ -3555,6 +3555,14 @@ function StudentZeugnisDokumentArchivieren()
case 'microcredential_2':
case 'microcredential_3':
case 'microcredential_4':
case 'microdegree_1':
case 'microdegree_2':
case 'microdegree_3':
case 'microdegree_4':
case 'microdegreeabschluss_1':
case 'microdegreeabschluss_2':
case 'microdegreeabschluss_3':
case 'microdegreeabschluss_4':
xml = 'microcredential.xml.php';
break;
+3 -1
View File
@@ -364,9 +364,10 @@ class entwicklungsteam extends basis_db
$bismeldung_jahr = $datetime->format('Y');
//laden des Datensatzes
$qry = "SELECT *
$qry = "SELECT tbl_entwicklungsteam.*, tbl_besqual.*, tbl_studiengang.studiengang_kz, tbl_studiengang.melderelevant
FROM bis.tbl_entwicklungsteam
JOIN bis.tbl_besqual USING(besqualcode)
JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid)."
AND (beginn is NULL OR beginn <= make_date(". $this->db_add_param($bismeldung_jahr). "::INTEGER, 12, 31))
AND (ende is NULL OR ende >= make_date(". $this->db_add_param($bismeldung_jahr). "::INTEGER, 1, 1))";
@@ -394,6 +395,7 @@ class entwicklungsteam extends basis_db
$obj->insertvon = $row->insertvon;
$obj->ext_id = $row->ext_id;
$obj->besqual = $row->besqualbez;
$obj->melderelevant = $this->db_parse_bool($row->melderelevant);
$this->result[] = $obj;
}
+4 -2
View File
@@ -584,8 +584,9 @@ class lehreinheitmitarbeiter extends basis_db
$qry = '
WITH semester_sws_tbl AS (
SELECT DISTINCT lehreinheit_id, studiensemester_kurzbz, lema.semesterstunden,
stg.studiengang_kz, stg.melde_studiengang_kz, stg.lgartcode
SELECT
DISTINCT lehreinheit_id, studiensemester_kurzbz, lema.semesterstunden,
stg.studiengang_kz, stg.melde_studiengang_kz, stg.lgartcode, stg.melderelevant
FROM lehre.tbl_lehreinheitmitarbeiter lema
JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id)
@@ -598,6 +599,7 @@ class lehreinheitmitarbeiter extends basis_db
AND ss.studiensemester_kurzbz IN ('.$this->implode4SQL($studiensemester_kurzbz_arr).')
-- nur lehre, die bisgemeldet wird
AND lema.bismelden
AND stg.melderelevant
-- keine lehreinheiten ohne semesterstunden
AND lema.semesterstunden != 0
)
+15 -5
View File
@@ -54,7 +54,7 @@ class ort extends basis_db
public $m2; // numeric(8,2)
public $gebteil; // varchar(32)
public $arbeitsplaetze; // integer
public $parent_ort_kurzbz; // varchar(16)
public $ort_kurzbz_old; // string
/**
@@ -117,6 +117,7 @@ class ort extends basis_db
$ort_obj->oe_kurzbz = $row->oe_kurzbz;
$ort_obj->gebteil = $row->gebteil;
$ort_obj->arbeitsplaetze = $row->arbeitsplaetze;
$ort_obj->parent_ort_kurzbz = $row->parent_ort_kurzbz;
$this->result[] = $ort_obj;
}
return true;
@@ -185,6 +186,7 @@ class ort extends basis_db
$ort_obj->oe_kurzbz = $row->oe_kurzbz;
$ort_obj->gebteil = $row->gebteil;
$ort_obj->arbeitsplaetze = $row->arbeitsplaetze;
$ort_obj->parent_ort_kurzbz = $row->parent_ort_kurzbz;
$this->result[] = $ort_obj;
}
return true;
@@ -232,6 +234,7 @@ class ort extends basis_db
$this->oe_kurzbz = $row->oe_kurzbz;
$this->m2 = $row->m2;
$this->arbeitsplaetze = $row->arbeitsplaetze;
$this->parent_ort_kurzbz = $row->parent_ort_kurzbz;
}
else
{
@@ -287,7 +290,7 @@ class ort extends basis_db
{
//Neuen Datensatz anlegen
$qry = 'INSERT INTO public.tbl_ort (ort_kurzbz, bezeichnung, planbezeichnung, max_person, aktiv, lehre, reservieren, lageplan,
dislozierung, kosten, stockwerk, standort_id, telefonklappe, insertamum, insertvon, updateamum, updatevon, content_id,ausstattung,m2,gebteil,oe_kurzbz,arbeitsplaetze) VALUES ('.
dislozierung, kosten, stockwerk, standort_id, telefonklappe, insertamum, insertvon, updateamum, updatevon, content_id,ausstattung,m2,gebteil,oe_kurzbz,arbeitsplaetze,parent_ort_kurzbz) VALUES ('.
$this->db_add_param($this->ort_kurzbz).', '.
$this->db_add_param($this->bezeichnung).', '.
$this->db_add_param($this->planbezeichnung).', '.
@@ -310,7 +313,8 @@ class ort extends basis_db
$this->db_add_param($this->m2).','.
$this->db_add_param($this->gebteil).','.
$this->db_add_param($this->oe_kurzbz).','.
$this->db_add_param($this->arbeitsplaetze).');';
$this->db_add_param($this->arbeitsplaetze).','.
$this->db_add_param($this->parent_ort_kurzbz).');';
}
else
{
@@ -337,7 +341,8 @@ class ort extends basis_db
'm2='.$this->db_add_param($this->m2).', '.
'gebteil='.$this->db_add_param($this->gebteil).', '.
'oe_kurzbz='.$this->db_add_param($this->oe_kurzbz).', '.
'arbeitsplaetze='.$this->db_add_param($this->arbeitsplaetze).' '.
'arbeitsplaetze='.$this->db_add_param($this->arbeitsplaetze).', '.
'parent_ort_kurzbz='.$this->db_add_param($this->parent_ort_kurzbz).' '.
'WHERE ort_kurzbz = '.$this->db_add_param(($this->ort_kurzbz_old!='')?$this->ort_kurzbz_old:$this->ort_kurzbz).';';
}
@@ -455,7 +460,8 @@ class ort extends basis_db
$ort_obj->gebteil = $row->gebteil;
$ort_obj->oe_kurzbz = $row->oe_kurzbz;
$ort_obj->arbeitsplaetze = $row->arbeitsplaetze;
$ort_obj->parent_ort_kurzbz = $row->parent_ort_kurzbz;
$this->result[] = $ort_obj;
}
return true;
@@ -523,6 +529,7 @@ class ort extends basis_db
$ort_obj->gebteil = $row->gebteil;
$ort_obj->oe_kurzbz = $row->oe_kurzbz;
$ort_obj->arbeitsplaetze = $row->arbeitsplaetze;
$ort_obj->parent_ort_kurzbz = $row->parent_ort_kurzbz;
$this->result[] = $ort_obj;
}
@@ -577,6 +584,8 @@ class ort extends basis_db
$ort_obj->oe_kurzbz = $row->oe_kurzbz;
$ort_obj->gebteil = $row->gebteil;
$ort_obj->arbeitsplaetze = $row->arbeitsplaetze;
$ort_obj->parent_ort_kurzbz = $row->parent_ort_kurzbz;
$this->result[] = $ort_obj;
}
return true;
@@ -634,6 +643,7 @@ class ort extends basis_db
$ort_obj->oe_kurzbz = $row->oe_kurzbz;
$ort_obj->gebteil = $row->gebteil;
$ort_obj->arbeitsplaetze = $row->arbeitsplaetze;
$ort_obj->parent_ort_kurzbz = $row->parent_ort_kurzbz;
$this->result[] = $ort_obj;
}
return true;
+41
View File
@@ -0,0 +1,41 @@
html {
font-size: .75em;
}
nav.navbar.navbar-header,
nav.navbar.navbar-left-side {
font-size: 18px
}
nav.navbar.navbar-left-side {
padding-top: 8px;
padding-bottom: 8px;
}
/* Relative sizing inside navbar */
nav.navbar .nav-item {
font-size: 18px
}
nav.navbar .navbar-brand-icon {
font-size: 16px
}
nav.navbar .left-side-menu-link-entry {
font-size: 14px !important;
}
nav.navbar .nav-link {
font-size: 18px;
padding-top: 15px;
padding-bottom: 8px;
}
nav.navbar .dropdown-menu {
padding: 8px 0px;
}
nav.navbar .dropdown-item {
font-size: 16px;
padding: 4px 16px;
}
+10
View File
@@ -0,0 +1,10 @@
export default {
getLocationsByCompanyType(companyType) {
return {
method: 'get',
url: '/api/frontend/v1/organisation/LocationApi/getLocationsByCompanyType',
params: { companyType }
};
}
};
@@ -0,0 +1,8 @@
export default {
getAllOrganizationalUnits() {
return {
method: "get",
url: "api/frontend/v1/organisation/organizationalUnitApi/getAllOrganizationalUnits",
};
},
}
+69 -2
View File
@@ -16,11 +16,52 @@
*/
export default {
getContentID(ort_kurbz) {
getAllRooms(params) {
return {
method: 'get',
url: 'api/frontend/v1/Ort/getAllRooms',
params: {
"filter[oe_kurzbz]" : params?.organizationalUnitShortCode,
"filter[standort_id]" : params?.locationId,
"filter[gebteil]" : params?.buildingComponent,
"filter[lehre]" : params?.isForTrainingProgram,
"filter[reservieren]" : params?.isReservationNeeded,
"filter[aktiv]" : params?.isActive,
"filter[ort_kurzbz]" : params?.shortCode,
"filter[bezeichnung]" : params?.description,
"filter[planbezeichnung]" : params?.planDescription,
"filter[max_person]" : params?.maxPersons,
"filter[arbeitsplaetze]" : params?.workplace,
"filter[m2]" : params?.squareMeters,
"filter[org_organisationseinheittyp_kurzbz_org_bezeichnung_concat]" : params?.orgUnitConcatDescription,
"filter[kosten]" : params?.costs,
"filter[stockwerk]" : params?.floor,
"filter[parent_ort_kurzbz]" : params?.parentRoomShortCode,
"filter[ort_kurzbz_bezeichnung_concat]" : params?.ort_kurzbz_bezeichnung_concat,
"sort[ort_kurzbz]" : params?.sort?.ort_kurzbz,
"sort[bezeichnung]" : params?.sort?.bezeichnung,
"sort[planbezeichnung]" : params?.sort?.planbezeichnung,
"sort[max_person]" : params?.sort?.max_person,
"sort[arbeitsplaetze]" : params?.sort?.arbeitsplaetze,
"sort[m2]" : params?.sort?.m2,
"sort[org_organisationseinheittyp_kurzbz_org_bezeichnung_concat]" : params?.sort?.org_organisationseinheittyp_kurzbz_org_bezeichnung_concat,
"sort[lehre]" : params?.sort?.lehre,
"sort[reservieren]" : params?.sort?.reservieren,
"sort[aktiv]" : params?.sort?.aktiv,
"sort[kosten]" : params?.sort?.kosten,
"sort[stockwerk]" : params?.sort?.stockwerk,
"sort[parent_ort_kurzbz]" : params?.sort?.parent_ort_kurzbz,
"pagination[page]" : params?.pagination?.page,
"pagination[size]" : params?.pagination?.size,
}
}
},
getContentID(ort_kurzbz) {
return {
method: 'get',
url: '/api/frontend/v1/Ort/ContentID',
params: { ort_kurzbz: ort_kurbz }
params: { ort_kurzbz: ort_kurzbz }
};
},
getRooms(datum, von, bis, typ, personenanzahl = 0) {
@@ -30,11 +71,37 @@ export default {
params: { datum, von, bis, typ, personenanzahl }
};
},
getRoom(ort_kurzbz) {
return {
method: 'get',
url: '/api/frontend/v1/Ort/getRoom/' + ort_kurzbz,
};
},
getRoomTypes() {
return {
method: 'get',
url: '/api/frontend/v1/Ort/getTypes',
params: { }
};
},
createRoom(roomData) {
return {
method: 'post',
url: '/api/frontend/v1/Ort/createRoom',
params: roomData
}
},
updateRoom(roomId, roomData) {
return {
method: 'post',
url: '/api/frontend/v1/Ort/updateRoom/' + roomId,
params: roomData
}
},
deleteRoom(ort_kurzbz) {
return {
method: 'post',
url: '/api/frontend/v1/Ort/deleteRoom/' + ort_kurzbz,
}
}
};
+47
View File
@@ -0,0 +1,47 @@
/**
* 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 <https://www.gnu.org/licenses/>.
*/
export default {
getRoomToRoomTypeRelationsByRoomShortCode(roomShortCode) {
return {
method: 'get',
url: `api/frontend/v1/RoomToRoomTypeApi/getRoomToRoomTypeRelationsByRoomShortCode/${roomShortCode}`,
}
},
createRoomToRoomTypeRelation(roomShortCode, roomTypeShortCode, hierarchy) {
return {
method: 'post',
url: `api/frontend/v1/RoomToRoomTypeApi/createRoomToRoomTypeRelation`,
params: {
roomShortCode,
roomTypeShortCode,
hierarchy
},
}
},
deleteRoomToRoomTypeRelation(roomShortCode, roomTypeShortCode, hierarchy) {
return {
method: 'post',
url: `api/frontend/v1/RoomToRoomTypeApi/deleteRoomToRoomTypeRelation`,
params: {
roomShortCode,
roomTypeShortCode,
hierarchy
},
}
}
};
+32
View File
@@ -0,0 +1,32 @@
/**
* 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 <https://www.gnu.org/licenses/>.
*/
export default {
getAllRoomTypes() {
return {
method: 'get',
url: 'api/frontend/v1/RoomTypeApi/getAllRoomTypes',
}
},
createRoomType(roomTypeData) {
return {
method: 'post',
url: 'api/frontend/v1/RoomTypeApi/createRoomType',
params: roomTypeData,
}
},
};
+57
View File
@@ -0,0 +1,57 @@
/**
* Copyright (C) 2023 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 <https://www.gnu.org/licenses/>.
*/
import RoomManagerOverview from "../components/RoomManager/RoomManagerOverview.js";
import {CoreNavigationCmpt} from '../components/navigation/Navigation.js';
import FhcAlert from "../plugins/FhcAlert.js";
import Phrasen from "../plugins/Phrasen.js";
import FhcApi from "../plugins/Api.js";
import {capitalize} from "../helpers/StringHelpers.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(),
routes: [
{
name: "overview",
path: `/${ciPath}/RoomManager`,
component: RoomManagerOverview,
},
],
});
const app = Vue.createApp({
components: {
RoomManagerOverview,
CoreNavigationCmpt
},
});
app.config.globalProperties.$capitalize = capitalize;
app.use(router)
.use(primevue.config.default, { zIndex: { overlay: 9999 } })
.use(FhcAlert)
.use(Phrasen)
.use(FhcApi)
.mount("#main");
@@ -0,0 +1,562 @@
import ApiRoom from "../../../js/api/factory/ort.js";
import ApiLocation from "../../../js/api/factory/location.js";
import ApiOrganizationalUnit from "../../../js/api/factory/organizationalUnit.js";
import BsModal from "../Bootstrap/Modal.js";
import CoreForm from "../Form/Form.js";
import FormInput from "../Form/Input.js";
export default {
name: "RoomFormModal",
components: {
BsModal,
CoreForm,
FormInput,
},
props: {
isVisible: {
type: Boolean,
required: true,
},
editedRoomShortCode: {
type: String,
default: null,
},
},
emits: ["hideBsModal", "roomCreated", "roomUpdated"],
watch: {
isVisible(newValue) {
if (newValue) {
this.$refs.roomFormModal.show();
} else {
this.$refs.roomFormModal.hide();
}
},
editedRoomShortCode(newValue) {
if (newValue) {
this.editRoom(newValue);
} else {
this.resetRoomForm();
}
},
},
data: () => {
return {
isEditInProgress: false,
organizationalUnits: [],
filteredOrganizationalUnits: [],
locations: [],
rooms: [],
filteredRooms: [],
editedRoom: null,
roomFormData: {
aktiv: true,
},
};
},
computed: {
dropdownParsedOrganizationalUnits() {
return this.organizationalUnits.map((unit) => {
return {
label: `${unit.bezeichnung} (${unit.organisationseinheittyp_kurzbz})`,
value: unit.oe_kurzbz,
};
});
},
dropdownParsedRooms() {
return this.rooms.map((room) => {
let label = room.ort_kurzbz;
if (room.bezeichnung && room.bezeichnung !== '') {
label += ` - ${room.bezeichnung}`;
}
return {
label,
value: room.ort_kurzbz,
};
});
},
},
methods: {
filterOrganizationalUnits(event) {
let defaultItem = {
label: this.$p.t("ui", "dropdownEmptyOption"),
value: null,
};
const query = event.query.toLowerCase();
if (!query) {
return (this.filteredOrganizationalUnits = [
defaultItem,
...this.dropdownParsedOrganizationalUnits,
]);
}
return (this.filteredOrganizationalUnits = [defaultItem].concat(
this.dropdownParsedOrganizationalUnits.filter((unit) => {
return unit.label.toLowerCase().includes(query);
}),
));
},
async filterRooms(event) {
this.rooms = await this.fetchRooms(event.query);
let defaultItem = {
label: this.$p.t("ui", "dropdownEmptyOption"),
value: null,
};
const query = event.query.toLowerCase();
if (!query) {
return (this.filteredRooms = [
defaultItem,
...this.dropdownParsedRooms,
]);
}
return (this.filteredRooms = [defaultItem]
.concat(this.dropdownParsedRooms)
.filter((room) => {
return room.label?.toLowerCase().includes(query);
}));
},
createRoom() {
return this.$refs.roomForm
.call(ApiRoom.createRoom(this.getApiCallParsedRoomFormData()))
.then((response) => {
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
this.$emit("roomCreated");
this.resetRoomForm();
this.hideRoomFormModal();
});
},
async editRoom(roomShortCode) {
let getLocationsResponse = await this.$api.call(
ApiRoom.getRoom(roomShortCode),
);
if (getLocationsResponse.meta.status === "success") {
this.editedRoom = getLocationsResponse.data;
} else {
this.$fhcAlert.alertError(this.$p.t("ui", "errorLoadingRoomData"));
return;
}
this.isEditInProgress = true;
let orgUnitData = null;
let orgUnit = this.organizationalUnits.find(
(unit) => unit.oe_kurzbz === this.editedRoom.oe_kurzbz,
);
if (orgUnit) {
orgUnitData = {
label: `${orgUnit.bezeichnung} (${orgUnit.organisationseinheittyp_kurzbz})`,
value: orgUnit.oe_kurzbz,
};
}
let potentialParentRooms = await this.fetchRooms(
this.editedRoom.parent_ort_kurzbz,
);
let parentRoomData = null;
let parentRoom = potentialParentRooms.find(
(room) => room.ort_kurzbz === this.editedRoom.parent_ort_kurzbz,
);
if (parentRoom) {
this.rooms.push(parentRoom);
let label = parentRoom.ort_kurzbz;
if (parentRoom.bezeichnung && parentRoom.bezeichnung !== '') {
label += ` - ${parentRoom.bezeichnung}`;
}
parentRoomData = {
label,
value: parentRoom.ort_kurzbz,
};
}
this.roomFormData = {
parentRoom: parentRoomData,
locationId: this.editedRoom.standort_id,
organizationalUnit: orgUnitData,
contentId: this.editedRoom.content_id,
kurzbezeichnung: this.editedRoom.ort_kurzbz,
bezeichnung: this.editedRoom.bezeichnung,
planbezeichnung: this.editedRoom.planbezeichnung,
aktiv: this.editedRoom.aktiv,
lehre: this.editedRoom.lehre,
reservieren: this.editedRoom.reservieren,
maxPerson: this.editedRoom.max_person,
stockwerk: this.editedRoom.stockwerk,
lageplan: this.editedRoom.lageplan,
dislozierung: this.editedRoom.dislozierung,
kosten: this.editedRoom.kosten,
ausstattung: this.editedRoom.ausstattung,
telefonklappe: this.editedRoom.telefonklappe,
quadratmeter: this.editedRoom.m2,
gebaudeteil: this.editedRoom.gebteil,
arbeitsplaetze: this.editedRoom.arbeitsplaetze,
};
this.$refs.roomFormModal.show();
},
updateRoom() {
return this.$refs.roomForm
.call(
ApiRoom.updateRoom(
this.editedRoom.ort_kurzbz,
this.getApiCallParsedRoomFormData(),
),
)
.then((response) => {
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
this.$emit("roomUpdated");
this.resetRoomForm();
this.hideRoomFormModal();
});
},
getApiCallParsedRoomFormData() {
return {
parent_ort_kurzbz: this.roomFormData.parentRoom?.value,
standort_id: this.roomFormData.locationId,
oe_kurzbz:
this.roomFormData.organizationalUnit?.value !== ""
? this.roomFormData.organizationalUnit?.value
: null,
content_id:
this.roomFormData.contentId !== ""
? this.roomFormData.contentId
: null,
ort_kurzbz: this.roomFormData.kurzbezeichnung,
bezeichnung: this.roomFormData.bezeichnung,
planbezeichnung: this.roomFormData.planbezeichnung,
aktiv: this.roomFormData.aktiv,
lehre: this.roomFormData.lehre,
reservieren: this.roomFormData.reservieren,
max_person:
this.roomFormData.maxPerson !== ""
? this.roomFormData.maxPerson
: null,
stockwerk:
this.roomFormData.stockwerk !== ""
? this.roomFormData.stockwerk
: null,
lageplan: this.roomFormData.lageplan,
dislozierung:
this.roomFormData.dislozierung === ""
? null
: this.roomFormData.dislozierung,
kosten:
this.roomFormData.kosten !== "" ? this.roomFormData.kosten : null,
ausstattung: this.roomFormData.ausstattung,
telefonklappe: this.roomFormData.telefonklappe,
m2:
this.roomFormData.quadratmeter !== ""
? this.roomFormData.quadratmeter
: null,
gebteil: this.roomFormData.gebaudeteil,
arbeitsplaetze:
this.roomFormData.arbeitsplaetze !== ""
? this.roomFormData.arbeitsplaetze
: null,
};
},
hideRoomFormModal() {
this.$refs.roomFormModal.hide();
this.$emit("hideBsModal");
this.resetRoomForm();
},
resetRoomForm() {
this.$refs.roomForm.clearValidation();
this.isEditInProgress = false;
this.editedRoom = null;
this.roomFormData = {
aktiv: true,
};
},
async fetchRooms(roomSearchTerm = "") {
let getRoomsResponse = await this.$api.call(
ApiRoom.getAllRooms({
ort_kurzbz_bezeichnung_concat: roomSearchTerm,
pagination: {
page: 1,
size: 100,
},
}),
);
if (getRoomsResponse.meta.status === "success") {
return getRoomsResponse.data;
} else {
this.$fhcAlert.alertError(this.$p.t("ui", "errorLoadingRooms"));
}
return [];
},
setDefaultLocationOption() {
this.locations.unshift({
standort_id: null,
bezeichnung: this.$p.t("ui", "dropdownEmptyOption"),
});
},
},
async created() {
let getLocationsResponse = await this.$api.call(
ApiLocation.getLocationsByCompanyType("Intern"),
);
if (getLocationsResponse.meta.status === "success") {
this.locations = getLocationsResponse.data;
} else {
this.$fhcAlert.alertError(this.$p.t("ui", "errorLoadingLocations"));
}
let getAllOrganizationalUnitsResponse = await this.$api.call(
ApiOrganizationalUnit.getAllOrganizationalUnits(),
);
if (getAllOrganizationalUnitsResponse.meta.status === "success") {
this.organizationalUnits = getAllOrganizationalUnitsResponse.data.sort(
(a, b) => a.bezeichnung.localeCompare(b.bezeichnung),
);
} else {
this.$fhcAlert.alertError(
this.$p.t("ui", "errorLoadingOrganizationalUnits"),
);
}
this.rooms = await this.fetchRooms();
},
mounted() {
this.$p
.loadCategory([
"global",
"lehre",
"ui",
"gruppenmanagement",
"core",
"person",
])
.then(() => {
this.phrasesLoaded = true;
this.setDefaultLocationOption();
});
},
template: /* html */ `
<bs-modal ref="roomFormModal" size="sm" @hideBsModal="() => { $emit('hideBsModal'); resetRoomForm(); }" class="modal-lg">
<template #title>
<p v-if="!editedRoom" class="fw-bold mt-3">{{$capitalize($p.t('ui', 'createRoomModalTitle'))}}</p>
<p v-else class="fw-bold mt-3">{{$capitalize($p.t('ui', 'editRoomModalTitle'))}}</p>
</template>
<template #default>
<core-form ref="roomForm" class="row g-3 pb-3">
<div class="row mb-3">
<form-input
v-model="roomFormData.parentRoom"
:label="$capitalize($p.t('ui/parentRoom'))"
:suggestions="filteredRooms"
:optionValue="(option) => option.value"
:optionLabel="(option) => option.label"
:delay="500"
@complete="filterRooms"
dropdown
forceSelection
type="autocomplete"
name="parent_ort_kurzbz"
>
</form-input>
</div>
<div class="row mb-3">
<div class="col">
<form-input
v-model="roomFormData.organizationalUnit"
:label="$capitalize($p.t('lehre/organisationseinheit'))"
:suggestions="filteredOrganizationalUnits"
:optionValue="(option) => option.value"
:optionLabel="(option) => option.label"
@complete="filterOrganizationalUnits"
dropdown
forceSelection
type="autocomplete"
name="oe_kurzbz"
>
</form-input>
</div>
<div class="col">
<form-input
v-model="roomFormData.locationId"
:label="$capitalize($p.t('person/standort'))"
type="select"
id="location"
name="standort_id"
>
<option
v-for="location in locations"
:key="location.standort_id"
:value="location.standort_id"
>
{{location.bezeichnung}}
</option>
</form-input>
</div>
</div>
<div class="row mb-3">
<div class="col">
<form-input
v-model="roomFormData.lehre"
:label="$capitalize($p.t('ui', 'lehre'))"
type="checkbox"
name="lehre"
>
</form-input>
</div>
<div class="col">
<form-input
v-model="roomFormData.reservieren"
:label="$capitalize($p.t('ui', 'reservieren'))"
type="checkbox"
name="reservieren"
>
</form-input>
</div>
<div class="col">
<form-input
v-model="roomFormData.aktiv"
:label="$capitalize($p.t('person', 'aktiv'))"
type="checkbox"
name="aktiv"
>
</form-input>
</div>
</div>
<div v-if='!this.editedRoom' class="row mb-3">
<form-input
v-model="roomFormData.kurzbezeichnung"
:label="$capitalize($p.t('gruppenmanagement', 'kurzbezeichnung'))"
type="text"
name="ort_kurzbz"
>
</form-input>
</div>
<div class="row mb-3">
<form-input
v-model="roomFormData.bezeichnung"
:label="$capitalize($p.t('ui', 'bezeichnung'))"
type="text"
name="bezeichnung"
>
</form-input>
</div>
<div class="row mb-3">
<form-input
v-model="roomFormData.planbezeichnung"
:label="$capitalize($p.t('ui', 'planbezeichnung'))"
type="text"
name="planbezeichnung"
>
</form-input>
</div>
<div class="row mb-3">
<div class="col">
<form-input
v-model.number="roomFormData.maxPerson"
:label="$capitalize($p.t('ui', 'maxPersons'))"
name="max_person"
>
</form-input>
</div>
<div class="col">
<form-input
v-model.number="roomFormData.stockwerk"
:label="$capitalize($p.t('ui', 'stockwerk'))"
name="stockwerk"
>
</form-input>
</div>
<div class="col">
<form-input
v-model.number="roomFormData.quadratmeter"
:label="$capitalize($p.t('ui', 'quadratmeter'))"
name="m2"
>
</form-input>
</div>
</div>
<div class="row mb-3">
<div class='col'>
<form-input
v-model="roomFormData.telefonklappe"
:label="$capitalize($p.t('person', 'telefonklappe'))"
name="telefonklappe"
>
</form-input>
</div>
<div class='col'>
<form-input
v-model.number="roomFormData.arbeitsplaetze"
:label="$capitalize($p.t('ui', 'arbeitsplaetze'))"
name="arbeitsplaetze"
>
</form-input>
</div>
<div class='col'>
<form-input
v-model="roomFormData.kosten"
:label="$capitalize($p.t('ui', 'kosten'))"
type="text"
name="kosten"
>
</form-input>
</div>
</div>
<div class="row mb-3">
<div class='col'>
<form-input
v-model="roomFormData.gebaudeteil"
:label="$capitalize($p.t('ui', 'gebaudeteil'))"
type="text"
name="gebteil"
>
</form-input>
</div>
<div class='col'>
<form-input
v-model.number="roomFormData.contentId"
:label="$capitalize($p.t('ui', 'contentId'))"
name="content_id"
>
</form-input>
</div>
<div class='col'>
<form-input
v-model.number="roomFormData.dislozierung"
:label="$capitalize($p.t('ui', 'dislozierung'))"
name="dislozierung"
>
</form-input>
</div>
</div>
<div class="row mb-3">
<form-input
v-model="roomFormData.lageplan"
:label="$capitalize($p.t('ui', 'lageplan'))"
type="textarea"
name="lageplan"
>
</form-input>
</div>
<div class="row mb-3">
<form-input
v-model="roomFormData.ausstattung"
:label="$capitalize($p.t('ui', 'ausstattung'))"
type="textarea"
name="ausstattung"
>
</form-input>
</div>
<div class="col d-flex justify-content-end gap-2">
<button type="button" class="btn btn-secondary" @click="hideRoomFormModal">{{$p.t('ui', 'abbrechen')}}</button>
<button type="button" class="btn btn-primary" @click="isEditInProgress ? updateRoom() : createRoom()">{{$p.t('ui', 'speichern')}}</button>
</div>
</core-form>
</template>
</bs-modal>
`,
};
@@ -0,0 +1,707 @@
import ApiRoom from "../../../js/api/factory/ort.js";
import ApiLocation from "../../../js/api/factory/location.js";
import ApiOrganizationalUnit from "../../../js/api/factory/organizationalUnit.js";
import { CoreFilterCmpt } from "../filter/Filter.js";
import CoreForm from "../Form/Form.js";
import FormInput from "../Form/Input.js";
import RoomFormModal from "./RoomFormModal.js";
import RoomTypeFormModal from "./RoomTypeFormModal.js";
export default {
name: "RoomManagerOverview",
components: {
CoreFilterCmpt,
CoreForm,
FormInput,
RoomFormModal,
RoomTypeFormModal,
},
props: {
permissions: Object,
},
provide() {
return {
cisRoot: this.cisRoot,
hasBasisOrtWPermission: this.permissions["basis/ort_w"] || false,
};
},
watch: {
filterData: {
handler(newValue) {
this.reloadTableData();
},
deep: true,
},
},
data() {
return {
phrasesLoaded: false,
filterData: {
locationId: null,
organizationalUnit: null,
buildingComponent: null,
isForTrainingProgram: null,
isReservationNeeded: null,
isActive: null,
},
locations: [],
organizationalUnits: [],
filteredOrganizationalUnits: [],
buildingComponents: [
{
label: "A",
value: "A",
},
{
label: "B",
value: "B",
},
{
label: "C",
value: "C",
},
{
label: "D",
value: "D",
},
{
label: "E",
value: "E",
},
{
label: "F",
value: "F",
},
],
isRoomFormModalVisible: false,
isRoomTypeFormModalVisible: false,
editedRoomShortCode: null,
editedRoomForRoomTypeManagement: null,
};
},
computed: {
hasBasisOrtWPermission() {
return this.permissions["basis/ort_w"] || false;
},
tabulatorOptions() {
const options = {
ajaxURL: "dummy",
ajaxRequestFunc: async (url, config, params) => {
let shortCodeFilter = params?.filter?.find(
(filter) => filter.field === "ort_kurzbz",
);
let descriptionFilter = params?.filter?.find(
(filter) => filter.field === "bezeichnung",
);
let planDescriptionFilter = params?.filter?.find(
(filter) => filter.field === "planbezeichnung",
);
let maxPersonsFilter = params?.filter?.find(
(filter) => filter.field === "max_person",
);
let workplaceFilter = params?.filter?.find(
(filter) => filter.field === "arbeitsplaetze",
);
let squareMetersFilter = params?.filter?.find(
(filter) => filter.field === "m2",
);
let orgUnitConcatFilter = params?.filter?.find(
(filter) => filter.field === "org_organisationseinheittyp_kurzbz_org_bezeichnung_concat",
);
let isForTrainingProgramFilter = params?.filter?.find(
(filter) => filter.field === "lehre",
);
let reservationNeededFilter = params?.filter?.find(
(filter) => filter.field === "reservieren",
);
let isActiveFilter = params?.filter?.find(
(filter) => filter.field === "aktiv",
);
let costsFilter = params?.filter?.find(
(filter) => filter.field === "kosten",
);
let floorFilter = params?.filter?.find(
(filter) => filter.field === "stockwerk",
);
let parentRoomFilter = params?.filter?.find(
(filter) => filter.field === "parent_ort_kurzbz",
);
let isForTrainingProgramValue = null;
if (this.filterData.isForTrainingProgram === true) {
isForTrainingProgramValue = true;
} else {
if (isForTrainingProgramFilter?.value === true) {
isForTrainingProgramValue = true;
} else if (isForTrainingProgramFilter?.value === false) {
isForTrainingProgramValue = false;
}
}
let reservationNeededValue = null;
if (this.filterData.isReservationNeeded === true) {
reservationNeededValue = true;
} else {
if (reservationNeededFilter?.value === true) {
reservationNeededValue = true;
} else if (reservationNeededFilter?.value === false) {
reservationNeededValue = false;
}
}
let isActiveValue = null;
if (this.filterData.isActive === true) {
isActiveValue = true;
} else {
if (isActiveFilter?.value === true) {
isActiveValue = true;
} else if (isActiveFilter?.value === false) {
isActiveValue = false;
}
}
let shortCodeSorter = params?.sort?.find((sort) => sort.field === "ort_kurzbz");
let descriptionSorter = params?.sort?.find((sort) => sort.field === "bezeichnung");
let planDescriptionSorter = params?.sort?.find((sort) => sort.field === "planbezeichnung");
let maxPersonsSorter = params?.sort?.find((sort) => sort.field === "max_person");
let workplaceSorter = params?.sort?.find((sort) => sort.field === "arbeitsplaetze");
let squareMetersSorter = params?.sort?.find((sort) => sort.field === "m2");
let orgUnitConcatSorter = params?.sort?.find((sort) => sort.field === "org_organisationseinheittyp_kurzbz_org_bezeichnung_concat");
let lehreSorter = params?.sort?.find((sort) => sort.field === "lehre");
let reservierenSorter = params?.sort?.find((sort) => sort.field === "reservieren");
let aktivSorter = params?.sort?.find((sort) => sort.field === "aktiv");
let costsSorter = params?.sort?.find((sort) => sort.field === "kosten");
let floorSorter = params?.sort?.find((sort) => sort.field === "stockwerk");
let parentRoomSorter = params?.sort?.find((sort) => sort.field === "parent_ort_kurzbz");
return this.$api.call(
ApiRoom.getAllRooms({
organizationalUnitShortCode:
this.filterData.organizationalUnit?.value,
locationId: this.filterData.locationId,
buildingComponent: this.filterData.buildingComponent,
isForTrainingProgram: isForTrainingProgramValue,
isReservationNeeded: reservationNeededValue,
isActive: isActiveValue,
shortCode: shortCodeFilter?.value,
description: descriptionFilter?.value,
planDescription: planDescriptionFilter?.value,
maxPersons: maxPersonsFilter?.value,
workplace: workplaceFilter?.value,
squareMeters: squareMetersFilter?.value,
orgUnitConcatDescription: orgUnitConcatFilter?.value,
costs: costsFilter?.value,
floor: floorFilter?.value,
parentRoomShortCode: parentRoomFilter?.value,
sort: {
ort_kurzbz: shortCodeSorter?.dir,
bezeichnung: descriptionSorter?.dir,
planbezeichnung: planDescriptionSorter?.dir,
max_person: maxPersonsSorter?.dir,
arbeitsplaetze: workplaceSorter?.dir,
m2: squareMetersSorter?.dir,
org_organisationseinheittyp_kurzbz_org_bezeichnung_concat: orgUnitConcatSorter?.dir,
lehre: lehreSorter?.dir,
reservieren: reservierenSorter?.dir,
aktiv: aktivSorter?.dir,
kosten: costsSorter?.dir,
stockwerk: floorSorter?.dir,
parent_ort_kurzbz: parentRoomSorter?.dir,
},
pagination: {
page: params.page,
size: params.size,
},
}),
);
},
ajaxResponse: (url, params, response) => response,
persistenceID: "room_manager_overview_table",
selectableRows: true,
index: "ort_kurzbz",
columns: [
{
title: this.$capitalize(
this.$p.t("gruppenmanagement", "kurzbezeichnung"),
),
field: "ort_kurzbz",
headerFilter: true,
width: 100,
},
{
title: this.$capitalize(
this.$p.t("gruppenmanagement", "bezeichnung"),
),
field: "bezeichnung",
headerFilter: true,
width: 200,
},
{
title: this.$capitalize(this.$p.t("ui", "planbezeichnung")),
field: "planbezeichnung",
headerFilter: true,
width: 150,
},
{
title: this.$capitalize(this.$p.t("ui", "maxPersons")),
field: "max_person",
headerFilter: true,
width: 80,
},
{
title: this.$capitalize(this.$p.t("ui", "arbeitsplaetze")),
field: "arbeitsplaetze",
headerFilter: true,
width: 80,
},
{
title: this.$capitalize(this.$p.t("ui", "quadratmeter")),
field: "m2",
headerFilter: true,
width: 100,
},
{
title: this.$capitalize(this.$p.t("lehre", "organisationseinheit")),
field: "org_organisationseinheittyp_kurzbz_org_bezeichnung_concat",
formatter: function (cell) {
let data = cell.getRow().getData();
let value = null;
if (data.org_organisationseinheittyp_kurzbz) {
value = `[${data.org_organisationseinheittyp_kurzbz}]`;
}
if (data.org_bezeichnung) {
value += ` ${data.org_bezeichnung}`;
}
return value;
},
sorter: function (a, b, aRow, bRow, column, dir, sorterParams) {
let aData = aRow.getData();
let bData = bRow.getData();
let aFull = (
aData.org_organisationseinheittyp_kurzbz +
" " +
aData.org_bezeichnung
).toLowerCase().trim();
let bFull = (
bData.org_organisationseinheittyp_kurzbz +
" " +
bData.org_bezeichnung
).toLowerCase().trim();
return aFull.localeCompare(bFull);
},
headerFilter: true,
width: 180,
},
{
title: this.$capitalize(this.$p.t("ui", "lehre")),
field: "lehre",
headerFilter: true,
headerFilterParams: {
tristate: true,
elementAttributes: { value: "true" },
},
formatter: "tickCross",
hozAlign: "center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>',
},
},
{
title: this.$capitalize(this.$p.t("ui", "reservieren")),
field: "reservieren",
headerFilter: true,
headerFilterParams: {
tristate: true,
elementAttributes: { value: "true" },
},
formatter: "tickCross",
hozAlign: "center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>',
},
},
{
title: this.$capitalize(this.$p.t("gruppenmanagement", "aktiv")),
field: "aktiv",
headerFilter: true,
headerFilterParams: {
tristate: true,
elementAttributes: { value: "true" },
},
formatter: "tickCross",
hozAlign: "center",
formatterParams: {
tickElement: '<i class="fa fa-check text-success"></i>',
crossElement: '<i class="fa fa-xmark text-danger"></i>',
},
},
{
title: this.$capitalize(this.$p.t("ui", "kosten")),
field: "kosten",
headerFilter: true,
},
{
title: this.$capitalize(this.$p.t("ui", "stockwerk")),
field: "stockwerk",
headerFilter: true,
},
{
title: this.$capitalize(this.$p.t("ui", "parentRoom")),
field: "parent_ort_kurzbz",
headerFilter: true,
width_: 120,
},
{
title: this.$capitalize(this.$p.t("global", "actions")),
field: "actions",
width: 120,
formatter: (cell, formatterParams, onRendered) => {
let container = document.createElement("div");
container.className = "d-flex gap-2 justify-content-center";
let roomTypeBtn = document.createElement("button");
roomTypeBtn.className = "btn btn-outline-secondary btn-action";
roomTypeBtn.innerHTML = '<i class="fa fa-layer-group"></i>';
roomTypeBtn.title = this.$capitalize(
this.$p.t("ui", "btn_editRoomType"),
);
roomTypeBtn.addEventListener("click", (event) =>
this.editRoomType(cell.getData().ort_kurzbz),
);
if (!this.hasBasisOrtWPermission) {
container.append(roomTypeBtn);
return container;
}
let button = document.createElement("button");
button = document.createElement("button");
button.className = "btn btn-outline-secondary btn-action";
button.innerHTML = '<i class="fa fa-edit"></i>';
button.title = this.$capitalize(this.$p.t("ui", "btn_editRoom"));
button.addEventListener("click", (event) =>
this.editRoom(cell.getData().ort_kurzbz),
);
container.append(button);
container.append(roomTypeBtn);
button = document.createElement("button");
button.className =
"btn btn-outline-secondary btn-action bg-danger";
button.innerHTML = '<i class="fa fa-xmark text-white"></i>';
button.title = this.$capitalize(
this.$p.t("ui", "btn_deleteRoom"),
);
button.addEventListener("click", () => {
let isDeletionConfirmed = confirm(
this.$p.t("ui", "deleteRoomConfirmation"),
);
if (!isDeletionConfirmed) return;
this.deleteRoom(cell.getData().ort_kurzbz);
});
container.append(button);
return container;
},
frozen: true,
},
],
layout: "fitColumns",
pagination: true,
paginationMode: "remote",
paginationSize: 100,
maxHeight: "700px",
filterMode: "remote",
sortMode: "remote",
};
return options;
},
tabulatorEvents() {
const events = [
{
event: "renderComplete",
handler: async () => {},
},
{
event: "cellClick",
handler: async (e, cell) => {
let updateableFieldsByClick = ["lehre", "reservieren", "aktiv"];
for (let field of updateableFieldsByClick) {
if (cell.getField() === field) {
let updatedValue = !cell.getValue();
this.$refs.roomManagerOverviewTable.tabulator.updateData([
{
ort_kurzbz: cell.getData().ort_kurzbz,
[field]: updatedValue,
},
]);
this.partialRoomUpdate(
cell.getData().ort_kurzbz,
field,
updatedValue,
);
this.$refs.roomManagerOverviewTable.tabulator.replaceData("/");
}
}
},
},
];
return events;
},
dropdownParsedOrganizationalUnits() {
return this.organizationalUnits
.map((unit) => {
return {
label: `[${unit.organisationseinheittyp_kurzbz}] ${unit.bezeichnung}`,
value: unit.oe_kurzbz,
};
})
.sort((a, b) => a.label.localeCompare(b.label));
},
},
methods: {
filterOrganizationalUnits(event) {
let defaultItem = {
label: this.$p.t("ui", "dropdownEmptyOption"),
value: null,
};
const query = event.query.toLowerCase();
if (!query) {
return (this.filteredOrganizationalUnits = [
defaultItem,
...this.dropdownParsedOrganizationalUnits,
]);
}
return (this.filteredOrganizationalUnits = [defaultItem]
.concat(this.dropdownParsedOrganizationalUnits)
.filter((unit) => {
return unit.label.toLowerCase().includes(query);
}));
},
showRoomFormModal() {
this.isRoomFormModalVisible = true;
},
editRoom(roomShortCode) {
this.editedRoomShortCode = roomShortCode;
},
deleteRoom(roomShortCode) {
this.$api
.call(ApiRoom.deleteRoom(roomShortCode))
.then((response) => {
if (response.meta.status === "success") {
this.reloadTableData();
this.$fhcAlert.alertSuccess(
this.$p.t("ui", "roomDeletedSuccessfully"),
);
} else {
this.reloadTableData();
this.$fhcAlert.alertError(this.$p.t("ui", "errorDeletingRoom"));
}
})
.catch((error) => {
this.$fhcAlert.alertError(this.$p.t("ui", "errorDeletingRoom"));
});
},
showRoomTypeFormModal() {
this.isRoomTypeFormModalVisible = true;
},
editRoomType(roomShortCode) {
this.editedRoomForRoomTypeManagement = roomShortCode;
},
async reloadTableData() {
this.$refs.roomManagerOverviewTable.tabulator.replaceData("/");
},
handleRoomUpdated() {
this.editedRoomShortCode = null;
this.reloadTableData();
},
async partialRoomUpdate(roomShortCode, attribute, value) {
let response = await this.$api.call(
ApiRoom.updateRoom(roomShortCode, {
[attribute]: value,
}),
);
if (response.meta.status === "success") {
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successUpdate"));
this.reloadTableData();
} else {
this.$fhcAlert.alertError(this.$p.t("ui", "errorUpdatingRoom"));
}
},
setDefaultBuildingComponentOption() {
this.buildingComponents.unshift({
label: this.$p.t("ui", "dropdownEmptyOption"),
value: null,
});
},
setDefaultLocationOption() {
this.locations.unshift({
standort_id: null,
bezeichnung: this.$p.t("ui", "dropdownEmptyOption"),
});
},
},
async created() {
let getLocationsResponse = await this.$api.call(
ApiLocation.getLocationsByCompanyType("Intern"),
);
if (getLocationsResponse.meta.status === "success") {
this.locations = getLocationsResponse.data;
} else {
this.$fhcAlert.alertError(this.$p.t("ui", "errorLoadingLocations"));
}
let getAllOrganizationalUnitsResponse = await this.$api.call(
ApiOrganizationalUnit.getAllOrganizationalUnits(),
);
if (getAllOrganizationalUnitsResponse.meta.status === "success") {
this.organizationalUnits = getAllOrganizationalUnitsResponse.data.sort(
(a, b) => a.bezeichnung.localeCompare(b.bezeichnung),
);
} else {
this.$fhcAlert.alertError(
this.$p.t("ui", "errorLoadingOrganizationalUnits"),
);
}
},
mounted() {
this.$p
.loadCategory([
"global",
"lehre",
"ui",
"gruppenmanagement",
"core",
"person",
])
.then(() => {
this.phrasesLoaded = true;
this.setDefaultBuildingComponentOption();
this.setDefaultLocationOption();
});
},
template: /* html */ `
<div class="container mt-4">
<h1 class='mb-5'>{{ $capitalize($p.t("ui", "roomManagerOverviewHeading")) }}</h1>
<div v-if="hasBasisOrtWPermission" class="row mb-3">
<div class="col d-flex justify-content-between">
<a class="btn btn-primary mb-3" @click="showRoomFormModal">{{$capitalize($p.t('ui', 'addRoomButton'))}}</a>
</div>
</div>
<core-filter-cmpt
v-if="phrasesLoaded"
ref="roomManagerOverviewTable"
table-only
:side-menu="false"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
>
<template #search>
<slot name="filterzuruecksetzen">
<core-form class="d-flex flex-column flex-md-row align-items-md-end gap-3">
<div>
<form-input
:label="$capitalize($p.t('lehre/organisationseinheit'))"
:suggestions="filteredOrganizationalUnits"
:optionValue="(option) => option.value"
:optionLabel="(option) => option.label"
@complete="filterOrganizationalUnits"
@itemSelect="(option) => { filterData.organizationalUnit = option.value; }"
dropdown
forceSelection
type="autocomplete"
name="organizationalUnitShortCode"
>
</form-input>
</div>
<div>
<form-input
v-model="filterData.locationId"
:label="$capitalize($p.t('person', 'standort'))"
type="select"
id="location"
name="location"
>
<option
v-for="location in locations"
:key="location.standort_id"
:value="location.standort_id"
>
{{location.bezeichnung}}
</option>
</form-input>
</div>
<div>
<form-input
v-model="filterData.buildingComponent"
:label="$capitalize($p.t('ui', 'buildingComponent'))"
type="select"
id="buildingComponent"
name="buildingComponent"
>
<option
v-for="component in buildingComponents"
:key="component"
:value="component.value"
>
{{component.label}}
</option>
</form-input>
</div>
<div>
<form-input
v-model="filterData.isForTrainingProgram"
:label="$capitalize($p.t('ui', 'lehre'))"
type="checkbox"
name="filterIsForTrainingProgram"
dropdown
></form-input>
</div>
<div>
<form-input
v-model="filterData.isReservationNeeded"
:label="$capitalize($p.t('ui', 'reservieren'))"
type="checkbox"
name="filterIsReservationNeeded"
dropdown
></form-input>
</div>
<div>
<form-input
v-model="filterData.isActive"
:label="$capitalize($p.t('person', 'aktiv'))"
type="checkbox"
name="filterIsActive"
dropdown
></form-input>
</div>
</core-form>
</slot>
</template>
</core-filter-cmpt>
<room-form-modal
:isVisible="isRoomFormModalVisible"
:editedRoomShortCode="editedRoomShortCode"
@hideBsModal="() => { isRoomFormModalVisible = false; editedRoomShortCode = null; }"
@roomCreated="handleRoomUpdated"
@roomUpdated="handleRoomUpdated"
/>
<room-type-form-modal
:isVisible="isRoomTypeFormModalVisible"
:editedRoomShortCode="editedRoomForRoomTypeManagement"
@hideBsModal="() => { isRoomTypeFormModalVisible = false; editedRoomForRoomTypeManagement = null; }"
/>
</div>
`,
};
@@ -0,0 +1,369 @@
import ApiRoomType from "../../../js/api/factory/roomType.js";
import ApiRoomToRoomType from "../../../js/api/factory/roomToRoomType.js";
import { CoreFilterCmpt } from "../filter/Filter.js";
import BsModal from "../Bootstrap/Modal.js";
import CoreForm from "../Form/Form.js";
import FormInput from "../Form/Input.js";
export default {
name: "RoomTypeFormModal",
components: {
BsModal,
CoreForm,
FormInput,
CoreFilterCmpt,
},
inject: ["hasBasisOrtWPermission"],
props: {
isVisible: {
type: Boolean,
required: true,
},
editedRoomShortCode: {
type: String,
default: null,
},
},
emits: [
"hideBsModal",
"roomTypeCreated",
"roomToRoomTypeCreated",
"roomToRoomTypeDeleted",
],
watch: {
isVisible(newValue) {
if (newValue) {
this.$refs.roomTypeFormModal.show();
} else {
this.$refs.roomTypeFormModal.hide();
}
},
async editedRoomShortCode(newValue) {
if (newValue) {
await this.$refs.roomTypesTable.reloadTable();
this.$refs.roomTypeFormModal.show();
} else {
this.resetRoomTypeForm();
}
},
},
data: () => {
return {
phrasesLoaded: false,
isEditInProgress: false,
editedRoom: null,
isRoomTypeFormVisible: false,
roomTypeFormData: {
aktiv: true,
},
roomToRoomTypeFormData: {},
roomTypes: [],
filteredRoomTypes: [],
};
},
computed: {
tabulatorOptions() {
const options = {
ajaxURL: "dummy",
ajaxRequestFunc: async () =>
this.$api.call(
ApiRoomToRoomType.getRoomToRoomTypeRelationsByRoomShortCode(
this.editedRoomShortCode,
),
),
ajaxResponse: (url, params, response) => response.data,
persistenceID: "room_type_assignment_table",
selectableRows: true,
columns: [
{
title: this.$capitalize(this.$p.t("ui", "roomType")),
field: "raumtyp_kurzbz",
width: 150,
},
{
title: this.$capitalize(this.$p.t("ui", "hierarchy")),
field: "hierarchie",
width: 50,
},
{
title: this.$capitalize(this.$p.t("gruppenmanagement", "beschreibung")),
field: "raumtyp_beschreibung",
},
{
title: this.$capitalize(this.$p.t("global", "actions")),
field: "actions",
width: 50,
formatter: (cell, formatterParams, onRendered) => {
if (!this.hasBasisOrtWPermission) return "";
let container = document.createElement("div");
container.className = "d-flex justify-content-center";
let button = document.createElement("button");
button = document.createElement("button");
button.className =
"btn btn-outline-secondary btn-action bg-danger";
button.innerHTML = '<i class="fa fa-xmark text-white"></i>';
button.title = this.$p.t(
"ui",
"btn_deleteRoomToRoomTypeRelation",
);
button.addEventListener("click", () => {
let isDeletionConfirmed = confirm(
this.$p.t("ui", "deleteRoomToRoomTypeRelationConfirmation"),
);
if (!isDeletionConfirmed) return;
this.deleteRoomToRoomTypeRelation(
cell.getData().ort_kurzbz,
cell.getData().raumtyp_kurzbz,
cell.getData().hierarchie,
);
});
container.append(button);
return container;
},
frozen: true,
visible: this.hasBasisOrtWPermission,
},
],
layout: "fitColumns",
};
return options;
},
tabulatorEvents() {
const events = [
{
event: "renderComplete",
handler: async () => {},
},
];
return events;
},
dropdownParsedRoomTypes() {
return this.roomTypes.map((roomType) => {
return {
label: `${roomType.raumtyp_kurzbz} - ${roomType.beschreibung}`,
value: roomType.raumtyp_kurzbz,
};
});
},
},
methods: {
filterRoomTypes(event) {
let defaultItem = {
label: this.$p.t("ui", "dropdownEmptyOption"),
value: null,
};
const query = event.query.toLowerCase();
if (!query) {
return (this.filteredRoomTypes = [
defaultItem,
...this.dropdownParsedRoomTypes,
]);
}
return (this.filteredRoomTypes = [defaultItem]
.concat(this.dropdownParsedRoomTypes)
.filter((roomType) => {
return roomType.label?.toLowerCase().includes(query);
}));
},
createRoomType() {
return this.$refs.roomTypeForm
.call(
ApiRoomType.createRoomType({
kurzbezeichnung: this.roomTypeFormData.shortCode,
beschreibung: this.roomTypeFormData.description,
}),
)
.then((response) => {
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
this.$emit("roomTypeCreated");
this.resetRoomTypeForm();
this.isRoomTypeFormVisible = false;
this.fetchRoomTypes();
});
},
createRoomToRoomTypeRelation() {
return this.$refs.roomToRoomTypeForm
.call(
ApiRoomToRoomType.createRoomToRoomTypeRelation(
this.editedRoomShortCode,
this.roomToRoomTypeFormData.roomType?.value,
this.roomToRoomTypeFormData.hierarchy,
),
)
.then((response) => {
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successSave"));
this.$emit("roomToRoomTypeCreated");
this.resetRoomTypeForm();
this.$refs.roomTypesTable.tabulator.replaceData("/");
});
},
deleteRoomToRoomTypeRelation(roomShortCode, roomTypeShortCode, hierarchy) {
return this.$api
.call(
ApiRoomToRoomType.deleteRoomToRoomTypeRelation(
roomShortCode,
roomTypeShortCode,
hierarchy
),
)
.then((response) => {
this.$fhcAlert.alertSuccess(this.$p.t("ui", "successDelete"));
this.$emit("roomToRoomTypeDeleted");
this.resetRoomTypeForm();
this.$refs.roomTypesTable.tabulator.replaceData("/");
});
},
hideRoomTypeFormModal() {
this.$refs.roomTypeFormModal.hide();
this.$emit("hideBsModal");
this.resetRoomTypeForm();
},
resetRoomTypeForm() {
this.$refs.roomTypeForm?.clearValidation();
this.isEditInProgress = false;
this.isRoomTypeFormVisible = false;
this.editedRoom = null;
this.roomTypeFormData = {
aktiv: true,
};
},
async fetchRoomTypes() {
let getRoomTypesResponse = await this.$api.call(
ApiRoomType.getAllRoomTypes(),
);
if (getRoomTypesResponse.meta.status === "success") {
this.roomTypes = getRoomTypesResponse.data;
} else {
this.$fhcAlert.alertError(this.$p.t("ui", "errorLoadingRoomTypes"));
}
},
},
async created() {
this.fetchRoomTypes();
this.$p
.loadCategory(["global", "lehre", "ui", "gruppenmanagement", "core", "person"])
.then(() => {
this.phrasesLoaded = true;
});
},
template: /* html */ `
<bs-modal
ref="roomTypeFormModal"
:bodyClass="'pt-4'"
@hideBsModal="() => { $emit('hideBsModal'); resetRoomTypeForm(); }"
size="sm"
class="modal-lg"
>
<template #title>
<p class="fw-bold mt-3">{{$capitalize($p.t('ui', 'assignRoomTypeToRoomModalTitle'))}}</p>
</template>
<template #default>
<div class="d-flex justify-content-end mb-1">
<a
v-if="!isRoomTypeFormVisible && hasBasisOrtWPermission"
:title='$capitalize($p.t("ui", "createRoomType"))'
@click.prevent="isRoomTypeFormVisible = !isRoomTypeFormVisible"
href="#"
class="btn btn-primary rounded-circle">
<i
class="fa fa-plus"
></i>
</a>
</div>
<div v-if="isRoomTypeFormVisible && hasBasisOrtWPermission" class="row g-3 pb-3">
<core-form ref="roomTypeForm">
<div class="row">
<div class="col">
<p class="fw-bold">{{$capitalize($p.t('ui', 'createRoomTypeFormTitle'))}}</p>
</div>
</div>
<div class="row mb-3">
<div class="col">
<form-input
v-model="roomTypeFormData.shortCode"
:label="$capitalize($p.t('gruppenmanagement', 'kurzbezeichnung'))"
type="text"
name="kurzbezeichnung"
>
</form-input>
</div>
<div class="col">
<form-input
v-model="roomTypeFormData.description"
:label="$capitalize($p.t('gruppenmanagement', 'beschreibung'))"
type="text"
name="beschreibung"
>
</form-input>
</div>
</div>
<div class="col d-flex justify-content-end gap-2">
<button type="button" class="btn btn-secondary" @click="isRoomTypeFormVisible = false">{{$p.t('ui', 'abbrechen')}}</button>
<button type="button" class="btn btn-primary" @click="createRoomType()">{{$p.t('ui', 'speichern')}}</button>
</div>
</core-form>
</div>
<div v-if="!isRoomTypeFormVisible && hasBasisOrtWPermission" class="row g-3 pb-3">
<core-form ref="roomToRoomTypeForm">
<div class="row">
<div class="col-8">
<form-input
v-model="roomToRoomTypeFormData.roomType"
:label="$capitalize($p.t('ui/roomType'))"
:suggestions="filteredRoomTypes"
:optionValue="(option) => option.value"
:optionLabel="(option) => option.label"
@complete="filterRoomTypes"
dropdown
forceSelection
type="autocomplete"
name="roomTypeShortCode"
>
</form-input>
</div>
<div class="col">
<form-input
v-model="roomToRoomTypeFormData.hierarchy"
:label="$capitalize($p.t('ui', 'hierarchy'))"
type="number"
name="hierarchy"
>
</form-input>
</div>
<div class="col justify-content-end align-items-end d-flex">
<button type="button" class="btn btn-primary" @click="createRoomToRoomTypeRelation()">{{$p.t('ui', 'speichern')}}</button>
</div>
</div>
</core-form>
</div>
<hr v-if="hasBasisOrtWPermission" class="mb-3 mt-0" />
<div class="row my-1">
<div class="col">
<p class="fw-bold">{{$capitalize($p.t('ui', 'assignedRoomTypesTitle'))}}</p>
</div>
</div>
<core-filter-cmpt
v-if="phrasesLoaded"
ref="roomTypesTable"
table-only
:side-menu="false"
:tabulator-options="tabulatorOptions"
:tabulator-events="tabulatorEvents"
>
</core-filter-cmpt>
</template>
</bs-modal>
`,
};
@@ -84,6 +84,14 @@ export default {
'microcredential_2',
'microcredential_3',
'microcredential_4',
'microdegree_1',
'microdegree_2',
'microdegree_3',
'microdegree_4',
'microdegreeabschluss_1',
'microdegreeabschluss_2',
'microdegreeabschluss_3',
'microdegreeabschluss_4',
]
},
documentDropdownObject: {}
+3 -3
View File
@@ -450,18 +450,18 @@ td.MarkLine
td.HeaderTesttool /*fuer die Button-Optik beim Testtool*/
{
color: #FFFFFF;
background-color: #00639C;
background-color: #71787D;
white-space:nowrap;
line-height: 25px;
box-shadow: inset 0 0 2px #FFFFFF;
padding: 10px;
padding: 0 10px;
width: 170px;
}
td.HeaderTesttoolSTG /*fuer die Button-Optik der Quereinstiegs-Studiengänge beim Testtool*/
{
color: white;
border: 2px solid #73a9d6;
padding: 10px;
padding: 0 10px;
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
+1 -1
View File
@@ -94,7 +94,7 @@ require_once('dbupdate_3.4/71399_dashboard_update_widget_paths.php');
require_once('dbupdate_3.4/71645_studvw_messagetab_ladezeit.php');
require_once('dbupdate_3.4/71566_studienordnungsdokument_neuer_organisationseinheitstyp_programm.php');
require_once('dbupdate_3.4/70376_lohnguide.php');
require_once('dbupdate_3.4/76663_tempus_rekursive_raum_struktur.php');
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
+116 -166
View File
@@ -22,11 +22,11 @@ GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE hr.tbl_lohnguide_jobfamilie TO vilesc
INSERT INTO hr.tbl_lohnguide_jobfamilie(jobfamilie_kurzbz, bezeichnung,aktiv, sort, insertvon, insertamum) VALUES
('FÜHRUNG','Führung',true,1,'system',NOW()),
('ALLGEMEIN','Allgemein',true,2,'system',NOW()),
('TECHNIK','Technik',true,3,'system',NOW()),
('IT','IT',true,4,'system',NOW()),
('PRODUKTION','Produktion',true,5,'system',NOW()),
('HANDW_IH_LOG','Handwerk, Instandhaltung + Logistik',true,6,'system',NOW())
('AKADEMIA','Akademia',true,2,'system',NOW()),
('VERWALTUNG','Verwaltung',true,3,'system',NOW()),
('TECHNIK','Technik',true,4,'system',NOW()),
('IT_SOFTWARE','IT & Software',true,5,'system',NOW()),
('TECHN_DIENSTE','Technische Dienste',true,6,'system',NOW())
ON CONFLICT (jobfamilie_kurzbz) DO NOTHING;
";
@@ -59,38 +59,33 @@ CREATE TABLE IF NOT EXISTS hr.tbl_lohnguide_modellfunktion (
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE hr.tbl_lohnguide_modellfunktion TO vilesci;
INSERT INTO hr.tbl_lohnguide_modellfunktion(modellfunktion_kurzbz, bezeichnung, jobfamilie_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('FÜHRUNG_I','Führung I','FÜHRUNG',true,1,'system',NOW()),
('FÜHRUNG_II','Führung I','FÜHRUNG',true,2,'system',NOW()),
('FÜHRUNG_III','Führung I','FÜHRUNG',true,3,'system',NOW()),
('GF','Geschäftsführung','FÜHRUNG',true,4,'system',NOW()),
/* Allgemein */
('FK_ALLGM','Fachkraft Allgemein','ALLGEMEIN',true,5,'system',NOW()),
('SFK_ALLGM','Spezial-Fachkraft Allgemein','ALLGEMEIN',true,6,'system',NOW()),
('SP_ALLGM','Spezialist:in Allgemein','ALLGEMEIN',true,7,'system',NOW()),
('EXP_ALLGM','Expert:in Allgemein','ALLGEMEIN',true,8,'system',NOW()),
('TOP_EXP_ALLGM','Top-Expert:in Allgemein','ALLGEMEIN',true,9,'system',NOW()),
('ABTEILUNGSLEITUNG','Abteilungsleitung','FÜHRUNG',true,1,'system',NOW()),
('GF','Geschäftsführung','FÜHRUNG',true,2,'system',NOW()),
('KOMPETENZFELDLEITER','Kompetenzfeldleiter*in','FÜHRUNG',true,3,'system',NOW()),
('DEPARTMENTSLEITER','Departmentsleiter*in','FÜHRUNG',true,4,'system',NOW()),
('FAKULTÄTSLEITER','Fakultätsleiter*in','FÜHRUNG',true,5,'system',NOW()),
/* Akademia */
('STUDENTISCHE_MA','Studentische MA','AKADEMIA',true,6,'system',NOW()),
('JUNIOR_LEC_RES','Junior Lecturer/Researcher','AKADEMIA',true,7,'system',NOW()),
('LEC_RES','Lecturer/Researcher','AKADEMIA',true,8,'system',NOW()),
('SEN_LEC_RES','Senior Lecturer/Researcher','AKADEMIA',true,9,'system',NOW()),
('STUDIENGANGSLEITUNG','Studiengangsleitung','AKADEMIA',true,10,'system',NOW()),
/* Verwaltung */
('FK_VERWALTUNG','Fachkraft Verwaltung','VERWALTUNG',true,11,'system',NOW()),
('SFK_VERWALTUNG','Spezial-Fachkraft Verwaltung','VERWALTUNG',true,12,'system',NOW()),
('SP_VERWALTUNG','Spezialist:in Verwaltung','VERWALTUNG',true,13,'system',NOW()),
('EXP_VERWALTUNG','Expert:in Verwaltung','VERWALTUNG',true,14,'system',NOW()),
/* Technik */
('FK_TECH','Fachkraft Technik','TECHNIK',true,10,'system',NOW()),
('SFK_TECH','Spezial-Fachkraft Technik','TECHNIK',true,11,'system',NOW()),
('SP_TECH','Spezialist:in Technik','TECHNIK',true,12,'system',NOW()),
('EXP_TECH','Expert:in Technik','TECHNIK',true,13,'system',NOW()),
('TOP_EXP_TECH','Top-Expert:in Technik','TECHNIK',true,14,'system',NOW()),
/* IT */
('FK_IT','Fachkraft IT','IT',true,15,'system',NOW()),
('SFK_IT','Spezial-Fachkraft IT','IT',true,16,'system',NOW()),
('SP_IT','Spezialist:in IT','IT',true,17,'system',NOW()),
('EXP_IT','Expert:in IT','IT',true,18,'system',NOW()),
('TOP_EXP_IT','Top-Expert:in IT','IT',true,19,'system',NOW()),
/* Produktion */
('HK_PROD','Hilfskraft Produktion','PRODUKTION',true,20,'system',NOW()),
('FK_PROD','Fachkraft Produktion','PRODUKTION',true,21,'system',NOW()),
('SFK_PROD','Spezial-Fachkraft Produktion','PRODUKTION',true,22,'system',NOW()),
('SP_PROD','Spezialist:in Produktion','PRODUKTION',true,23,'system',NOW()),
/* Handwerk, Instandhaltung, Logistik */
('HK_HIL','Hilfskraft Handwerk, Instandhaltung + Logistik','HANDW_IH_LOG',true,24,'system',NOW()),
('FK_HIL','Fachkraft Handwerk, Instandhaltung + Logistik','HANDW_IH_LOG',true,25,'system',NOW()),
('SFK_HIL','Spezial-Fachkraft Handwerk, Instandhaltung + Logistik','HANDW_IH_LOG',true,26,'system',NOW()),
('SP_HIL','Spezialist:in Handwerk, Instandhaltung + Logistik','HANDW_IH_LOG',true,27,'system',NOW())
('FK_TECHNIK','Fachkraft Technik','TECHNIK',true,15,'system',NOW()),
/* IT & Software */
('FK_IT','Fachkraft IT & Software','IT_SOFTWARE',true,16,'system',NOW()),
('SFK_IT','Spezial-Fachkraft IT & Software','IT_SOFTWARE',true,17,'system',NOW()),
('SP_IT','Spezialist:in IT & Software','IT_SOFTWARE',true,18,'system',NOW()),
('EXP_IT','Expert:in IT & Software','IT_SOFTWARE',true,19,'system',NOW()),
/* Technische Dienste */
('HK_TECHN_DIENSTE','Hilfskraft Technische Dienste','TECHN_DIENSTE',true,20,'system',NOW()),
('FK_TECHN_DIENSTE','Fachkraft Technische Dienste','TECHN_DIENSTE',true,21,'system',NOW()),
('SFK_TECHN_DIENSTE','Spezial-Fachkraft Technische Dienste','TECHN_DIENSTE',true,22,'system',NOW())
ON CONFLICT (modellfunktion_kurzbz) DO NOTHING;
@@ -111,6 +106,7 @@ if ($result = $db->db_query("SELECT * FROM information_schema.tables WHERE table
CREATE TABLE IF NOT EXISTS hr.tbl_lohnguide_modellstelle (
modellstelle_kurzbz character varying(32) NOT NULL,
bezeichnung varchar(128) NOT NULL,
code character varying(32) NOT NULL,
grade int NOT NULL,
modellfunktion_kurzbz character varying(32) NOT NULL,
aktiv boolean DEFAULT FALSE,
@@ -125,132 +121,94 @@ CREATE TABLE IF NOT EXISTS hr.tbl_lohnguide_modellstelle (
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE hr.tbl_lohnguide_modellstelle TO vilesci;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('111','Führung III 1/5',9,'FÜHRUNG_III',true,13,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('112','Führung III 2/5',10,'FÜHRUNG_III',true,14,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('113','Führung III 3/5',11,'FÜHRUNG_III',true,15,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('114','Führung III 4/5',12,'FÜHRUNG_III',true,16,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('115','Führung III 5/5',13,'FÜHRUNG_III',true,17,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('121','Führung II 1/4',14,'FÜHRUNG_II',true,7,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('122a','Führung II 2a/4',15,'FÜHRUNG_II',true,8,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('122b','Führung II 2b/4',15,'FÜHRUNG_II',true,9,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('123a','Führung II 3a/4',16,'FÜHRUNG_II',true,10,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('123b','Führung II 3b/4',16,'FÜHRUNG_II',true,11,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('124','Führung II 4/4',17,'FÜHRUNG_II',true,12,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('131','Führung I 1/4',18,'FÜHRUNG_I',true,1,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('132a','Führung I 2a/4',19,'FÜHRUNG_I',true,2,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('132b','Führung I 2b/4',19,'FÜHRUNG_I',true,3,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('133a','Führung I 3a/4',20,'FÜHRUNG_I',true,4,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('133b','Führung I 3b/4',20,'FÜHRUNG_I',true,5,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('134','Führung I 4/4',21,'FÜHRUNG_I',true,6,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- GF
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('141','Geschäftsführung 1/5',22,'GF',true,18,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('142a','Geschäftsführung 2a/5',23,'GF',true,19,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('142b','Geschäftsführung 2b/5',23,'GF',true,20,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('143a','Geschäftsführung 3a/5',24,'GF',true,21,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('143b','Geschäftsführung 3b/5',24,'GF',true,22,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('144a','Geschäftsführung 4a/5',25,'GF',true,23,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('144b','Geschäftsführung 4b/5',25,'GF',true,24,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('145','Geschäftsführung 5/5',26,'GF',true,25,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- FÜHRUNG
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz,bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('ABTL_1_4', 'Abteilungsleitung 1/4', '111', 16, 'ABTEILUNGSLEITUNG', true, 1, 'system', NOW()),
('ABTL_2A_4', 'Abteilungsleitung 2a/4', '112a', 17, 'ABTEILUNGSLEITUNG', true, 2, 'system', NOW()),
('ABTL_2B_4', 'Abteilungsleitung 2b/4', '112b', 17, 'ABTEILUNGSLEITUNG', true, 3, 'system', NOW()),
('ABTL_3A_4', 'Abteilungsleitung 3a/4', '113a', 18, 'ABTEILUNGSLEITUNG', true, 4, 'system', NOW()),
('ABTL_3B_4', 'Abteilungsleitung 3b/4', '113b', 18, 'ABTEILUNGSLEITUNG', true, 5, 'system', NOW()),
('ABTL_4_4', 'Abteilungsleitung 4/4', '114', 19, 'ABTEILUNGSLEITUNG', true, 6, 'system', NOW()),
('GF_1_2', 'Geschäftsführung 1/2', '121', 22, 'GF', true, 7, 'system', NOW()),
('GF_2_2', 'Geschäftsführung 2/2', '122', 23, 'GF', true, 8, 'system', NOW()),
('KOMFL_1_1', 'Kompetenzfeldleiter*in 1/1', '131', 15, 'KOMPETENZFELDLEITER', true, 9, 'system', NOW()),
('DEPL_1_1', 'Departmentleiter*in 1/1', '141', 18, 'DEPARTMENTSLEITER', true, 10, 'system', NOW()),
('FAKL_1_1', 'Fakultätsleiter*in 1/1', '151', 20, 'FAKULTÄTSLEITER', true, 11, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- Allgemein
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('211','Fachkraft Allgemein 1/3',4,'FK_ALLGM',true,26,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('212a','Fachkraft Allgemein 2a/3',5,'FK_ALLGM',true,27,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('212b','Fachkraft Allgemein 2b/3',5,'FK_ALLGM',true,28,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('213','Fachkraft Allgemein 3/3',6,'FK_ALLGM',true,29,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('221','Spezial-Fachkraft Allgemein 1/4', 7,'SFK_ALLGM',true,30,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('222a','Spezial-Fachkraft Allgemein 2a/4',8,'SFK_ALLGM',true,31,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('222b','Spezial-Fachkraft Allgemein 2b/4',8,'SFK_ALLGM',true,32,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('223a','Spezial-Fachkraft Allgemein 3a/4',9,'SFK_ALLGM',true,33,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('223b','Spezial-Fachkraft Allgemein 3b/4',9,'SFK_ALLGM',true,34,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('224','Spezial-Fachkraft Allgemein 4/4',10,'SFK_ALLGM',true,35,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('231','Spezialist:in Allgemein 1/4',11,'SP_ALLGM',true,36,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('232a','Spezialist:in Allgemein 2a/4',12,'SP_ALLGM',true,37,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('232b','Spezialist:in Allgemein 2b/4',12,'SP_ALLGM',true,38,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('233a','Spezialist:in Allgemein 3a/4',13,'SP_ALLGM',true,39,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('233b','Spezialist:in Allgemein 3b/4',13,'SP_ALLGM',true,40,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('234','Spezialist:in Allgemein 4/4',14,'SP_ALLGM',true,41,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('241','Expert:in Allgemein 1/4',15,'EXP_ALLGM',true,42,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('242a','Expert:in Allgemein 2a/4',16,'EXP_ALLGM',true,43,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('242b','Expert:in Allgemein 2b/4',16,'EXP_ALLGM',true,44,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('243a','Expert:in Allgemein 3a/4',17,'EXP_ALLGM',true,45,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('243b','Expert:in Allgemein 3b/4',17,'EXP_ALLGM',true,46,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('244','Expert:in Allgemein 4/4',18,'EXP_ALLGM',true,47,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('251','Top-Expert:in Allgemein 1/1',19,'TOP_EXP_ALLGM',true,48,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- AKADEMIA
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('STUDENTISCHE_MA_1_1', 'Studentische MA 1/1', '211', 5, 'STUDENTISCHE_MA', true, 12, 'system', NOW()),
('JUNIOR_LEC_RES_1_2', 'Junior Lecturer/Researcher 1/2', '221', 8, 'JUNIOR_LEC_RES', true, 13, 'system', NOW()),
('JUNIOR_LEC_RES_2_2', 'Junior Lecturer/Researcher 2/2', '222', 9, 'JUNIOR_LEC_RES', true, 14, 'system', NOW()),
('LEC_RES_1_2', 'Lecturer/Researcher 1/2', '231', 11, 'LEC_RES', true, 15, 'system', NOW()),
('LEC_RES_2_2', 'Lecturer/Researcher 2/2', '232', 12, 'LEC_RES', true, 16, 'system', NOW()),
('SEN_LEC_RES_1_2', 'Senior Lecturer/Researcher 1/2', '241', 13, 'SEN_LEC_RES', true, 17, 'system', NOW()),
('SEN_LEC_RES_2_2', 'Senior Lecturer/Researcher 2/2', '242', 14, 'SEN_LEC_RES', true, 18, 'system', NOW()),
('STGL_1_2', 'Studiengangsleitung 1/2', '251', 15, 'STUDIENGANGSLEITUNG', true, 19, 'system', NOW()),
('STGL_2_2', 'Studiengangsleitung 2/2', '252', 16, 'STUDIENGANGSLEITUNG', true, 20, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- Technik
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('311','Fachkraft Technik 1/3',4,'FK_TECH',true,49,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('312a','Fachkraft Technik 2a/3',5,'FK_TECH',true,50,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('312b','Fachkraft Technik 2b/3',5,'FK_TECH',true,51,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('313','Fachkraft Technik 3/3',6,'FK_TECH',true,52,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('321','Spezial-Fachkraft Technik 1/4',7,'SFK_TECH',true,53,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('322a','Spezial-Fachkraft Technik 2a/4',8,'SFK_TECH',true,54,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('322b','Spezial-Fachkraft Technik 2b/4',8,'SFK_TECH',true,55,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('323a','Spezial-Fachkraft Technik 3a/4',9,'SFK_TECH',true,56,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('323b','Spezial-Fachkraft Technik 3b/4',9,'SFK_TECH',true,57,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('324','Spezial-Fachkraft Technik 4/4',10,'SFK_TECH',true,58,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('331','Spezialist:in Technik 1/4',11,'SP_TECH',true,59,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('332a','Spezialist:in Technik 2a/4',12,'SP_TECH',true,60,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('332b','Spezialist:in Technik 2b/4',12,'SP_TECH',true,61,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('333a','Spezialist:in Technik 3a/4',13,'SP_TECH',true,62,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('333b','Spezialist:in Technik 3b/4',13,'SP_TECH',true,63,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('334','Spezialist:in Technik 4/4',14,'SP_TECH',true,64,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('341','Expert:in Technik 1/4',15,'EXP_TECH',true,65,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('342a','Expert:in Technik 2a/4',16,'EXP_TECH',true,66,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('342b','Expert:in Technik 2b/4',16,'EXP_TECH',true,67,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('343a','Expert:in Technik 3a/4',17,'EXP_TECH',true,68,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('343b','Expert:in Technik 3b/4',17,'EXP_TECH',true,69,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('344','Expert:in Technik 4/4',18,'EXP_TECH',true,70,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('351','Top-Expert:in Technik 1/1',19,'TOP_EXP_TECH',true,71,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- VERWALTUNG
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('FK_VERWALTUNG_1_3', 'Fachkraft Verwaltung 1/3', '311', 4, 'FK_VERWALTUNG', true, 21, 'system', NOW()),
('FK_VERWALTUNG_2A_3', 'Fachkraft Verwaltung 2a/3', '312a', 5, 'FK_VERWALTUNG', true, 22, 'system', NOW()),
('FK_VERWALTUNG_2B_3', 'Fachkraft Verwaltung 2b/3', '312b', 5, 'FK_VERWALTUNG', true, 23, 'system', NOW()),
('FK_VERWALTUNG_3_3', 'Fachkraft Verwaltung 3/3', '313', 6, 'FK_VERWALTUNG', true, 24, 'system', NOW()),
('SFK_VERWALTUNG_1_4', 'Spezial-Fachkraft Verwaltung 1/4', '321', 7, 'SFK_VERWALTUNG', true, 25, 'system', NOW()),
('SFK_VERWALTUNG_2A_4', 'Spezial-Fachkraft Verwaltung 2a/4', '322a', 8, 'SFK_VERWALTUNG', true, 26, 'system', NOW()),
('SFK_VERWALTUNG_2B_4', 'Spezial-Fachkraft Verwaltung 2b/4', '322b', 8, 'SFK_VERWALTUNG', true, 27, 'system', NOW()),
('SFK_VERWALTUNG_3A_4', 'Spezial-Fachkraft Verwaltung 3a/4', '323a', 9, 'SFK_VERWALTUNG', true, 28, 'system', NOW()),
('SFK_VERWALTUNG_3B_4', 'Spezial-Fachkraft Verwaltung 3b/4', '323b', 9, 'SFK_VERWALTUNG', true, 29, 'system', NOW()),
('SFK_VERWALTUNG_4_4', 'Spezial-Fachkraft Verwaltung 4/4', '324', 10, 'SFK_VERWALTUNG', true, 30, 'system', NOW()),
('SP_VERWATLTUNG_1_4', 'Spezialist:in Verwaltung 1/4', '331', 11, 'SP_VERWALTUNG', true, 31, 'system', NOW()),
('SP_VERWATLTUNG_2A_4', 'Spezialist:in Verwaltung 2a/4', '332a', 12, 'SP_VERWALTUNG', true, 32, 'system', NOW()),
('SP_VERWATLTUNG_2B_4', 'Spezialist:in Verwaltung 2b/4', '332b', 12, 'SP_VERWALTUNG', true, 33, 'system', NOW()),
('SP_VERWATLTUNG_3A_4', 'Spezialist:in Verwaltung 3a/4', '333a', 13, 'SP_VERWALTUNG', true, 34, 'system', NOW()),
('SP_VERWATLTUNG_3B_4', 'Spezialist:in Verwaltung 3b/4', '333b', 13, 'SP_VERWALTUNG', true, 35, 'system', NOW()),
('SP_VERWATLTUNG_4_4', 'Spezialist:in Verwaltung 4/4', '334', 14, 'SP_VERWALTUNG', true, 36, 'system', NOW()),
('EXP_VERWALTUNG_1_1', 'Expert:in Verwaltung 1/1', '341', 15, 'EXP_VERWALTUNG', true, 37, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- IT
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('411','Fachkraft IT 1/2',5,'FK_IT',true,72,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('412','Fachkraft IT 2/2',6,'FK_IT',true,73,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('421','Spezial-Fachkraft IT 1/4',7,'SFK_IT',true,74,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('422','Spezial-Fachkraft IT 2/4',8,'SFK_IT',true,75,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('423','Spezial-Fachkraft IT 3/4',9,'SFK_IT',true,76,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('424','Spezial-Fachkraft IT 4/4',10,'SFK_IT',true,77,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('431','Spezialist:in IT 1/4',11,'SP_IT',true,78,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('432a','Spezialist:in IT 2a/4',12,'SP_IT',true,79,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('432b','Spezialist:in IT 2b/4',12,'SP_IT',true,80,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('433a','Spezialist:in IT 3a/4',13,'SP_IT',true,81,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('433b','Spezialist:in IT 3b/4',13,'SP_IT',true,82,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('434','Spezialist:in IT 4/4',14,'SP_IT',true,83,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('441','Expert:in IT 1/4',15,'EXP_IT',true,84,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('442','Expert:in IT 2/4',16,'EXP_IT',true,85,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('443','Expert:in IT 3/4',17,'EXP_IT',true,86,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('444','Expert:in IT 4/4',18,'EXP_IT',true,87,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('451','Top-Expert:in IT 1/1',19,'TOP_EXP_IT',true,88,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- TECHNIK
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('FK_TECHNIK_1_3', 'Fachkraft Technik 1/3', '311', 4, 'FK_TECHNIK', true, 38, 'system', NOW()),
('FK_TECHNIK_2a_3', 'Fachkraft Technik 2a/3', '312a', 5, 'FK_TECHNIK', true, 39, 'system', NOW()),
('FK_TECHNIK_2b_3','Fachkraft Technik 2b/3', '312b', 5, 'FK_TECHNIK', true, 40, 'system', NOW()),
('FK_TECHNIK_3_3', 'Fachkraft Technik 3/3', '313', 6, 'FK_TECHNIK', true, 41, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- Produktion
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('511','Hilfskraft Produktion 1/4',1,'HK_PROD',true,89,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('512','Hilfskraft Produktion 2/4',2,'HK_PROD',true,90,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('513','Hilfskraft Produktion 3/4',3,'HK_PROD',true,91,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('514','Hilfskraft Produktion 4/4',4,'HK_PROD',true,92,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('521','Fachkraft Produktion 1/2',5,'FK_PROD',true,93,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('522','Fachkraft Produktion 2/2',6,'FK_PROD',true,94,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('531','Spezial-Fachkraft Produktion 1/4',7,'SFK_PROD',true,95,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('532','Spezial-Fachkraft Produktion 2/4',8,'SFK_PROD',true,96,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('533','Spezial-Fachkraft Produktion 3/4',9,'SFK_PROD',true,97,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('534','Spezial-Fachkraft Produktion 4/4',10,'SFK_PROD',true,98,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('541','Spezialist:in Produktion 1/4',11,'SP_PROD',true,99,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('542a','Spezialist:in Produktion 2a/4',12,'SP_PROD',true,100,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('542b','Spezialist:in Produktion 2b/4',12,'SP_PROD',true,101,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('543a','Spezialist:in Produktion 3a/4',13,'SP_PROD',true,102,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('543b','Spezialist:in Produktion 3b/4',13,'SP_PROD',true,103,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('544','Spezialist:in Produktion 4/4',14,'SP_PROD',true,104,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- IT & Software
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('FK_IT_1_2', 'Fachkraft IT & Software 1/2', '411', 5, 'FK_IT', true, 42, 'system', NOW()),
('FK_IT_2_2', 'Fachkraft IT & Software 2/2', '412', 6, 'FK_IT', true, 43, 'system', NOW()),
('SFK_IT_1_4', 'Spezial-Fachkraft IT & Software 1/4', '421', 7, 'SFK_IT', true, 44, 'system', NOW()),
('SFK_IT_2_4', 'Spezial-Fachkraft IT & Software 2/4', '422', 8, 'SFK_IT', true, 45, 'system', NOW()),
('SFK_IT_3_4', 'Spezial-Fachkraft IT & Software 3/4', '423', 9, 'SFK_IT', true, 46, 'system', NOW()),
('SFK_IT_4_4', 'Spezial-Fachkraft IT & Software 4/4', '424', 10, 'SFK_IT', true, 47, 'system', NOW()),
('SP_IT_1_4', 'Spezialist:in IT & Software 1/4', '431', 11, 'SP_IT', true, 48, 'system', NOW()),
('SP_IT_2A_4', 'Spezialist:in IT & Software 2a/4', '432a', 12, 'SP_IT', true, 49, 'system', NOW()),
('SP_IT_2B_4', 'Spezialist:in IT & Software 2b/4', '432b', 12, 'SP_IT', true, 50, 'system', NOW()),
('SP_IT_3A_4', 'Spezialist:in IT & Software 3a/4', '433a', 13, 'SP_IT', true, 51, 'system', NOW()),
('SP_IT_3B_4', 'Spezialist:in IT & Software 3b/4', '433b', 13, 'SP_IT', true, 52, 'system', NOW()),
('SP_IT_4_4', 'Spezialist:in IT & Software 4/4', '434', 14, 'SP_IT', true, 53, 'system', NOW()),
('EXP_IT_1_1', 'Expert:in IT & Software 1/1', '441', 15, 'EXP_IT', true, 54, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- Handwerk, Logistik, ..
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('611','Hilfskraft Handwerk, Instandhaltung + Logistik 1/4',1,'HK_HIL',true,105,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('612','Hilfskraft Handwerk, Instandhaltung + Logistik 2/4',2,'HK_HIL',true,106,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('613','Hilfskraft Handwerk, Instandhaltung + Logistik 3/4',3,'HK_HIL',true,107,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('614','Hilfskraft Handwerk, Instandhaltung + Logistik 4/4',4,'HK_HIL',true,108,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('621','Fachkraft Handwerk, Instandhaltung + Logistik 1/2',5,'FK_HIL',true,109,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('622','Fachkraft Handwerk, Instandhaltung + Logistik 2/2',6,'FK_HIL',true,110,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('631','Spezial-Fachkraft Handwerk, Instandhaltung + Logistik 1/4',7,'SFK_HIL',true,111,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('632','Spezial-Fachkraft Handwerk, Instandhaltung + Logistik 2/4',8,'SFK_HIL',true,112,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('633','Spezial-Fachkraft Handwerk, Instandhaltung + Logistik 3/4',9,'SFK_HIL',true,113,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES('634','Spezial-Fachkraft Handwerk, Instandhaltung + Logistik 4/4',10,'SFK_HIL',true,114,'system',NOW()) ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
-- TECHNISCHE DIENSTE
INSERT INTO hr.tbl_lohnguide_modellstelle(modellstelle_kurzbz, bezeichnung, code, grade, modellfunktion_kurzbz, aktiv, sort, insertvon, insertamum) VALUES
('HK_TECHN_DIENSTE_1_4', 'Hilfskraft Technische Dienste 1/4', '511', 1, 'HK_TECHN_DIENSTE', true, 55, 'system', NOW()),
('HK_TECHN_DIENSTE_2_4', 'Hilfskraft Technische Dienste 2/4', '512', 2, 'HK_TECHN_DIENSTE', true, 56, 'system', NOW()),
('HK_TECHN_DIENSTE_3_4', 'Hilfskraft Technische Dienste 3/4', '513', 3, 'HK_TECHN_DIENSTE', true, 57, 'system', NOW()),
('HK_TECHN_DIENSTE_4_4', 'Hilfskraft Technische Dienste 4/4', '514', 4, 'HK_TECHN_DIENSTE', true, 58, 'system', NOW()),
('FK_TECHN_DIENSTE_1_2', 'Fachkraft Technische Dienste 1/2', '521', 5, 'FK_TECHN_DIENSTE', true, 59, 'system', NOW()),
('FK_TECHN_DIENSTE_2_2', 'Fachkraft Technische Dienste 2/2', '522', 6, 'FK_TECHN_DIENSTE', true, 60, 'system', NOW()),
('SFK_TECHN_DIENSTE_1_4', 'Spezial-Fachkraft Technische Dienste 1/4', '531', 7, 'SFK_TECHN_DIENSTE', true, 61, 'system', NOW()),
('SFK_TECHN_DIENSTE_2_4', 'Spezial-Fachkraft Technische Dienste 2/4', '532', 8, 'SFK_TECHN_DIENSTE', true, 62, 'system', NOW()),
('SFK_TECHN_DIENSTE_3_4', 'Spezial-Fachkraft Technische Dienste 3/4', '533', 9, 'SFK_TECHN_DIENSTE', true, 63, 'system', NOW()),
('SFK_TECHN_DIENSTE_4_4', 'Spezial-Fachkraft Technische Dienste 4/4', '534', 10, 'SFK_TECHN_DIENSTE', true, 64, 'system', NOW())
ON CONFLICT (modellstelle_kurzbz) DO NOTHING;
";
@@ -280,16 +238,7 @@ CREATE TABLE IF NOT EXISTS hr.tbl_lohnguide_fachrichtung (
GRANT SELECT,INSERT,DELETE,UPDATE ON TABLE hr.tbl_lohnguide_fachrichtung TO vilesci;
INSERT INTO hr.tbl_lohnguide_fachrichtung(fachrichtung_kurzbz,bezeichnung,aktiv,insertvon,insertamum) VALUES
('FA00','Keine Berücksichtigung',true,'system',NOW()),
('FA01','Administration allgemein',true,'system',NOW()),
('FA02','Dienste Infrastruktur',true,'system',NOW()),
('FA03','Finanzwesen & Controlling',true,'system',NOW()),
('FA04','IT',true,'system',NOW()),
('FA05','Logistik',true,'system',NOW()),
('FA06','Marketing & Digitales Marketing',true,'system',NOW()),
('FA07','Produktion',true,'system',NOW()),
('FA08','Technik',true,'system',NOW()),
('FA09','Verkauf',true,'system',NOW())
('FA00','Keine Berücksichtigung',true,'system',NOW())
ON CONFLICT (fachrichtung_kurzbz) DO NOTHING;
";
@@ -298,6 +247,7 @@ ON CONFLICT (fachrichtung_kurzbz) DO NOTHING;
echo '<strong>Lohnguide Fachrichtung: ' . $db->db_last_error() . '</strong><br>';
else
echo 'hr.tbl_lohnguide_fachrichtung wurde neu erstellt<br>';
}
}
@@ -0,0 +1,22 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
if(!$result = @$db->db_query("SELECT parent_ort_kurzbz FROM public.tbl_ort LIMIT 1;"))
{
$qry = 'ALTER TABLE public.tbl_ort ADD COLUMN parent_ort_kurzbz VARCHAR(16);';
if(!$db->db_query($qry))
echo '<strong>public.tbl_ort: '.$db->db_last_error().'</strong><br>';
else
echo ' public.tbl_ort: parent_ort_kurzbz added successfully.<br>';
}
$result = $db->db_query("SELECT constraint_name FROM information_schema.table_constraints
WHERE table_name='tbl_ort' AND constraint_type='FOREIGN KEY' AND constraint_name='fk_parent_ort_kurzbz'");
if($db->db_num_rows($result)==0)
{
$qry = "ALTER TABLE public.tbl_ort ADD CONSTRAINT fk_parent_ort_kurzbz FOREIGN KEY(parent_ort_kurzbz) REFERENCES public.tbl_ort(ort_kurzbz);";
if(!$db->db_query($qry))
echo '<strong>public.tbl_ort: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Added foreign key constraint fk_parent_ort_kurzbz to public.tbl_ort';
}
File diff suppressed because it is too large Load Diff
+8 -7
View File
@@ -742,7 +742,7 @@ function _getFunktionscontainer_Funktionscode123456($bisfunktion_arr)
$has_oe_lehrgang = !($studiengang->studiengang_kz > 0 && $studiengang->studiengang_kz < 10000);
// STG, die nicht BIS-bemeldet werden, ueberspringen
if (in_array($studiengang->studiengang_kz, BIS_EXCLUDE_STG))
if (in_array($studiengang->studiengang_kz, BIS_EXCLUDE_STG) || !$studiengang->melderelevant)
{
continue;
}
@@ -825,6 +825,7 @@ function _addFunktionscontainer_Funktionscode7($uid, $funktion_arr, $stichtag)
$entwicklungsteam_arr = array_filter($entwicklungsteam_arr, function ($obj) {
return
!in_array($obj->studiengang_kz, BIS_EXCLUDE_STG) &&
$obj->melderelevant &&
$obj->studiengang_kz > 0 &&
$obj->studiengang_kz < 10000;
});
@@ -889,7 +890,7 @@ function _getLehrecontainer($sws_proStg_arr)
$kennzeichen_name = $is_lehrgang ? 'LehrgangNr' : 'StgKz';
// Lehreobjekt generieren
if (empty($lehre_arr) || !lehre_stg_exists($sws_proStg->studiengang_kz, $lehre_arr))
if (empty($lehre_arr) || !lehre_stg_exists($sws_proStg->melde_studiengang_kz, $lehre_arr))
{
$lehre_obj = new StdClass();
@@ -904,8 +905,8 @@ function _getLehrecontainer($sws_proStg_arr)
}
else // Lehrecontainer mit STG schon vorhanden
{
$lehre_obj_arr = array_filter($lehre_arr, function (&$obj) use ($sws_proStg) {
return $obj->StgKz == $sws_proStg->studiengang_kz;
$lehre_obj_arr = array_filter($lehre_arr, function (&$obj) use ($sws_proStg, $kennzeichen_name) {
return isset($obj->{$kennzeichen_name}) && $obj->{$kennzeichen_name} == $sws_proStg->melde_studiengang_kz;
});
// SWS ergaenzen
@@ -1359,15 +1360,15 @@ function verwendung_exists($bisverwendung, $verwendung_arr)
/**
* Prueft ob ein Studiengang bereits im Lehre Container vorhanden ist
* @param $studiengang_kz Studiengangskennzahl
* @param $melde_studiengang_kz Studiengangskennzahl
* @param $lehre_arr Array mit Lehre Objekten
* @return true wenn der Studiengang bereits existiert
*/
function lehre_stg_exists($studiengang_kz, $lehre_arr)
function lehre_stg_exists($melde_studiengang_kz, $lehre_arr)
{
foreach($lehre_arr as $row)
{
$kennzeichenName = $row->LehrgangNr ?? $row->StgKz;
$kennzeichenName = isset($row->LehrgangNr) ? 'LehrgangNr' : 'StgKz';
if(isset($row->{$kennzeichenName}) && $row->{$kennzeichenName} == $melde_studiengang_kz)
return true;
}
+6
View File
@@ -67,6 +67,7 @@
$gebteil='';
$m2='';
$arbeitsplaetze='';
$parent_ort_kurzbz = '';
$neu = "true";
@@ -93,6 +94,7 @@
$oe_kurzbz = $_POST["oe_kurzbz"];
$gebteil = $_POST["gebteil"];
$arbeitsplaetze = $_POST["arbeitsplaetze"];
$parent_ort_kurzbz = $_POST["parent_ort_kurzbz"];
$sg_update = new ort();
$sg_update->ort_kurzbz = $ort_kurzbz;
@@ -115,6 +117,7 @@
$sg_update->gebteil = $gebteil;
$sg_update->oe_kurzbz = $oe_kurzbz;
$sg_update->arbeitsplaetze = $arbeitsplaetze;
$sg_update->parent_ort_kurzbz = $parent_ort_kurzbz;
$sg_update->updateamum = date('Y-m-d H:i:s');
$sg_update->updatevon = $user;
@@ -161,6 +164,7 @@
$m2 = $sg->m2;
$oe_kurzbz = $sg->oe_kurzbz;
$arbeitsplaetze = $sg->arbeitsplaetze;
$parent_ort_kurzbz = $sg->parent_ort_kurzbz;
$neu = "false";
}
@@ -402,6 +406,8 @@
<td><input class="detail" type="text" name="telefonklappe" size="3" maxlength="8" value="'.$telefonklappe.'" onchange="submitable()"></td>
<td>Anz. Arbeitsplätze</td>
<td><input class="detail" type="text" name="arbeitsplaetze" size="3" maxlength="8" value="'.$arbeitsplaetze.'" onchange="submitable()"></td>
<td>Parent Raum Kurzbz</td>
<td><input type="text" name="parent_ort_kurzbz" size="10" onchange="submitable()" value="'.$parent_ort_kurzbz.'" /></td>
</tr>
<tr>
<td valign="top">Lageplan</td>
+14 -3
View File
@@ -227,7 +227,8 @@ if (isset($_GET['sendform']))
<table class="tablesorter" id="t1">
<thead>
<tr>
<th><span class="tooltip"><img src="../../skin/images/information.png" height="20px" name="infoicon"/>
<th><button type="button" class="resetsaved" title="Reset Filter">Reset Filter</button>
<span class="tooltip"><img src="../../skin/images/information.png" height="20px" name="infoicon"/>
'.$tooltiptext.'
</span>
</th>
@@ -243,6 +244,7 @@ if (isset($_GET['sendform']))
<th>Aktiv</th>
<th>Kosten</th>
<th>Stockwerk</th>
<th>Parent Ort Kurzbz</th>
</tr>
</thead>
<tbody>';
@@ -286,6 +288,7 @@ if (isset($_GET['sendform']))
$htmlstr .= " <td>".$twraum->kosten."</td>\n";
$htmlstr .= " <td>".$twraum->stockwerk."</td>\n";
$htmlstr .= " <td><a href='raum_details.php?ort_kurzbz=".$twraum->parent_ort_kurzbz."' target='detail_raum'>".$twraum->parent_ort_kurzbz."</a></td>\n";
$htmlstr .= " </tr>\n";
}
@@ -364,9 +367,10 @@ if (isset($_GET['sendform']))
$("#t1").tablesorter(
{
sortList: [[3,0]],
widgets: ["zebra", "filter", "stickyHeaders"],
widgets: ["saveSort", "zebra", "filter", "stickyHeaders"],
headers: { 0: { filter: false, sorter: false }},
widgetOptions : { filter_functions : {
widgetOptions : { filter_saveFilters : true,
filter_functions : {
// Add select menu to this column
8 : {
"True" : function(e, n, f, i, $r, c, data) { return /t/.test(e); },
@@ -381,6 +385,13 @@ if (isset($_GET['sendform']))
"False" : function(e, n, f, i, $r, c, data) { return /f/.test(e); }
}
}}
});
$('.resetsaved').click(function()
{
$("#t1").trigger("filterReset");
location.reload(forceGet);
return false;
});
});
@@ -588,7 +588,9 @@ if(isset($_POST['testergebnisanzeigen']) && isset($_POST['prestudent_id']))
{
if(is_numeric($_POST['prestudent_id']) && $_POST['prestudent_id']!='')
{
$qry="SELECT nachname,vorname,person_id,prestudent_id,tbl_pruefling.pruefling_id,tbl_pruefling_frage.begintime,bezeichnung,kurzbz,tbl_frage.nummer,level, tbl_vorschlag.nummer as antwortnummer, tbl_vorschlag.punkte
$qry="SELECT nachname,vorname,person_id,prestudent_id,tbl_pruefling.pruefling_id,
tbl_pruefling_frage.begintime,bezeichnung,kurzbz,tbl_frage.nummer,level,
tbl_vorschlag.nummer as antwortnummer, tbl_vorschlag.punkte, tbl_frage.frage_id
FROM testtool.tbl_antwort
JOIN testtool.tbl_vorschlag USING(vorschlag_id)
JOIN testtool.tbl_frage USING (frage_id)
@@ -615,6 +617,7 @@ if(isset($_POST['testergebnisanzeigen']) && isset($_POST['prestudent_id']))
<th>Level</th>
<th>Antwort #</th>
<th>Punkte</th>
<th>FrageID</th>
</tr>
</thead>
<tbody>';
@@ -632,6 +635,7 @@ if(isset($_POST['testergebnisanzeigen']) && isset($_POST['prestudent_id']))
echo "<td>$row->level</td>";
echo "<td>$row->antwortnummer</td>";
echo "<td>$row->punkte</td>";
echo "<td>$row->frage_id</td>";
echo '</tr>';
}
echo '</tbody></table>';
+29 -2
View File
@@ -837,6 +837,25 @@ if(isset($_GET['excel']))
<script src="../../vendor/fgelinas/timepicker/jquery.ui.timepicker.js" type="text/javascript" ></script>
<script type="text/javascript">
$.tablesorter.addParser({
id: "customDate",
is: function(s) {
//return false;
//use the above line if you don\'t want table sorter to auto detected this parser
// match dd.mm.yyyy e.g. 01.01.2001 as regex
//return /\d{1,4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2} .*/.test(s);
return /\d{1,2}.\d{1,2}.\d{1,4}.*/.test(s);
},
// replace regex-wildcards and return new date
format: function(s) {
s = s.replace(/\-/g," ");
s = s.replace(/:/g," ");
s = s.replace(/\./g," ");
s = s.split(" ");
return $.tablesorter.formatFloat(new Date(s[2], s[1]-1, s[0]).getTime());
},
type: "numeric"
});
$(document).ready(function()
{
// Check, ob Räume zugeteilt sind oder max_teilnehmer gesetzt ist, wenn "öffentlich" gesetzt wird
@@ -1007,7 +1026,7 @@ if(isset($_GET['excel']))
{
widgets: ["zebra", "filter", "stickyHeaders"],
sortList: [[2,0],[3,0]],
headers: {0: { sorter: false}},
headers: {0: { sorter: false},10: { sorter: "customDate"},11: { sorter: "customDate"}},
widgetOptions: {filter_cssFilter: [
"filter_clm_null",
"filter_clm_prestudent_id",
@@ -1020,6 +1039,7 @@ if(isset($_GET['excel']))
"filter_clm_studienplan",
"filter_clm_einstiegssemester",
"filter_clm_geburtsdatum",
"filter_clm_anmeldedatum",
"filter_clm_email",
"filter_clm_absolviert"]}
});
@@ -1072,6 +1092,7 @@ if(isset($_GET['excel']))
'clm_studienplan',
'clm_einstiegssemester',
'clm_geburtsdatum',
"filter_clm_anmeldedatum",
'clm_email',
'clm_absolviert'];
for (var i in arr)
@@ -2697,7 +2718,8 @@ if($reihungstest_id!='')
WHERE prestudent_id = tbl_prestudent.prestudent_id
AND status_kurzbz = 'Interessent'
) LIMIT 1
) AS orgform_kurzbz
) AS orgform_kurzbz,
tbl_rt_person.anmeldedatum
FROM PUBLIC.tbl_rt_person
JOIN PUBLIC.tbl_person USING (person_id)
JOIN PUBLIC.tbl_reihungstest rt ON (rt_id = rt.reihungstest_id)
@@ -2786,6 +2808,7 @@ if($reihungstest_id!='')
echo '<div id="clm_studienplan" class="active" onclick="hideColumn(\'clm_studienplan\')">Studienplan</div>';
echo '<div id="clm_einstiegssemester" class="active" onclick="hideColumn(\'clm_einstiegssemester\')">Einstiegssemester</div>';
echo '<div id="clm_geburtsdatum" class="active" onclick="hideColumn(\'clm_geburtsdatum\')">Geburtsdatum</div>';
echo '<div id="clm_anmeldedatum" class="active" onclick="hideColumn(\'clm_anmeldedatum\')">Geburtsdatum</div>';
echo '<div id="clm_email" class="active" onclick="hideColumn(\'clm_email\')">EMail</div>';
echo '<div id="clm_absolviert" class="active" onclick="hideColumn(\'clm_absolviert\')">Absolvierte Tests <span class="wait"></span></div>';
//echo '<div id="clm_ergebnis" class="active" onclick="hideColumn(\'clm_ergebnis\')">Ergebnis <span class="wait"></span></div>';
@@ -2827,6 +2850,7 @@ if($reihungstest_id!='')
<th style="display: table-cell" class="clm_studienplan">Studienplan</th>
<th style="display: table-cell" class="clm_einstiegssemester">Einstiegssemester</th>
<th style="display: table-cell" class="clm_geburtsdatum">Geburtsdatum</th>
<th style="display: table-cell" class="clm_anmeldedatum">Anmeldedatum</th>
<th style="display: table-cell" class="clm_email">EMail</th>
<th style="display: table-cell" class="clm_absolviert">bereits absolvierte Verfahren</th>
<!--<th style="display: table-cell" class="clm_ergebnis">Ergebnis</th>
@@ -2946,6 +2970,7 @@ if($reihungstest_id!='')
<td style="display: table-cell" class="clm_studienplan">'.$db->convert_html_chars($studienplan_bezeichnung).' ('.$row->studienplan_id.')</td>
<td style="display: table-cell" class="clm_einstiegssemester">'.$db->convert_html_chars($row->ausbildungssemester).'</td>
<td style="display: table-cell" class="clm_geburtsdatum">'.$db->convert_html_chars($row->gebdatum!=''?$datum_obj->convertISODate($row->gebdatum):' ').'</td>
<td style="display: table-cell" class="clm_anmeldedatum">'.$db->convert_html_chars($row->anmeldedatum!=''?$datum_obj->convertISODate($row->anmeldedatum):' ').'</td>
<td style="display: table-cell; text-align: center" class="clm_email"><a href="mailto:'.$db->convert_html_chars($row->email).'"><img src="../../skin/images/button_mail.gif" name="mail"></a></td>
<td style="display: table-cell;" class="clm_absolviert">'.$rt_in_anderen_stg.'</td>
</tr>';
@@ -3009,6 +3034,7 @@ if($reihungstest_id!='')
<th style="display: table-cell" class="clm_studienplan">Studienplan</th>
<th style="display: table-cell" class="clm_einstiegssemester">Einstiegssemester</th>
<th style="display: table-cell" class="clm_geburtsdatum">Geburtsdatum</th>
<th style="display: table-cell" class="clm_anmeldedatum">Anmeldedatum</th>
<th style="display: table-cell" class="clm_email">EMail</th>
<th style="display: table-cell" class="clm_absolviert">bereits absolvierte Verfahren</th>
<!--<th style="display: table-cell" class="clm_ergebnis">Ergebnis</th>
@@ -3128,6 +3154,7 @@ if($reihungstest_id!='')
<td style="display: table-cell" class="clm_studienplan">'.$db->convert_html_chars($studienplan_bezeichnung).' ('.$row->studienplan_id.')</td>
<td style="display: table-cell" class="clm_einstiegssemester">'.$db->convert_html_chars($row->ausbildungssemester).'</td>
<td style="display: table-cell" class="clm_geburtsdatum">'.$db->convert_html_chars($row->gebdatum!=''?$datum_obj->convertISODate($row->gebdatum):' ').'</td>
<td style="display: table-cell" class="clm_anmeldedatum">'.$db->convert_html_chars($row->anmeldedatum!=''?$datum_obj->convertISODate($row->anmeldedatum):' ').'</td>
<td style="display: table-cell; text-align: center" class="clm_email"><a href="mailto:'.$db->convert_html_chars($row->email).'"><img src="../../skin/images/button_mail.gif" name="mail"></a></td>
<td style="display: table-cell;" class="clm_absolviert">'.$rt_in_anderen_stg.'</td>';
/*echo '<td style="display: table-cell; align: right" class="clm_ergebnis">'.($rtergebnis==0?'-':number_format($rtergebnis,2,'.','')).' %</td>