add resources assignment to tempus kalender entries

This commit is contained in:
Ivymaster
2026-07-17 09:09:49 +02:00
parent 9abaf30ed3
commit e09fea72a4
18 changed files with 1907 additions and 837 deletions
@@ -32,7 +32,7 @@ class Config extends FHCAPI_Controller
{
$config = [];
$result = $this->_ci->VariableModel->getVariables(getAuthUID(), ['ignore_kollision', 'kollision_student', 'ignore_reservierung', 'ignore_zeitsperre']);
$result = $this->_ci->VariableModel->getVariables(getAuthUID(), ['ignore_kollision', 'kollision_student', 'ignore_reservierung', 'ignore_zeitsperre', 'ignore_resources_collisions']);
$data = $this->getDataOrTerminateWithError($result);
$config['ignore_kollision'] = [
@@ -61,7 +61,11 @@ class Config extends FHCAPI_Controller
"value" => ($data['ignore_zeitsperre'] ?? 'false') === 'true'
];
$config['ignore_resources_collisions'] = [
"type" => "checkbox",
"label" => $this->p->t('ui', 'ignore_resources_collisions'),
"value" => ($data['ignore_resources_collisions'] ?? 'false') === 'true'
];
$this->terminateWithSuccess($config);
}
@@ -108,6 +112,11 @@ class Config extends FHCAPI_Controller
'ignore_zeitsperre',
$this->input->post('ignore_zeitsperre') === true ? 'true' : 'false'
);
$this->_ci->VariableModel->setVariable(
getAuthUID(),
'ignore_resources_collisions',
$this->input->post('ignore_resources_collisions') === true ? 'true' : 'false'
);
$this->terminateWithSuccess();
}
@@ -224,7 +224,7 @@ class Kalender extends FHCAPI_Controller
if (isError($result))
$this->terminateWithError(getError($result), $result->code);
$this->terminateWithSuccess();
$this->terminateWithSuccess(getData($result));
}
public function getRaumvorschlag()
@@ -0,0 +1,84 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class OperationalResourceToCalenderAPI extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getAssignedResourcesByCalender' => ['admin:r', 'assistenz:r'],
'storeResourcesToCalendarRelationship' => ['admin:w', 'assistenz:w'],
'getSchedulableResourcesByCalendar' => ['admin:r', 'assistenz:r'],
]);
$this->load->model('ressource/BetriebsmittelKalender_model', 'BetriebsmittelKalenderModel');
$this->load->model('ressource/Betriebsmittel_model', 'BetriebsmittelModel');
$this->load->model('ressource/Kalender_model', 'KalenderModel');
$this->load->library('CollisionChecker');
$this->load->library('KalenderLib');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getSchedulableResourcesByCalendar($calenderID)
{
if (!isset($calenderID)) $this->terminateWithError("Missing required parameter 'kalender_id'");
$result = $this->KalenderModel->loadWhere(['kalender_id' => $calenderID]);
if (isError($result)) $this->terminateWithError("Calendar with id '$calenderID' does not have a valid group id");
$calender = $this->getDataOrTerminateWithError($result)[0];
if (!isset($calender)) $this->terminateWithError("Calendar with id '$calenderID' not found");
$result = $this->BetriebsmittelModel->getSchedulableEntriesByDatetimeInterval($calender->von, $calender->bis);
$this->terminateWithSuccess($this->getDataOrTerminateWithError($result));
}
public function getAssignedResourcesByCalender($calenderID)
{
if (!isset($calenderID)) $this->terminateWithError("Missing required parameter 'kalender_id'");
$result = $this->KalenderModel->loadWhere(['kalender_id' => $calenderID]);
if (empty($result)) $this->terminateWithError("Calendar with id '$calenderID' not found");
$calenderGroupID = $this->getDataOrTerminateWithError($result)[0]->eindeutige_gruppen_id;
if (!isset($calenderGroupID)) $this->terminateWithError("Calendar with id '$calenderID' does not have a valid group id");
$this->BetriebsmittelKalenderModel->addSelect(['tbl_betriebsmittel_kalender.*', 'tbl_betriebsmittel.beschreibung', 'tbl_betriebsmittel.verplanen']);
$this->BetriebsmittelKalenderModel->addJoin('wawi.tbl_betriebsmittel', 'betriebsmittel_id');
$result = $this->BetriebsmittelKalenderModel->loadWhere([
'eindeutige_kalender_gruppen_id' => $calenderGroupID,
'tbl_betriebsmittel.verplanen' => true,
]);
$this->terminateWithSuccess($this->getDataOrTerminateWithError($result));
}
public function storeResourcesToCalendarRelationship()
{
$calenderID = $this->input->post('kalender_id');
$assignedResources = $this->input->post('assignedResources');
if (!isset($calenderID)) $this->terminateWithError("Missing required parameter 'kalender_id'", 'general');
if (!isset($assignedResources)) $this->terminateWithError("Missing required parameter 'assignedResources'", 'general');
$result = $this->KalenderModel->loadWhere(['kalender_id' => $calenderID]);
if (empty($result)) $this->terminateWithError("Calendar with id '$calenderID' not found");
$calendar = $this->getDataOrTerminateWithError($result)[0];
$calenderGroupID = $calendar->eindeutige_gruppen_id;
if (!isset($calenderGroupID)) $this->terminateWithError("Calendar with id '$calenderID' does not have a valid group id");
$result = $this->kalenderlib->addOperationalResourcesToKalenderEvent($calendar, $assignedResources);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess(['message' => 'Resources assigned successfully']);
}
}
@@ -264,7 +264,108 @@ class MigrateKalender extends CLI_Controller
}
}
public function migrateStundenplanBetriebsmittelEntries() {
$this->setKalendarEntriesGroupIDs();
$this->setKalendarEntriesGroupIDsForChildren();
$dbModel = new DB_Model();
$deleteOldImportedTempusEntriesQuery = "DELETE from lehre.tbl_betriebsmittel_kalender WHERE quelle != 'tempus_neu' OR quelle IS NULL;";
$createHelperTypeQuery = "DO $$
BEGIN
IF NOT EXISTS (
SELECT 1
FROM pg_type
WHERE typname = 'betriebsmittel_info'
) THEN
CREATE TYPE betriebsmittel_info AS (
betriebsmittel_id bigint,
insertamum timestamp,
insertvon text
);
END IF;
END $$;";
$query = $deleteOldImportedTempusEntriesQuery .
$createHelperTypeQuery .
"WITH test AS (
SELECT
tk.eindeutige_gruppen_id AS eindeutige_gruppen_id,
array_agg(tk.kalender_id),
array_agg(
ROW(tsb.betriebsmittel_id, tsb.insertamum, tsb.insertvon)::betriebsmittel_info
) AS betriebsmittel_data
FROM sync.tbl_stundenplandev_kalender AS sk
JOIN lehre.tbl_kalender tk ON tk.kalender_id = sk.kalender_id
JOIN lehre.tbl_stundenplan_betriebsmittel tsb ON tsb.stundenplandev_id = sk.stundenplandev_id
GROUP BY tk.eindeutige_gruppen_id
)
INSERT INTO lehre.tbl_betriebsmittel_kalender (
eindeutige_kalender_gruppen_id,
betriebsmittel_id,
insertamum,
insertvon
)
SELECT
t.eindeutige_gruppen_id,
bm.betriebsmittel_id,
bm.insertamum,
bm.insertvon
FROM test t
CROSS JOIN LATERAL unnest(t.betriebsmittel_data) AS bm
ON CONFLICT (eindeutige_kalender_gruppen_id, betriebsmittel_id) DO NOTHING;
;";
$dbModel->db->query($query);
}
private function setKalendarEntriesGroupIDs() {
$dbModel = new DB_Model();
$query = "UPDATE lehre.tbl_kalender
SET eindeutige_gruppen_id = gen_random_uuid()
WHERE vorgaenger_kalender_id IS NULL
AND eindeutige_gruppen_id IS NULL;";
$dbModel->db->query($query);
}
private function setKalendarEntriesGroupIDsForChildren() {
$dbModel = new DB_Model();
$query = "WITH RECURSIVE tree AS
(
SELECT
kalender_id,
vorgaenger_kalender_id,
kalender_id AS root_id,
eindeutige_gruppen_id as root_eindeutige_gruppen_id
FROM lehre.tbl_kalender
WHERE vorgaenger_kalender_id IS NULL
UNION ALL
SELECT
i.kalender_id,
i.vorgaenger_kalender_id,
t.root_id,
t.root_eindeutige_gruppen_id
FROM lehre.tbl_kalender i
JOIN tree t
ON i.vorgaenger_kalender_id = t.kalender_id
where i.eindeutige_gruppen_id is NULL
)
UPDATE lehre.tbl_kalender k
SET eindeutige_gruppen_id = t.root_eindeutige_gruppen_id
FROM tree t
WHERE k.kalender_id = t.kalender_id
AND k.eindeutige_gruppen_id IS NULL;";
$dbModel->db->query($query);
}
private function _insertKalender($block, $typ)
{
$result = $this->KalenderModel->insert(
+10
View File
@@ -570,3 +570,13 @@ function buildDropdownEntryPrintArray($id, $name, $parameterurl, $uid=null, $ord
];
}
function generateUUID()
{
$data = openssl_random_pseudo_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40);
$data[8] = chr(ord($data[8]) & 0x3f | 0x80);
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
@@ -18,10 +18,12 @@ class CollisionChecker
$this->_ci->load->library('collision/checks/LectureCollisionCheck');
$this->_ci->load->library('collision/checks/VerbandCollisionCheck');
$this->_ci->load->library('collision/checks/StudentCollisionCheck');
$this->_ci->load->library('collision/checks/ResourcesCollisionCheck');
$this->register($this->_ci->roomcollisioncheck);
$this->register($this->_ci->lecturecollisioncheck);
$this->register($this->_ci->verbandcollisioncheck);
$this->register($this->_ci->studentcollisioncheck);
$this->register($this->_ci->resourcescollisioncheck);
Events::trigger('collision_register', $this);
}
+105 -2
View File
@@ -14,6 +14,7 @@ class KalenderLib
$this->_ci->load->model('ressource/Kalender_Event_model', 'KalenderEventModel');
$this->_ci->load->model('ressource/Kalender_Event_Teilnehmer_model', 'KalenderEventTeilnehmerModel');
$this->_ci->load->model('ressource/Kalender_Ort_model', 'KalenderOrtModel');
$this->_ci->load->model('ressource/BetriebsmittelKalender_model', 'BetriebsmittelKalenderModel');
$this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->_ci->load->model('education/LehreinheitMitarbeiter_model', 'LehreinheitMitarbeiterModel');
@@ -38,6 +39,7 @@ class KalenderLib
$end_date = date('Y-m-d', strtotime($end_date . ' +1 day'));
$this->_ci->KalenderModel->addSelect('tbl_kalender.kalender_id,
tbl_kalender.eindeutige_gruppen_id,
tbl_kalender.status_kurzbz,
tbl_kalender.typ,
tbl_kalender.von,
@@ -134,6 +136,8 @@ class KalenderLib
$this->_ci->KalenderModel->db->where('tbl_kalender.von >=', $start_date);
$this->_ci->KalenderModel->db->where('tbl_kalender.bis <', $end_date);
$this->_ci->KalenderModel->addOrder('tbl_kalender.eindeutige_gruppen_id', 'DESC');
}
private function _mapEvents($data, $collisionCheck = true)
@@ -155,6 +159,7 @@ class KalenderLib
$bis = new DateTime($row->bis);
$events[$id] = (object) [
'eindeutige_gruppen_id' => $row->eindeutige_gruppen_id,
'type' => $row->typ,
'beginn' => $von->format('H:i:s'),
'ende' => $bis->format('H:i:s'),
@@ -179,7 +184,8 @@ class KalenderLib
'titel' => isset($row->titel) ? $row->titel : '',
'beschreibung' => isset($row->beschreibung) ? $row->beschreibung : '',
'topic' => [],
'collisions' => false
'collisions' => false,
'has_assigned_resources' => isset($row->has_assigned_resources) ? $row->has_assigned_resources : false,
];
}
@@ -436,6 +442,14 @@ class KalenderLib
WHERE nachfolger.vorgaenger_kalender_id = tbl_kalender.kalender_id)', null, false);
$this->_ci->KalenderModel->db->where_not_in('status_kurzbz', array('deleted'));
$this->_ci->KalenderModel->addSelect([
"(
SELECT COUNT(*) FROM lehre.tbl_betriebsmittel_kalender
WHERE tbl_betriebsmittel_kalender.eindeutige_kalender_gruppen_id = tbl_kalender.eindeutige_gruppen_id
) AS has_assigned_resources"
]);
$data = $this->_ci->KalenderModel->load();
return $this->_mapEvents($data);
@@ -633,6 +647,7 @@ class KalenderLib
'bis' => $end_date,
'typ' => 'lehreinheit',
'status_kurzbz' => 'planning',
'eindeutige_gruppen_id' => $this->_ci->KalenderModel->generateUniqueGroupId(),
'insertvon' => getAuthUID(),
'insertamum' => date('Y-m-d H:i:s')
)
@@ -990,6 +1005,81 @@ class KalenderLib
return $kalenderresult;
}
public function addOperationalResourcesToKalenderEvent($calendar, $assignedResources)
{
$checkerData = new stdClass();
$checkerData->kalender_id = $calendar->kalender_id;
$checkerData->betriebsmittel_ids = [];
$checkerData->von = $calendar->von;
$checkerData->bis = $calendar->bis;
foreach ($assignedResources as $assignedResource) {
array_push($checkerData->betriebsmittel_ids, $assignedResource['betriebsmittel_id']);
}
$errors = [];
$result = $this->_ci->collisionchecker->run($checkerData);
if (!empty($result))
{
$errors = $result;
}
if (!empty($errors)) {
return error($errors);
}
$this->_ci->db->trans_start();
$allowedResourceIDs = array_filter(array_map(
function ($resource) {
return $resource['betriebsmittel_id'] ?? null;
},
$assignedResources
));
if (!empty($allowedResourceIDs)) {
$placeholders = implode(',', array_fill(0, count($allowedResourceIDs), '?'));
$query = "
DELETE FROM lehre.tbl_betriebsmittel_kalender
WHERE eindeutige_kalender_gruppen_id = ?
AND betriebsmittel_id NOT IN ($placeholders)
";
$params = array_merge(
[$calendar->eindeutige_gruppen_id],
$allowedResourceIDs
);
$this->_ci->db->query($query, $params);
} else {
$this->_ci->db->where('eindeutige_kalender_gruppen_id', $calendar->eindeutige_gruppen_id);
$this->_ci->db->delete('lehre.tbl_betriebsmittel_kalender');
}
foreach ($assignedResources as $assignedResource) {
$data = [
'eindeutige_kalender_gruppen_id' => $calendar->eindeutige_gruppen_id,
'betriebsmittel_id' => $assignedResource['betriebsmittel_id'],
'anmerkung' => $assignedResource['anmerkung'] ?? null,
'quelle' => 'tempus_neu',
'updateamum' => date('c'),
'updatevon' => getAuthUid(),
];
if (isset($assignedResource['betriebsmittel_kalender_id'])) {
$result = $this->_ci->BetriebsmittelKalenderModel->update($assignedResource['betriebsmittel_kalender_id'], $data);
} else {
$result = $this->_ci->BetriebsmittelKalenderModel->insert(array_merge($data, [
'insertvon' => getAuthUid(),
'updateamum' => date('c'),
]));
}
}
$this->_ci->db->trans_complete();
return success('Operational resources added to calendar event successfully.');
}
private function _addTeilnehmerToEvent($kalender_id, $uid, $rolle)
{
return $this->_ci->KalenderEventTeilnehmerModel->insert(
@@ -1090,6 +1180,18 @@ class KalenderLib
$kalender_entry = getData($entryResult);
$calendarResources = $this->_ci->BetriebsmittelKalenderModel->loadWhere(['eindeutige_kalender_gruppen_id' => $kalender_entry->eindeutige_gruppen_id]);
if (isError($calendarResources)) return $calendarResources;
$calendarResourcesItems = getData($calendarResources);
$calendarResourcesIDs = [];
if (is_array($calendarResourcesItems)) {
$calendarResourcesIDs = array_map(function($resource) {
return $resource->betriebsmittel_id;
}, getData($calendarResources));
}
$kalender_entry->betriebsmittel_ids = $calendarResourcesIDs;
$kalender_entry->ort_kurzbz = !is_null($ort_kurzbz) ? (array) $ort_kurzbz : $kalender_entry->ort_kurzbz;
$kalender_entry->von = $start_time ?? $kalender_entry->von;
$kalender_entry->bis = $end_time ?? $kalender_entry->bis;
@@ -1115,7 +1217,7 @@ class KalenderLib
if (isError($result)) return $result;
}
return success('Erfolgreich');
return success($result);
}
public function updateZeit($kalender_id, $start_date, $end_date)
@@ -1237,6 +1339,7 @@ class KalenderLib
'typ' => 'lehreinheit',
'status_kurzbz' => 'planning',
'vorgaenger_kalender_id' => $old_id,
'eindeutige_gruppen_id' => $kalender_entry->eindeutige_gruppen_id,
'insertvon' => getAuthUID(),
'insertamum' => date('Y-m-d H:i:s')
)
@@ -0,0 +1,85 @@
<?php
class ResourcesCollisionCheck implements ICollisionCheck
{
private $_ci;
public function __construct()
{
$this->_ci =& get_instance();
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
$this->_ci->load->library('PhrasesLib', array('ui'));
}
public function getName()
{
return 'resources';
}
public function check($data)
{
if (!isset($data->betriebsmittel_ids, $data->von, $data->bis, $data->kalender_id)) return [];
if (empty($data->betriebsmittel_ids)) return [];
if ($this->_ci->variablelib->getVar('ignore_kollision') === 'true') return [];
if ($this->_ci->variablelib->getVar('ignore_resources_collisions') === 'true') return [];
$this->_ci->KalenderModel->addSelect('kalender_id, von, bis, bm.beschreibung AS betriebsmittel_beschreibung');
$this->_ci->KalenderModel->addJoin('lehre.tbl_betriebsmittel_kalender bk', 'bk.eindeutige_kalender_gruppen_id = tbl_kalender.eindeutige_gruppen_id');
$this->_ci->KalenderModel->addJoin('wawi.tbl_betriebsmittel bm', 'bm.betriebsmittel_id = bk.betriebsmittel_id');
$this->_ci->KalenderModel->db->where('tbl_kalender.kalender_id !=', $data->kalender_id);
$this->_ci->KalenderModel->db->where('tbl_kalender.kalender_id NOT IN (SELECT vorgaenger_kalender_id FROM lehre.tbl_kalender WHERE vorgaenger_kalender_id IS NOT NULL)', null, false);
$this->_ci->KalenderModel->db->where_not_in('tbl_kalender.status_kurzbz', ['archived', 'deleted', 'to_delete']);
$this->_ci->KalenderModel->db->where_in('bk.betriebsmittel_id', $data->betriebsmittel_ids);
$result = $this->_ci->KalenderModel->loadWhere(array(
'von <' => $data->bis,
'bis >' => $data->von,
));
if (isError($result)) return [];
if (!hasData($result)) return [];
return array_map(function($row)
{
return [
'errorCode' => 'resource_collision',
'message' => $this->_ci->phraseslib->t('ui', 'resource_collision') . ': ' . $row->betriebsmittel_beschreibung . ' (' . date('d.m.Y H:i', strtotime($row->von)) . ' - ' . date('d.m.Y H:i', strtotime($row->bis)) . ')'
];
}, getData($result));
}
public function checkAll($kalender_ids)
{
if (empty($kalender_ids)) return [];
$this->_ci->KalenderModel->addSelect('DISTINCT ON (tbl_kalender.kalender_id) tbl_kalender.kalender_id');
$this->_ci->KalenderModel->addJoin('lehre.tbl_betriebsmittel_kalender current_bk', 'current_bk.eindeutige_kalender_gruppen_id = tbl_kalender.eindeutige_gruppen_id');
$this->_ci->KalenderModel->addJoin('lehre.tbl_betriebsmittel_kalender other_bk', 'other_bk.betriebsmittel_id = current_bk.betriebsmittel_id');
$this->_ci->KalenderModel->addJoin('lehre.tbl_kalender other_kalender', 'other_kalender.eindeutige_gruppen_id = other_bk.eindeutige_kalender_gruppen_id');
$this->_ci->KalenderModel->db->where('other_kalender.kalender_id != tbl_kalender.kalender_id', null, false);
$this->_ci->KalenderModel->db->where('other_kalender.von < tbl_kalender.bis', null, false);
$this->_ci->KalenderModel->db->where('other_kalender.bis > tbl_kalender.von', null, false);
$this->_ci->KalenderModel->db->where_not_in('other_kalender.status_kurzbz', ['archived', 'deleted', 'to_delete']);
$this->_ci->KalenderModel->db->where_in('tbl_kalender.kalender_id', $kalender_ids);
$this->_ci->KalenderModel->db->where('other_kalender.kalender_id NOT IN (SELECT vorgaenger_kalender_id FROM lehre.tbl_kalender WHERE vorgaenger_kalender_id IS NOT NULL)', null, false);
$result = $this->_ci->KalenderModel->load();
if (isError($result) || !hasData($result)) return [];
$grouped = [];
foreach (getData($result) as $row)
{
$grouped[$row->kalender_id][] = true;
}
return $grouped;
}
}
@@ -0,0 +1,14 @@
<?php
class BetriebsmittelKalender_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'lehre.tbl_betriebsmittel_kalender';
$this->pk = 'betriebsmittel_kalender_id';
}
}
@@ -31,4 +31,26 @@ class Betriebsmittel_model extends DB_Model
return $this->execQuery($qry);
}
public function getSchedulableEntriesByDatetimeInterval($from, $to)
{
$qry = "SELECT
*
FROM
wawi.tbl_betriebsmittel
WHERE
verplanen=true
AND
NOT EXISTS(
SELECT 1 FROM lehre.tbl_betriebsmittel_kalender
JOIN lehre.tbl_kalender ON tbl_kalender.eindeutige_gruppen_id = tbl_betriebsmittel_kalender.eindeutige_kalender_gruppen_id
WHERE
betriebsmittel_id=tbl_betriebsmittel.betriebsmittel_id
AND tbl_kalender.von <= ?
AND tbl_kalender.bis >= ?
)";
return $this->execQuery($qry, array($from, $to));
}
}
@@ -11,4 +11,15 @@ class Kalender_model extends DB_Model
$this->dbTable = 'lehre.tbl_kalender';
$this->pk = 'kalender_id';
}
public function generateUniqueGroupId()
{
while (true) {
$uniqueGroupId = generateUUID();
$result = $this->loadWhere(['eindeutige_gruppen_id' => $uniqueGroupId]);
if (!hasData($result)) {
return $uniqueGroupId;
}
}
}
}
@@ -0,0 +1,38 @@
/**
* 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 {
getSchedulableResourcesByCalendar(calendarID) {
return {
method: "get",
url: "/api/frontend/v1/tempus/OperationalResourceToCalenderAPI/getSchedulableResourcesByCalendar/" + calendarID,
};
},
getAssignedResourcesByCalender(calenderID) {
return {
method: "get",
url: "/api/frontend/v1/tempus/OperationalResourceToCalenderAPI/getAssignedResourcesByCalender/" + calenderID,
};
},
storeResourcesToCalendarRelationship(calenderID, assignedResources) {
return {
method: "post",
url: "/api/frontend/v1/tempus/OperationalResourceToCalenderAPI/storeResourcesToCalendarRelationship",
params: { kalender_id: calenderID, assignedResources: assignedResources },
};
}
};
@@ -82,8 +82,14 @@ export default {
template: /*html*/`
<div
:class="classes"
class="position-relative"
@wheel.stop
>
<div v-if="event.has_assigned_resources" class="position-absolute top-0 start-0 m-1" >
<i
class="fa-solid fa-table-list text-muted"
></i>
</div>
<div
v-if="!event.allDayEvent && event?.beginn && event?.ende"
class="event-time d-none d-xl-grid h-100"
@@ -93,7 +99,10 @@ export default {
</div>
<div class="event-text" v-tooltip="tooltipString">
<span class="event-topic">{{ topicString }}</span>
<span class="event-place">{{ ortString }}</span>
<span
class="event-place"
data-cy="calendar-event-room"
>{{ ortString }}</span>
<span v-if="gruppeString" class="event-gruppe">{{ gruppeString }}</span>
<span
v-for="(lektor,index) in event.lektor.slice(0, 3)"
File diff suppressed because it is too large Load Diff
@@ -7,6 +7,11 @@ export function useContextMenuActions(handlers)
icon: 'fa-solid fa-door-open',
action: handlers.openRaumauswahl
},
{
label: 'Ressourcen zuordnen',
icon: 'fa-solid fa-table-list',
action: handlers.openResourcesAssignmentModal
},
{
label: 'Freischalten für Voransicht',
icon: 'fa-solid fa-chalkboard-user',
+1 -1
View File
@@ -99,7 +99,7 @@ require_once('dbupdate_3.4/75888_reihungstest_mehrfachdurchfuehrung.php');
require_once('dbupdate_3.4/76150_perm_other_lv_plan.php');
require_once('dbupdate_3.4/68957_dashboard_bookmark_neue_Spalte_sort.php');
require_once('dbupdate_3.4/68530_Dashboard_Cleanup.php');
require_once('dbupdate_3.4/77375_ressourcen.php');
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
+92
View File
@@ -0,0 +1,92 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
$result = $db->db_query("SELECT 1 FROM information_schema.columns WHERE table_schema = 'lehre' AND table_name = 'tbl_kalender' AND column_name = 'eindeutige_gruppen_id'");
if($db->db_num_rows($result) === 0)
{
$qry = "ALTER TABLE lehre.tbl_kalender
ADD COLUMN IF NOT EXISTS eindeutige_gruppen_id UUID";
if(!$db->db_query($qry))
echo '<strong>lehre.tbl_kalender: '.$db->db_last_error().'</strong><br>';
else
echo '<br>lehre.tbl_kalender column eindeutige_gruppen_id hinzugefuegt';
}
$result = $db->db_query("SELECT 1 FROM public.tbl_variablenname WHERE name = 'ignore_resources_collisions'");
if($db->db_num_rows($result) === 0)
{
$qry = "INSERT INTO public.tbl_variablenname
(name, defaultwert)
VALUES('ignore_resources_collisions', 'false')";
if(!$db->db_query($qry))
echo '<strong>public.tbl_variablenname: '.$db->db_last_error().'</strong><br>';
else
echo '<br>public.tbl_variablenname column ignore_resources_collisions hinzugefuegt';
}
if(!$result = @$db->db_query("SELECT 1 FROM lehre.tbl_betriebsmittel_kalender LIMIT 1"))
{
$qry = '
CREATE TABLE lehre.tbl_betriebsmittel_kalender (
"betriebsmittel_kalender_id" INTEGER NOT NULL,
"eindeutige_kalender_gruppen_id" UUID NOT NULL,
"betriebsmittel_id" INTEGER NOT NULL,
"anmerkung" TEXT,
"quelle" VARCHAR(32),
"insertamum" TIMESTAMP WITH TIME ZONE DEFAULT now(),
"insertvon" VARCHAR(32),
"updateamum" TIMESTAMP WITH TIME ZONE DEFAULT now(),
"updatevon" VARCHAR(32),
CONSTRAINT pk_betriebsmittel_kalender_id PRIMARY KEY("betriebsmittel_kalender_id"),
CONSTRAINT fk_betriebsmittel_id FOREIGN KEY("betriebsmittel_id") REFERENCES wawi.tbl_betriebsmittel("betriebsmittel_id") ON DELETE CASCADE,
CONSTRAINT eindeutige_kalender_gruppen_id_betriebsmittel_id UNIQUE (eindeutige_kalender_gruppen_id, betriebsmittel_id)
);';
if(!$db->db_query($qry))
echo '<strong>lehre.tbl_betriebsmittel_kalender: '.$db->db_last_error().'</strong><br>';
else
echo '<br>lehre.tbl_betriebsmittel_kalender table created';
$db->db_query('CREATE SEQUENCE IF NOT EXISTS lehre.seq_tbl_betriebsmittel_kalender_betriebsmittel_kalender_id
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;');
$db->db_query("ALTER TABLE lehre.tbl_betriebsmittel_kalender ALTER COLUMN betriebsmittel_kalender_id SET DEFAULT nextval('lehre.seq_tbl_betriebsmittel_kalender_betriebsmittel_kalender_id');");
$qry = 'GRANT SELECT ON TABLE lehre.tbl_betriebsmittel_kalender TO web;';
if(!$db->db_query($qry))
echo '<strong>lehre.tbl_betriebsmittel_kalender: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Granted privileges to <strong>web</strong> on lehre.tbl_betriebsmittel_kalender';
$qry = 'GRANT USAGE ON lehre.seq_tbl_betriebsmittel_kalender_betriebsmittel_kalender_id TO web;';
if(!$db->db_query($qry))
echo '<strong>lehre.tbl_betriebsmittel_kalender: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Granted privileges to <strong>web</strong> on lehre.tbl_betriebsmittel_kalender';
$qry = 'GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE lehre.tbl_betriebsmittel_kalender TO vilesci;';
if(!$db->db_query($qry))
echo '<strong>lehre.tbl_betriebsmittel_kalender: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Granted privileges to <strong>vilesci</strong> on lehre.tbl_betriebsmittel_kalender';
$qry = 'GRANT USAGE, INSERT ON lehre.seq_tbl_betriebsmittel_kalender_betriebsmittel_kalender_id TO vilesci;';
if(!$db->db_query($qry))
echo '<strong>lehre.tbl_betriebsmittel_kalender: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Granted privileges to <strong>vilesci</strong> on lehre.tbl_betriebsmittel_kalender';
$qry = 'GRANT USAGE, UPDATE ON lehre.seq_tbl_betriebsmittel_kalender_betriebsmittel_kalender_id TO vilesci;';
if(!$db->db_query($qry))
echo '<strong>lehre.tbl_betriebsmittel_kalender: '.$db->db_last_error().'</strong><br>';
else
echo '<br>Granted privileges to <strong>vilesci</strong> on lehre.tbl_betriebsmittel_kalender';
}
+200
View File
@@ -49123,6 +49123,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'resource_collision',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ressourcen Kollision',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Resource Collision',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
@@ -49183,6 +49203,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'ignore_resources_collisions',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ressourcenkollisionen ignorieren',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Ignore resource collision',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
@@ -60859,6 +60899,166 @@ I have been informed that I am under no obligation to consent to the transmissio
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'failed_assigned_resources_fetch_error_message',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Fehler beim Abrufen der zugewiesenen Ressourcen. Bitte versuchen Sie es erneut.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Error fetching assigned resources. Please try again.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'failed_schedulable_resources_fetch_error_message',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Fehler beim Abrufen der zuweisbaren Ressourcen. Bitte versuchen Sie es erneut.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Error fetching schedulable resources. Please try again.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'failed_assigned_resources_save_error_message',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Fehler beim Speichern der zugewiesenen Ressourcen. Bitte versuchen Sie es erneut.',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Error saving assigned resources. Please try again.',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'resource_assignment_modal_title',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Ressourcen-Zuweisung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Resource Assignment',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'assigned_resources_subtitle',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Zugewiesene Ressourcen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Assigned Resources',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'no_assigned_resources',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Keine zugewiesenen Ressourcen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'No Assigned Resources',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'available_resources_label',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Verfügbare Ressourcen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Available Resources',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'ui',
'phrase' => 'assigned_resources_save_success_message',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Zugewiesene Ressourcen erfolgreich gespeichert',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Assigned Resources successfully saved',
'description' => '',
'insertvon' => 'system'
)
)
),
// generic tabulator phrases END
);