mirror of
https://github.com/FH-Complete/FHC-Core.git
synced 2026-10-12 15:04:04 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ecd4b5a65 | ||
|
|
6ea1d4610d | ||
|
|
f0b1689a06 | ||
|
|
6e6cb8ae11 | ||
|
|
1bbe4368bb |
@@ -137,9 +137,6 @@ $route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)/stg/(
|
||||
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)/stg/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2/$3';
|
||||
|
||||
|
||||
|
||||
$route['api/frontend/v1/lvplan/calendar-events'] = 'api/frontend/v1/LvPlanCalendarEvents/getCalendarData';
|
||||
|
||||
// load routes from extensions, also look for environment-specific configs
|
||||
$subdirs = ['application/config/extensions', 'application/config/' . ENVIRONMENT . '/extensions'];
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
<?php
|
||||
|
||||
if (! defined('BASEPATH')) exit('No direct script access allowed');
|
||||
|
||||
/**
|
||||
* Provides the authenticated user's LVPlan events as JSON.
|
||||
*/
|
||||
class LvPlanCalendarEvents extends FHCAPI_Controller
|
||||
{
|
||||
/**
|
||||
* Object initialization.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct([
|
||||
'getCalendarData' => self::PERM_LOGGED
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the authenticated user's mapped calendar events.
|
||||
*/
|
||||
public function getCalendarData()
|
||||
{
|
||||
$this->output->set_header('Cache-Control: no-store');
|
||||
|
||||
if ($this->input->method() !== 'get')
|
||||
{
|
||||
$this->output->set_header('Allow: GET');
|
||||
$this->terminateWithError(
|
||||
'Method not allowed',
|
||||
self::ERROR_TYPE_GENERAL,
|
||||
REST_Controller::HTTP_METHOD_NOT_ALLOWED
|
||||
);
|
||||
}
|
||||
|
||||
$startDate = $this->input->get('start_date', true);
|
||||
$endDate = $this->input->get('end_date', true);
|
||||
$validationErrors = array();
|
||||
|
||||
if (!is_null($startDate) && !$this->isValidDate($startDate))
|
||||
$validationErrors['start_date'] = 'The start_date field must use the YYYY-MM-DD format.';
|
||||
|
||||
if (!is_null($endDate) && !$this->isValidDate($endDate))
|
||||
$validationErrors['end_date'] = 'The end_date field must use the YYYY-MM-DD format.';
|
||||
|
||||
if (!empty($validationErrors))
|
||||
$this->terminateWithValidationErrors($validationErrors);
|
||||
|
||||
$today = new DateTimeImmutable('today', new DateTimeZone('Europe/Vienna'));
|
||||
|
||||
if (is_null($startDate))
|
||||
$startDate = $today->modify('-14 days')->format('Y-m-d');
|
||||
|
||||
if (is_null($endDate))
|
||||
$endDate = $today->modify('+6 months')->format('Y-m-d');
|
||||
|
||||
if ($startDate > $endDate)
|
||||
{
|
||||
$this->terminateWithValidationErrors(array(
|
||||
'end_date' => 'The end_date field must be on or after start_date.'
|
||||
));
|
||||
}
|
||||
|
||||
$userUID = getAuthUID();
|
||||
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
|
||||
$this->load->library('KalenderLib', ['uid' => $userUID]);
|
||||
|
||||
$isUserEmployeeResult = $this->MitarbeiterModel->isMitarbeiter($userUID);
|
||||
$isUserEmployee = $this->getDataOrTerminateWithError($isUserEmployeeResult);
|
||||
|
||||
if ($isUserEmployee)
|
||||
{
|
||||
$events = $this->kalenderlib->getPlanForLecturerByLecturer(
|
||||
$startDate,
|
||||
$endDate,
|
||||
$userUID
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$events = $this->kalenderlib->getPlanForStudentByStudent(
|
||||
$startDate,
|
||||
$endDate,
|
||||
$userUID
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_array($events))
|
||||
$events = array();
|
||||
|
||||
$this->terminateWithSuccess($events);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a date uses the exact YYYY-MM-DD format.
|
||||
*
|
||||
* @param mixed $date
|
||||
* @return bool
|
||||
*/
|
||||
private function isValidDate($date)
|
||||
{
|
||||
if (!is_string($date) || $date === '')
|
||||
return false;
|
||||
|
||||
$parsedDate = DateTimeImmutable::createFromFormat('!Y-m-d', $date);
|
||||
$errors = DateTimeImmutable::getLastErrors();
|
||||
|
||||
return $parsedDate !== false
|
||||
&& ($errors === false
|
||||
|| ($errors['warning_count'] === 0 && $errors['error_count'] === 0))
|
||||
&& $parsedDate->format('Y-m-d') === $date;
|
||||
}
|
||||
}
|
||||
@@ -44,9 +44,9 @@ class Kalender extends FHCAPI_Controller
|
||||
|
||||
$this->_ci->load->library('LogLib');
|
||||
$this->_ci->load->library('form_validation');
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('KalenderLib');
|
||||
$this->_ci->load->library('KalenderSyncLib');
|
||||
$this->_ci->load->library('RaumvorschlagLib', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('RaumvorschlagLib');
|
||||
$this->loadPhrases([
|
||||
'ui'
|
||||
]);
|
||||
|
||||
@@ -18,8 +18,8 @@ class OperationalResourceToCalenderAPI extends FHCAPI_Controller
|
||||
$this->load->model('ressource/Betriebsmittel_model', 'BetriebsmittelModel');
|
||||
$this->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
|
||||
$this->_ci->load->library('CollisionChecker', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => getAuthUID()]);
|
||||
$this->load->library('CollisionChecker');
|
||||
$this->load->library('KalenderLib');
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -22,7 +22,7 @@ class Reservierung extends FHCAPI_Controller
|
||||
|
||||
$this->_ci->load->library('LogLib');
|
||||
$this->_ci->load->library('form_validation');
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('KalenderLib');
|
||||
|
||||
$this->_ci->load->model('ressource/Ort_model', 'OrtModel');
|
||||
$this->_ci->load->model('ressource/Kalender_Event_Rolle_model', 'KalenderEventRolleModel');
|
||||
|
||||
@@ -20,7 +20,6 @@ class Tags extends Tag_Controller
|
||||
]);
|
||||
|
||||
$this->config->load('tempus');
|
||||
$this->load->model('ressource/KalenderNotiz_model', 'KalenderNotizModel');
|
||||
}
|
||||
|
||||
public function getTag($readonly_tags = null)
|
||||
@@ -31,53 +30,14 @@ class Tags extends Tag_Controller
|
||||
{
|
||||
parent::getTags($this->config->item('tempus_tags'));
|
||||
}
|
||||
|
||||
public function getTagsByCalendar($eindeutige_kalender_gruppen_id)
|
||||
public function getTagsByCalendar($eindeutige_kalender_gruppen_id = null)
|
||||
{
|
||||
$language = $this->_getLanguageIndex();
|
||||
$index_bezeichnung_mehrsprachig = $language - 1;
|
||||
|
||||
$this->KalenderNotizModel->addSelect(
|
||||
'tbl_kalender_notiz.notiz_id as notiz_id,
|
||||
typ_kurzbz as tag_typ_kurzbz,
|
||||
array_to_json(bezeichnung_mehrsprachig::varchar[])->>'. $index_bezeichnung_mehrsprachig. ' as bezeichnung,
|
||||
style,
|
||||
beschreibung,
|
||||
tag,
|
||||
tbl_notiz.erledigt as done
|
||||
'
|
||||
);
|
||||
|
||||
$this->KalenderNotizModel->addJoin('public.tbl_notiz', 'tbl_kalender_notiz.notiz_id = public.tbl_notiz.notiz_id');
|
||||
$this->KalenderNotizModel->addJoin('public.tbl_notiz_typ', 'public.tbl_notiz.typ = public.tbl_notiz_typ.typ_kurzbz');
|
||||
|
||||
$this->KalenderNotizModel->addOrder('prioritaet');
|
||||
|
||||
$notiztypen = $this->KalenderNotizModel->loadWhere(array('aktiv' => true, 'eindeutige_kalender_gruppen_id' => $eindeutige_kalender_gruppen_id));
|
||||
$this->terminateWithSuccess(hasData($notiztypen) ? getData($notiztypen) : array());
|
||||
parent::getTagsByAssignmentTypeValue('eindeutige_kalender_gruppen_id', $eindeutige_kalender_gruppen_id, $this->config->item('tempus_tags'));
|
||||
}
|
||||
|
||||
public function addTag($withZuordnung = true, $updatable_tags = null)
|
||||
{
|
||||
$postData = $this->getPostJson();
|
||||
|
||||
$return = array();
|
||||
foreach ($postData->values as $value)
|
||||
{
|
||||
$insertResult = parent::addTag(false, $this->config->item('tempus_tags'));
|
||||
|
||||
$insertZuordnung = $this->KalenderNotizModel->insert(array(
|
||||
'eindeutige_kalender_gruppen_id' => $value,
|
||||
'notiz_id' => $insertResult,
|
||||
));
|
||||
|
||||
if (isError($insertZuordnung))
|
||||
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
|
||||
$return[] = ['eindeutige_kalender_gruppen_id' => $value, 'id' => $insertResult];
|
||||
}
|
||||
$this->terminateWithSuccess($return);
|
||||
parent::addTag(true, $this->config->item('tempus_tags'));
|
||||
}
|
||||
|
||||
public function updateTag($updatable_tags = null)
|
||||
{
|
||||
parent::updateTag($this->config->item('tempus_tags'));
|
||||
@@ -90,13 +50,4 @@ class Tags extends Tag_Controller
|
||||
{
|
||||
parent::doneTag($this->config->item('tempus_tags'));
|
||||
}
|
||||
|
||||
public function _getLanguageIndex()
|
||||
{
|
||||
$this->load->model('system/Sprache_model', 'SpracheModel');
|
||||
$this->SpracheModel->addSelect('index');
|
||||
$result = $this->SpracheModel->loadWhere(array('sprache' => getUserLanguage()));
|
||||
|
||||
return hasData($result) ? getData($result)[0]->index : 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class TempusJob extends JOB_Controller
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
$this->_ci->load->helper('hlp_sancho_helper');
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => null]);
|
||||
$this->_ci->load->library('KalenderLib');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -32,42 +32,6 @@ class MigrateKalender extends CLI_Controller
|
||||
/**
|
||||
* Everything has a beginning
|
||||
*/
|
||||
public function refreshTablesAndFullMigrateOfStundenplanReservierung($von, $bis = null, $studiengang_kz = null, $ort_kurzbz = null)
|
||||
{
|
||||
if (defined('CI_ENVIRONMENT') && CI_ENVIRONMENT === 'production')
|
||||
{
|
||||
echo "This script is not allowed to run in production environment.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
echo "Refreshing calendar related tables...\n";
|
||||
$this->resetBeforeNewStundenplanReservierungImport();
|
||||
echo "Calendar related tables refreshed successfully.\n\n";
|
||||
|
||||
echo "Starting full migration of Stundenplan and Reservierung from $von to " . ($bis ?? '2100-12-31') . "...\n";
|
||||
$this->fullMigrateOfStundenplanReservierung($von, $bis, $studiengang_kz, $ort_kurzbz);
|
||||
echo "Full migration of Stundenplan and Reservierung completed successfully.\n";
|
||||
}
|
||||
|
||||
public function fullMigrateOfStundenplanReservierung($von, $bis = null, $studiengang_kz = null, $ort_kurzbz = null)
|
||||
{
|
||||
echo "Starting migration of Stundenplan from $von to " . ($bis ?? '2100-12-31') . "...\n";
|
||||
$this->migrateStundenplan($von, $bis, $studiengang_kz);
|
||||
echo "Stundenplan migration completed successfully.\n\n";
|
||||
|
||||
echo "Starting migration of Reservierung from $von to " . ($bis ?? '2100-12-31') . "...\n";
|
||||
$this->migrateReservierung($von, $bis, $ort_kurzbz);
|
||||
echo "Reservierung migration completed successfully.\n\n";
|
||||
|
||||
echo "Starting migration of Stundenplan Betriebsmittel entries...\n";
|
||||
$this->migrateStundenplanBetriebsmittelEntries();
|
||||
echo "Stundenplan Betriebsmittel entries migration completed successfully.\n\n";
|
||||
|
||||
echo "Starting to add title values as tags to calendar entries...\n";
|
||||
$this->addTitleValuesAsTagsToKalenderEntries();
|
||||
echo "Adding title values as tags to calendar entries completed successfully.\n\n";
|
||||
}
|
||||
|
||||
public function migrateStundenplan($von, $bis = null, $studiengang_kz = null)
|
||||
{
|
||||
if (is_null($von))
|
||||
@@ -369,121 +333,6 @@ class MigrateKalender extends CLI_Controller
|
||||
$dbModel->db->query($query);
|
||||
}
|
||||
|
||||
public function addTitleValuesAsTagsToKalenderEntries() {
|
||||
$dbModel = new DB_Model();
|
||||
|
||||
|
||||
$query = "SELECT
|
||||
k.eindeutige_kalender_gruppen_id,
|
||||
ARRAY_AGG(DISTINCT(spd.titel) ORDER BY spd.titel) AS titel,
|
||||
MAX(spd.updateamum) AS updateamum
|
||||
FROM lehre.tbl_stundenplandev spd
|
||||
JOIN sync.tbl_stundenplandev_kalender spdk ON spd.stundenplandev_id = spdk.stundenplandev_id
|
||||
JOIN lehre.tbl_kalender k ON k.kalender_id = spdk.kalender_id
|
||||
WHERE k.typ = 'lehreinheit' AND k.eindeutige_kalender_gruppen_id IS NOT NULL AND spd.titel IS NOT NULL
|
||||
GROUP BY k.eindeutige_kalender_gruppen_id";
|
||||
|
||||
$result = $dbModel->execReadOnlyQuery($query);
|
||||
|
||||
if (isError($result)) {
|
||||
error("Error while fetching title values for adding as tags: " . getError($result));
|
||||
return;
|
||||
}
|
||||
if (!hasData($result)) {
|
||||
error("No title values found for adding as tags.");
|
||||
return;
|
||||
}
|
||||
|
||||
$data = getData($result);
|
||||
|
||||
foreach($data as $block) {
|
||||
$eindeutige_kalender_gruppen_id = $block->eindeutige_kalender_gruppen_id;
|
||||
$notizText = implode(' - ', array_filter($block->titel, function($titel) {
|
||||
return !empty(trim($titel));
|
||||
}));
|
||||
|
||||
if (!empty($notizText)) {
|
||||
$this->addTag($eindeutige_kalender_gruppen_id, $notizText, $block->updateamum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function resetBeforeNewStundenplanReservierungImport()
|
||||
{
|
||||
if (defined('CI_ENVIRONMENT') && CI_ENVIRONMENT === 'production')
|
||||
{
|
||||
echo "This script is not allowed to run in production environment.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
$db = new DB_Model();
|
||||
|
||||
$db->db->trans_start();
|
||||
|
||||
$db->db->query('DELETE FROM sync.tbl_stundenplandev_kalender');
|
||||
$db->db->query('DELETE FROM sync.tbl_reservierung_kalender');
|
||||
|
||||
$db->db->query("DELETE FROM lehre.tbl_kalender_event_teilnehmer
|
||||
WHERE kalender_id IN (
|
||||
SELECT kalender_id
|
||||
FROM lehre.tbl_kalender
|
||||
WHERE typ = 'reservierung'
|
||||
)");
|
||||
|
||||
$db->db->query("DELETE FROM lehre.tbl_kalender_event
|
||||
WHERE kalender_id IN (
|
||||
SELECT kalender_id
|
||||
FROM lehre.tbl_kalender
|
||||
WHERE typ = 'reservierung'
|
||||
)");
|
||||
|
||||
$db->db->query("DELETE FROM lehre.tbl_kalender_lehreinheit
|
||||
WHERE kalender_id IN (
|
||||
SELECT kalender_id
|
||||
FROM lehre.tbl_kalender
|
||||
WHERE typ = 'lehreinheit' OR typ = 'reservierung'
|
||||
)");
|
||||
|
||||
$db->db->query("DELETE FROM lehre.tbl_kalender_ort
|
||||
WHERE kalender_id IN (
|
||||
SELECT kalender_id
|
||||
FROM lehre.tbl_kalender
|
||||
WHERE typ IN ('lehreinheit', 'reservierung')
|
||||
)");
|
||||
|
||||
$db->db->query("DELETE FROM public.tbl_notiz
|
||||
WHERE notiz_id IN (
|
||||
SELECT notiz_id
|
||||
FROM lehre.tbl_kalender_notiz
|
||||
WHERE eindeutige_kalender_gruppen_id IN (
|
||||
SELECT eindeutige_kalender_gruppen_id
|
||||
FROM lehre.tbl_kalender
|
||||
)
|
||||
)");
|
||||
|
||||
$db->db->query("DELETE FROM lehre.tbl_kalender_notiz
|
||||
WHERE eindeutige_kalender_gruppen_id IN (
|
||||
SELECT eindeutige_kalender_gruppen_id
|
||||
FROM lehre.tbl_kalender
|
||||
)");
|
||||
|
||||
$db->db->query("DELETE FROM lehre.tbl_betriebsmittel_kalender
|
||||
WHERE eindeutige_kalender_gruppen_id IN (
|
||||
SELECT eindeutige_kalender_gruppen_id
|
||||
FROM lehre.tbl_kalender
|
||||
)");
|
||||
|
||||
$db->db->query("DELETE FROM lehre.tbl_kalender
|
||||
WHERE typ IN ('lehreinheit', 'reservierung')");
|
||||
|
||||
$db->db->trans_complete();
|
||||
|
||||
if ($db->db->trans_status() === false)
|
||||
return error('Reset before new import failed');
|
||||
|
||||
return success('Migration data reset successfully');
|
||||
}
|
||||
|
||||
private function setKalendarEntriesGroupIDs() {
|
||||
$dbModel = new DB_Model();
|
||||
|
||||
@@ -758,129 +607,4 @@ class MigrateKalender extends CLI_Controller
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private function addTag($eindeutige_kalender_gruppen_id, $notizText, $lastUpdatedInOldSystem): bool
|
||||
{
|
||||
$notizType = 'hinweis';
|
||||
$insertvonMockUser = 'oldToNewTempusMigration';
|
||||
|
||||
if (is_null($eindeutige_kalender_gruppen_id) || empty($eindeutige_kalender_gruppen_id)) {
|
||||
var_dump("Error: eindeutige_kalender_gruppen_id is null or empty.");
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->load->model('person/Notiz_model', 'NotizModel');
|
||||
$this->load->model('system/Notiztyp_model', 'NotiztypModel');
|
||||
$this->load->model('ressource/KalenderNotiz_model', 'KalenderNotizModel');
|
||||
|
||||
$checkTyp = $this->NotiztypModel->loadWhere(array('typ_kurzbz' => $notizType));
|
||||
|
||||
if (isError($checkTyp))
|
||||
{
|
||||
error("Error occurred while checking Notiztyp: " . $checkTyp->message);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hasData($checkTyp))
|
||||
{
|
||||
error("Notiztyp 'hinweis' does not exist. Please create it before adding tags.");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$this->KalenderNotizModel->addJoin('tbl_notiz', 'tbl_notiz.notiz_id = tbl_kalender_notiz.notiz_id', 'LEFT');
|
||||
$this->KalenderNotizModel->db->where('tbl_notiz.typ', $notizType);
|
||||
$this->KalenderNotizModel->db->where('tbl_notiz.insertvon', $insertvonMockUser);
|
||||
$oldKalenderNotiz = $this->KalenderNotizModel->loadWhere(array('eindeutige_kalender_gruppen_id' => $eindeutige_kalender_gruppen_id));
|
||||
if (isError($oldKalenderNotiz))
|
||||
{
|
||||
error("Error occurred while checking KalenderNotiz: " . $oldKalenderNotiz->message);
|
||||
return false;
|
||||
}
|
||||
if (hasData($oldKalenderNotiz))
|
||||
{
|
||||
return $this->updateTag($eindeutige_kalender_gruppen_id, $notizText, $lastUpdatedInOldSystem);
|
||||
}
|
||||
|
||||
|
||||
$insertResult = $this->NotizModel->insert(array(
|
||||
'titel' => 'TAG',
|
||||
'text' => $notizText,
|
||||
'verfasser_uid' => null,
|
||||
'erledigt' => false,
|
||||
'insertamum' => date('Y-m-d H:i:s'),
|
||||
'insertvon' => $insertvonMockUser,
|
||||
'typ' => $notizType
|
||||
));
|
||||
|
||||
if (isError($insertResult))
|
||||
{
|
||||
error("Error occurred while inserting Notiz: " . $insertResult->message);
|
||||
return false;
|
||||
}
|
||||
|
||||
$insertKalenderNotiz = $this->KalenderNotizModel->insert(array(
|
||||
'notiz_id' => $insertResult->retval,
|
||||
'eindeutige_kalender_gruppen_id' => $eindeutige_kalender_gruppen_id
|
||||
));
|
||||
|
||||
if (isError($insertKalenderNotiz))
|
||||
{
|
||||
error("Error occurred while inserting KalenderNotiz: " . $insertKalenderNotiz->message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function updateTag($eindeutige_kalender_gruppen_id, $notizText, $lastUpdatedInOldSystem)
|
||||
{
|
||||
$notizType = 'hinweis';
|
||||
$insertvonMockUser = 'oldToNewTempusMigration';
|
||||
|
||||
$this->KalenderNotizModel->addJoin('tbl_notiz', 'tbl_notiz.notiz_id = tbl_kalender_notiz.notiz_id', 'LEFT');
|
||||
$this->KalenderNotizModel->db->where('tbl_notiz.typ', $notizType);
|
||||
$this->KalenderNotizModel->db->where('tbl_notiz.insertvon', $insertvonMockUser);
|
||||
$kalenderNotizRes = $this->KalenderNotizModel->loadWhere(array('eindeutige_kalender_gruppen_id' => $eindeutige_kalender_gruppen_id));
|
||||
if (isError($kalenderNotizRes))
|
||||
{
|
||||
error("Error occurred while loading KalenderNotiz: " . $kalenderNotizRes->message);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$tag = $this->NotizModel->loadWhere(array('notiz_id' => $kalenderNotizRes->retval[0]->notiz_id));
|
||||
if (isError($tag))
|
||||
{
|
||||
error("Error occurred while loading Notiz: " . $tag->message);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hasData($tag))
|
||||
{
|
||||
error("Error occurred while loading KalenderNotiz: " . $tag->message);
|
||||
return false;
|
||||
}
|
||||
|
||||
$adjustedLastUpdatedInOldSystem = date('Y-m-d H:i:s', strtotime($lastUpdatedInOldSystem) + 5);
|
||||
if ($tag->retval[0]->updateamum >= $adjustedLastUpdatedInOldSystem)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
$updateData = $this->NotizModel->update(array('notiz_id' => $tag->retval[0]->notiz_id),
|
||||
array('text' => $notizText,
|
||||
'updateamum' => date('Y-m-d H:i:s'),
|
||||
'updatevon' => $insertvonMockUser,
|
||||
'bearbeiter_uid' => null,
|
||||
)
|
||||
);
|
||||
if (isError($updateData))
|
||||
{
|
||||
error("Error occurred while updating Notiz: " . $updateData->message);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class Tag_Controller extends FHCAPI_Controller
|
||||
$this->load->model('person/Notiz_model', 'NotizModel');
|
||||
$this->load->model('system/Notiztyp_model', 'NotiztypModel');
|
||||
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
|
||||
|
||||
|
||||
$this->loadPhrases([
|
||||
'ui'
|
||||
]);
|
||||
@@ -122,7 +122,36 @@ class Tag_Controller extends FHCAPI_Controller
|
||||
$notiztypen = $this->NotiztypModel->loadWhere(array('aktiv' => true));
|
||||
$this->terminateWithSuccess(hasData($notiztypen) ? getData($notiztypen) : array());
|
||||
}
|
||||
public function getTagsByAssignmentTypeValue($zuordnung_typ, $zuordnung_id, $tags = null)
|
||||
{
|
||||
$language = $this->_getLanguageIndex();
|
||||
$index_bezeichnung_mehrsprachig = $language - 1;
|
||||
|
||||
$this->NotizzuordnungModel->addSelect(
|
||||
'tbl_notizzuordnung.notiz_id as notiz_id,
|
||||
typ_kurzbz as tag_typ_kurzbz,
|
||||
array_to_json(bezeichnung_mehrsprachig::varchar[])->>'. $index_bezeichnung_mehrsprachig. ' as bezeichnung,
|
||||
style,
|
||||
beschreibung,
|
||||
tag,
|
||||
tbl_notiz.erledigt as done
|
||||
'
|
||||
);
|
||||
|
||||
if (is_array($tags) && !isEmptyArray($tags))
|
||||
{
|
||||
$tags = $this->_filterTag($tags, false);
|
||||
$this->NotizzuordnungModel->db->where_in('tbl_notiz_typ.typ_kurzbz', $tags);
|
||||
}
|
||||
|
||||
$this->NotizzuordnungModel->addJoin('public.tbl_notiz', 'public.tbl_notizzuordnung.notiz_id = public.tbl_notiz.notiz_id');
|
||||
$this->NotizzuordnungModel->addJoin('public.tbl_notiz_typ', 'public.tbl_notiz.typ = public.tbl_notiz_typ.typ_kurzbz');
|
||||
|
||||
$this->NotizzuordnungModel->addOrder('prioritaet');
|
||||
|
||||
$notiztypen = $this->NotizzuordnungModel->loadWhere(array('aktiv' => true, $zuordnung_typ => $zuordnung_id));
|
||||
$this->terminateWithSuccess(hasData($notiztypen) ? getData($notiztypen) : array());
|
||||
}
|
||||
public function addTag($withZuordnung = true, $updatable_tags = null)
|
||||
{
|
||||
$postData = $this->getPostJson();
|
||||
|
||||
@@ -9,23 +9,16 @@ class CollisionChecker
|
||||
private $_checks = [];
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
public function __construct()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->library('collision/checks/RoomCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('collision/checks/LectureCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('collision/checks/VerbandCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('collision/checks/StudentCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('collision/checks/ResourcesCollisionCheck', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('collision/checks/RoomCollisionCheck');
|
||||
$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);
|
||||
@@ -71,4 +64,4 @@ class CollisionChecker
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,17 +5,9 @@ if (! defined("BASEPATH")) exit("No direct script access allowed");
|
||||
class KalenderLib
|
||||
{
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
public function __construct()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->model('ressource/Kalender_Lehreinheit_model', 'KalenderLehreinheitModel');
|
||||
@@ -35,34 +27,20 @@ class KalenderLib
|
||||
$this->_ci->load->model('organisation/Ferien_model', 'FerienModel');
|
||||
|
||||
|
||||
$this->_ci->load->library('CollisionChecker', ['uid' => $this->_uid]);
|
||||
$this->_ci->load->library('CollisionChecker');
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
|
||||
|
||||
}
|
||||
|
||||
private function _buildFilteredKalenderCte($start_date, $end_date)
|
||||
{
|
||||
$end_date = date('Y-m-d', strtotime($end_date . ' +1 day'));
|
||||
|
||||
return sprintf(
|
||||
'WITH filtered_kalender AS MATERIALIZED (
|
||||
SELECT *
|
||||
FROM lehre.tbl_kalender
|
||||
WHERE von >= timestamp %s
|
||||
AND bis < timestamp %s
|
||||
)',
|
||||
$this->_ci->KalenderModel->db->escape(date('Y-m-d H:i:s', strtotime($start_date))),
|
||||
$this->_ci->KalenderModel->db->escape(date('Y-m-d H:i:s', strtotime($end_date)))
|
||||
);
|
||||
}
|
||||
|
||||
private function _buildBasePlanQuery()
|
||||
private function _getBasePlan($start_date, $end_date)
|
||||
{
|
||||
$language = $this->getLanguageIndex();
|
||||
$index_bezeichnung_mehrsprachig = $language - 1;
|
||||
|
||||
$end_date = date('Y-m-d', strtotime($end_date . ' +1 day'));
|
||||
|
||||
$this->_ci->KalenderModel->addSelect('tbl_kalender.kalender_id,
|
||||
tbl_kalender.eindeutige_kalender_gruppen_id,
|
||||
tbl_kalender.status_kurzbz,
|
||||
@@ -161,7 +139,6 @@ class KalenderLib
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_benutzer resevierung_benutzer', 'reservierung_ma.mitarbeiter_uid = resevierung_benutzer.uid', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_person reservierung_person', 'reservierung_person.person_id = resevierung_benutzer.person_id', 'LEFT');
|
||||
|
||||
|
||||
$this->_ci->KalenderModel->addJoin('lehre.tbl_lehreinheitgruppe', 'tbl_lehreinheit.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_gruppe le_gruppe', 'tbl_lehreinheitgruppe.gruppe_kurzbz = le_gruppe.gruppe_kurzbz', 'LEFT');
|
||||
$this->_ci->KalenderModel->addJoin('public.tbl_lehrverband le_lehrverband',
|
||||
@@ -200,7 +177,7 @@ class KalenderLib
|
||||
n.erledigt AS done,
|
||||
nt.prioritaet AS prioritaet,
|
||||
nz.eindeutige_kalender_gruppen_id
|
||||
FROM lehre.tbl_kalender_notiz AS nz
|
||||
FROM public.tbl_notizzuordnung AS nz
|
||||
JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id
|
||||
JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz " . $whereTags . "
|
||||
) AS tag
|
||||
@@ -239,17 +216,12 @@ class KalenderLib
|
||||
$this->_ci->KalenderModel->db->join('lehre.tbl_stunde vonstunde', 'tbl_kalender.von::time = vonstunde.beginn', 'LEFT', FALSE);
|
||||
$this->_ci->KalenderModel->db->join('lehre.tbl_stunde bisstunde', 'tbl_kalender.bis::time = bisstunde.ende', 'LEFT', FALSE);
|
||||
|
||||
$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_kalender_gruppen_id', 'DESC');
|
||||
}
|
||||
|
||||
private function _loadFilteredBasePlan($start_date, $end_date)
|
||||
{
|
||||
$query = $this->_buildFilteredKalenderCte($start_date, $end_date) . "\n" .
|
||||
$this->_ci->KalenderModel->db->get_compiled_select('filtered_kalender AS tbl_kalender');
|
||||
|
||||
return $this->_ci->KalenderModel->execReadOnlyQuery($query);
|
||||
}
|
||||
|
||||
private function _mapEvents($data, $collisionCheck = true)
|
||||
{
|
||||
$stundenplan_data = [];
|
||||
@@ -271,7 +243,7 @@ class KalenderLib
|
||||
$parsedResources = is_string($resources) ? json_decode($resources, true) : $resources;
|
||||
|
||||
$events[$id] = (object) [
|
||||
'kalender_id' => $id,
|
||||
'kalender_id' => $id,
|
||||
'eindeutige_kalender_gruppen_id' => $row->eindeutige_kalender_gruppen_id,
|
||||
'type' => $row->typ,
|
||||
'beginn' => $von->format('H:i:s'),
|
||||
@@ -302,7 +274,6 @@ class KalenderLib
|
||||
'has_assigned_resources' => !empty($parsedResources),
|
||||
'resources' => is_array($parsedResources) ? $parsedResources : [],
|
||||
'tags' => isset($row->tags) ? $row->tags : [],
|
||||
'updateamum' => isset($row->updateamum) ? $row->updateamum : null,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -398,10 +369,10 @@ class KalenderLib
|
||||
}
|
||||
public function getPlanByOrt($start_date, $end_date, $ort)
|
||||
{
|
||||
$this->_buildBasePlanQuery();
|
||||
$this->_getBasePlan($start_date, $end_date);
|
||||
|
||||
$this->_ci->KalenderModel->db->where('tbl_kalender_ort.ort_kurzbz', $ort);
|
||||
$data = $this->_loadFilteredBasePlan($start_date, $end_date);
|
||||
$data = $this->_ci->KalenderModel->load();
|
||||
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
@@ -411,7 +382,7 @@ class KalenderLib
|
||||
$start_date = date('Y-m-d', strtotime($start_date));
|
||||
$end_date = date('Y-m-d', strtotime($end_date . ' +1 day'));
|
||||
|
||||
$this->_buildBasePlanQuery();
|
||||
$this->_getBasePlan($start_date, $end_date);
|
||||
|
||||
$this->_ci->KalenderModel->db->where('NOT EXISTS (
|
||||
SELECT 1 FROM lehre.tbl_kalender nachfolger
|
||||
@@ -443,7 +414,7 @@ class KalenderLib
|
||||
$this->_ci->KalenderModel->db->group_end();
|
||||
}
|
||||
|
||||
$data = $this->_loadFilteredBasePlan($start_date, $end_date);
|
||||
$data = $this->_ci->KalenderModel->load();
|
||||
return $this->_mapEvents($data, false);
|
||||
}
|
||||
|
||||
@@ -459,14 +430,14 @@ class KalenderLib
|
||||
|
||||
$kalender_entry = getData($kalender_entry)[0];
|
||||
|
||||
$this->_buildBasePlanQuery();
|
||||
$this->_getBasePlan($kalender_entry->von, $kalender_entry->bis);
|
||||
$this->_ci->KalenderModel->db->where('tbl_kalender.kalender_id', $kalender_entry->kalender_id);
|
||||
$data = $this->_loadFilteredBasePlan($kalender_entry->von, $kalender_entry->bis);
|
||||
$data = $this->_ci->KalenderModel->load();
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
public function getPlanForPlanner($start_date, $end_date, $ort = null, $uids = null, $studiengaenge = null)
|
||||
{
|
||||
$this->_buildBasePlanQuery();
|
||||
$this->_getBasePlan($start_date, $end_date);
|
||||
|
||||
if (!is_null($ort))
|
||||
{
|
||||
@@ -569,151 +540,26 @@ class KalenderLib
|
||||
) AS has_assigned_resources"
|
||||
]);
|
||||
|
||||
$data = $this->_loadFilteredBasePlan($start_date, $end_date);
|
||||
$data = $this->_ci->KalenderModel->load();
|
||||
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
|
||||
public function getPlanForStudent($start_date, $end_date)
|
||||
{
|
||||
$this->_buildBasePlanQuery();
|
||||
$this->_getBasePlan($start_date, $end_date);
|
||||
|
||||
$this->_ci->KalenderModel->db->where_in('status_kurzbz', array('live', 'to_delete_live'));
|
||||
|
||||
$data = $this->_loadFilteredBasePlan($start_date, $end_date);
|
||||
$data = $this->_ci->KalenderModel->load();
|
||||
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
|
||||
public function getPlanForStudentByStudent($start_date, $end_date, $userUID)
|
||||
{
|
||||
$this->_buildBasePlanQuery();
|
||||
|
||||
$escapedUserUID = $this->_ci->KalenderModel->db->escape($userUID);
|
||||
|
||||
$benutzerExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM public.tbl_benutzer student_benutzer
|
||||
WHERE student_benutzer.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$directEventTeilnehmerExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer event_teilnehmer
|
||||
WHERE event_teilnehmer.kalender_id = tbl_kalender.kalender_id
|
||||
AND event_teilnehmer.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$eventBenutzergruppeExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer event_gruppe
|
||||
JOIN public.tbl_benutzergruppe event_benutzergruppe
|
||||
ON event_benutzergruppe.gruppe_kurzbz = event_gruppe.gruppe_kurzbz
|
||||
AND (
|
||||
event_gruppe.studiensemester_kurzbz IS NULL
|
||||
OR event_benutzergruppe.studiensemester_kurzbz = event_gruppe.studiensemester_kurzbz
|
||||
)
|
||||
WHERE event_gruppe.kalender_id = tbl_kalender.kalender_id
|
||||
AND event_gruppe.gruppe_kurzbz IS NOT NULL
|
||||
AND event_benutzergruppe.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$eventStudentlehrverbandExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer event_lehrverband
|
||||
JOIN public.tbl_studentlehrverband event_studentlehrverband
|
||||
ON event_studentlehrverband.student_uid = $escapedUserUID
|
||||
AND event_studentlehrverband.studiengang_kz = event_lehrverband.studiengang_kz
|
||||
AND (
|
||||
event_lehrverband.studiensemester_kurzbz IS NULL
|
||||
OR event_studentlehrverband.studiensemester_kurzbz = event_lehrverband.studiensemester_kurzbz
|
||||
)
|
||||
AND (
|
||||
event_lehrverband.semester IS NULL
|
||||
OR event_studentlehrverband.semester = event_lehrverband.semester
|
||||
)
|
||||
AND (
|
||||
event_lehrverband.verband = event_studentlehrverband.verband
|
||||
OR event_lehrverband.verband IS NULL
|
||||
OR btrim(event_lehrverband.verband::text) = ''
|
||||
OR event_studentlehrverband.verband IS NULL
|
||||
)
|
||||
AND (
|
||||
event_lehrverband.gruppe = event_studentlehrverband.gruppe
|
||||
OR event_lehrverband.gruppe IS NULL
|
||||
OR btrim(event_lehrverband.gruppe::text) = ''
|
||||
OR event_studentlehrverband.gruppe IS NULL
|
||||
)
|
||||
WHERE event_lehrverband.kalender_id = tbl_kalender.kalender_id
|
||||
AND event_lehrverband.gruppe_kurzbz IS NULL
|
||||
AND event_lehrverband.studiengang_kz IS NOT NULL
|
||||
)";
|
||||
|
||||
$lehreinheitBenutzergruppeExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_lehreinheit student_kalender_lehreinheit
|
||||
JOIN lehre.tbl_lehreinheit student_lehreinheit
|
||||
ON student_lehreinheit.lehreinheit_id = student_kalender_lehreinheit.lehreinheit_id
|
||||
JOIN lehre.tbl_lehreinheitgruppe student_lehreinheitgruppe
|
||||
ON student_lehreinheitgruppe.lehreinheit_id = student_lehreinheit.lehreinheit_id
|
||||
JOIN public.tbl_gruppe student_gruppe
|
||||
ON student_gruppe.studiengang_kz = student_lehreinheitgruppe.studiengang_kz
|
||||
AND student_gruppe.semester = student_lehreinheitgruppe.semester
|
||||
AND student_gruppe.gruppe_kurzbz = student_lehreinheitgruppe.gruppe_kurzbz
|
||||
JOIN public.tbl_benutzergruppe student_benutzergruppe
|
||||
ON student_benutzergruppe.gruppe_kurzbz = student_gruppe.gruppe_kurzbz
|
||||
AND student_benutzergruppe.studiensemester_kurzbz = student_lehreinheit.studiensemester_kurzbz
|
||||
WHERE student_kalender_lehreinheit.kalender_id = tbl_kalender.kalender_id
|
||||
AND student_lehreinheitgruppe.gruppe_kurzbz IS NOT NULL
|
||||
AND student_benutzergruppe.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$lehreinheitStudentlehrverbandExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_lehreinheit student_kalender_lehreinheit
|
||||
JOIN lehre.tbl_lehreinheit student_lehreinheit
|
||||
ON student_lehreinheit.lehreinheit_id = student_kalender_lehreinheit.lehreinheit_id
|
||||
JOIN lehre.tbl_lehreinheitgruppe student_lehreinheitgruppe
|
||||
ON student_lehreinheitgruppe.lehreinheit_id = student_lehreinheit.lehreinheit_id
|
||||
JOIN public.tbl_studentlehrverband student_lehrverband
|
||||
ON student_lehrverband.student_uid = $escapedUserUID
|
||||
AND student_lehrverband.studiengang_kz = student_lehreinheitgruppe.studiengang_kz
|
||||
AND student_lehrverband.semester = student_lehreinheitgruppe.semester
|
||||
AND student_lehrverband.studiensemester_kurzbz = student_lehreinheit.studiensemester_kurzbz
|
||||
AND (
|
||||
student_lehreinheitgruppe.verband = student_lehrverband.verband
|
||||
OR student_lehreinheitgruppe.verband IS NULL
|
||||
OR btrim(student_lehreinheitgruppe.verband::text) = ''
|
||||
OR student_lehrverband.verband IS NULL
|
||||
)
|
||||
AND (
|
||||
student_lehreinheitgruppe.gruppe = student_lehrverband.gruppe
|
||||
OR student_lehreinheitgruppe.gruppe IS NULL
|
||||
OR btrim(student_lehreinheitgruppe.gruppe::text) = ''
|
||||
OR student_lehrverband.gruppe IS NULL
|
||||
)
|
||||
WHERE student_kalender_lehreinheit.kalender_id = tbl_kalender.kalender_id
|
||||
AND student_lehreinheitgruppe.gruppe_kurzbz IS NULL
|
||||
)";
|
||||
|
||||
$this->_ci->KalenderModel->db->where('status_kurzbz', 'live');
|
||||
$this->_ci->KalenderModel->db->where($benutzerExists, null, false);
|
||||
$this->_ci->KalenderModel->db->group_start();
|
||||
$this->_ci->KalenderModel->db->where($directEventTeilnehmerExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($eventBenutzergruppeExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($eventStudentlehrverbandExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($lehreinheitBenutzergruppeExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($lehreinheitStudentlehrverbandExists, null, false);
|
||||
$this->_ci->KalenderModel->db->group_end();
|
||||
|
||||
$data = $this->_loadFilteredBasePlan($start_date, $end_date);
|
||||
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
|
||||
public function getPlanForLecturer($start_date, $end_date)
|
||||
{
|
||||
$this->_buildBasePlanQuery();
|
||||
$this->_getBasePlan($start_date, $end_date);
|
||||
|
||||
$this->_ci->KalenderModel->addJoin(
|
||||
'lehre.tbl_kalender neuerer',
|
||||
@@ -725,60 +571,10 @@ class KalenderLib
|
||||
OR (tbl_kalender.status_kurzbz = 'preview' AND neuerer.kalender_id IS NULL)
|
||||
OR (tbl_kalender.status_kurzbz = 'live' AND neuerer.kalender_id IS NULL)
|
||||
)", NULL, FALSE);
|
||||
$data = $this->_loadFilteredBasePlan($start_date, $end_date);
|
||||
$data = $this->_ci->KalenderModel->load();
|
||||
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
|
||||
public function getPlanForLecturerByLecturer($start_date, $end_date, $userUID)
|
||||
{
|
||||
$this->_buildBasePlanQuery();
|
||||
|
||||
$escapedUserUID = $this->_ci->KalenderModel->db->escape($userUID);
|
||||
|
||||
$lehreinheitMitarbeiterExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_lehreinheit lecturer_kalender_lehreinheit
|
||||
JOIN lehre.tbl_lehreinheit lecturer_lehreinheit
|
||||
ON lecturer_lehreinheit.lehreinheit_id = lecturer_kalender_lehreinheit.lehreinheit_id
|
||||
JOIN lehre.tbl_lehreinheitmitarbeiter lecturer_lehreinheitmitarbeiter
|
||||
ON lecturer_lehreinheitmitarbeiter.lehreinheit_id = lecturer_lehreinheit.lehreinheit_id
|
||||
WHERE lecturer_kalender_lehreinheit.kalender_id = tbl_kalender.kalender_id
|
||||
AND lecturer_lehreinheitmitarbeiter.mitarbeiter_uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$eventTeilnehmerExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer lecturer_event_teilnehmer
|
||||
WHERE lecturer_event_teilnehmer.kalender_id = tbl_kalender.kalender_id
|
||||
AND lecturer_event_teilnehmer.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$eventBenutzergruppeExists = "EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_event_teilnehmer lecturer_event_gruppe
|
||||
JOIN public.tbl_benutzergruppe lecturer_benutzergruppe
|
||||
ON lecturer_benutzergruppe.gruppe_kurzbz = lecturer_event_gruppe.gruppe_kurzbz
|
||||
AND (
|
||||
lecturer_event_gruppe.studiensemester_kurzbz IS NULL
|
||||
OR lecturer_benutzergruppe.studiensemester_kurzbz = lecturer_event_gruppe.studiensemester_kurzbz
|
||||
)
|
||||
WHERE lecturer_event_gruppe.kalender_id = tbl_kalender.kalender_id
|
||||
AND lecturer_event_gruppe.gruppe_kurzbz IS NOT NULL
|
||||
AND lecturer_benutzergruppe.uid = $escapedUserUID
|
||||
)";
|
||||
|
||||
$this->_ci->KalenderModel->db->where('tbl_kalender.status_kurzbz', 'live');
|
||||
$this->_ci->KalenderModel->db->group_start();
|
||||
$this->_ci->KalenderModel->db->where($lehreinheitMitarbeiterExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($eventTeilnehmerExists, null, false);
|
||||
$this->_ci->KalenderModel->db->or_where($eventBenutzergruppeExists, null, false);
|
||||
$this->_ci->KalenderModel->db->group_end();
|
||||
|
||||
$data = $this->_loadFilteredBasePlan($start_date, $end_date);
|
||||
return $this->_mapEvents($data);
|
||||
}
|
||||
|
||||
public function getZeitsperren($start_date, $end_date, $emp)
|
||||
{
|
||||
$db = new DB_Model();
|
||||
@@ -1327,7 +1123,6 @@ class KalenderLib
|
||||
'bis' => $end_date,
|
||||
'typ' => 'reservierung',
|
||||
'status_kurzbz' => 'live',
|
||||
'eindeutige_kalender_gruppen_id' => $this->_ci->KalenderModel->generateUniqueGroupId(),
|
||||
'insertvon' => getAuthUID(),
|
||||
'insertamum' => date('Y-m-d H:i:s')
|
||||
)
|
||||
@@ -1588,7 +1383,6 @@ class KalenderLib
|
||||
$entryResult = $this->_loadKalenderEntry($kalender_id);
|
||||
if (isError($entryResult)) return $entryResult;
|
||||
|
||||
|
||||
$kalender_entry = getData($entryResult);
|
||||
|
||||
if (!$this->_checkPermission($kalender_entry->lehreinheit_id))
|
||||
@@ -2046,7 +1840,7 @@ class KalenderLib
|
||||
else
|
||||
{
|
||||
|
||||
if (!isEmptyArray($kalender_entry->ort_kurzbz) || !isEmptyString($kalender_entry->location))
|
||||
if (!isEmptyArray($kalender_entry->ort_kurzbz))
|
||||
{
|
||||
$result = $this->_deleteOrtEntry($kalender_entry);
|
||||
if (isError($result))
|
||||
|
||||
@@ -7,18 +7,10 @@ use CI3_Events as Events;
|
||||
class RaumvorschlagLib
|
||||
{
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
public function __construct()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->model('ressource/Kalender_Lehreinheit_model', 'KalenderLehreinheitModel');
|
||||
$this->_ci->load->model('ressource/Kalender_Event_model', 'KalenderEventModel');
|
||||
@@ -34,8 +26,8 @@ class RaumvorschlagLib
|
||||
$this->_ci->load->model('ressource/Stunde_model', 'StundeModel');
|
||||
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
|
||||
|
||||
$this->_ci->load->library('CollisionChecker', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('KalenderLib', ["uid" => getAuthUID()]);
|
||||
$this->_ci->load->library('CollisionChecker');
|
||||
$this->_ci->load->library('KalenderLib');
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ class VariableLib
|
||||
/**
|
||||
* VariableLib constructor.
|
||||
* Loads variable of logged in user.
|
||||
* @param $params
|
||||
* @param $loggeduid
|
||||
*/
|
||||
public function __construct($params)
|
||||
public function __construct($loggeduid)
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
@@ -25,8 +25,8 @@ class VariableLib
|
||||
$this->_ci->load->model('system/Variable_model', 'VariableModel');
|
||||
$this->_ci->load->model('organisation/studiensemester_model', 'StudiensemesterModel');
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid']))
|
||||
$this->_setVariables($params['uid']);
|
||||
if (isset($loggeduid['uid']) && !isEmptyString($loggeduid['uid']))
|
||||
$this->_setVariables($loggeduid['uid']);
|
||||
else
|
||||
{
|
||||
show_error('uid of logged user not passed!');
|
||||
|
||||
@@ -4,18 +4,10 @@ class LectureCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
public function __construct()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->model('ressource/Zeitsperre_model', 'ZeitsperreModel');
|
||||
$this->_ci->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
|
||||
|
||||
@@ -4,20 +4,12 @@ class ResourcesCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
public function __construct()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->library('VariableLib', array('uid' => $this->_uid));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
}
|
||||
|
||||
@@ -99,4 +91,4 @@ class ResourcesCollisionCheck implements ICollisionCheck
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,12 @@ class RoomCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
public function __construct()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->library('VariableLib', array('uid' => $this->_uid));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
}
|
||||
|
||||
@@ -95,4 +87,4 @@ class RoomCollisionCheck implements ICollisionCheck
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,20 +3,12 @@
|
||||
class StudentCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
public function __construct()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->library('VariableLib', array('uid' => $this->_uid));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
}
|
||||
|
||||
@@ -291,4 +283,4 @@ class StudentCollisionCheck implements ICollisionCheck
|
||||
|
||||
return $grouped;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,12 @@ class VerbandCollisionCheck implements ICollisionCheck
|
||||
{
|
||||
|
||||
private $_ci;
|
||||
private $_uid;
|
||||
|
||||
public function __construct($params)
|
||||
public function __construct()
|
||||
{
|
||||
$this->_ci =& get_instance();
|
||||
|
||||
if (isset($params['uid']) && !isEmptyString($params['uid'])){
|
||||
$this->_uid = $params['uid'];
|
||||
} else {
|
||||
show_error('uid of logged user not passed!');
|
||||
}
|
||||
|
||||
$this->_ci->load->model('ressource/Kalender_model', 'KalenderModel');
|
||||
$this->_ci->load->library('VariableLib', array('uid' => $this->_uid));
|
||||
$this->_ci->load->library('VariableLib', array('uid' => getAuthUID()));
|
||||
$this->_ci->load->library('PhrasesLib', array('ui'));
|
||||
|
||||
}
|
||||
@@ -418,4 +410,4 @@ class VerbandCollisionCheck implements ICollisionCheck
|
||||
return $grouped;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
<?php
|
||||
class KalenderNotiz_model extends DB_Model
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->dbTable = 'lehre.tbl_kalender_notiz';
|
||||
$this->pk = array('eindeutige_kalender_gruppen_id', 'notiz_id');
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,6 @@ class Kalender_model extends DB_Model
|
||||
parent::__construct();
|
||||
$this->dbTable = 'lehre.tbl_kalender';
|
||||
$this->pk = 'kalender_id';
|
||||
|
||||
$this->load->helper('hlp_common');
|
||||
}
|
||||
|
||||
public function generateUniqueGroupId()
|
||||
|
||||
+98
-29
@@ -6,19 +6,19 @@
|
||||
@import './components/Notiz.css';
|
||||
|
||||
html {
|
||||
font-size: .875em;
|
||||
height: 100%;
|
||||
font-size: 0.875em;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
/*display: flex;*/
|
||||
height: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.heightfull {
|
||||
height: 95%;
|
||||
height: 95%;
|
||||
}
|
||||
.navbar-dark .navbar-brand:focus {
|
||||
box-shadow: 0 0 0 .25rem rgba(13,110,253,.25);
|
||||
box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
|
||||
z-index: 3;
|
||||
}
|
||||
#main {
|
||||
@@ -28,13 +28,13 @@ body {
|
||||
height: 100%;
|
||||
}
|
||||
.searchbar {
|
||||
margin-right: 0!important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.searchbar > .input-group {
|
||||
margin-right: 0!important;
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.searchbar > .input-group > * {
|
||||
border-radius: 0!important;
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
|
||||
#sidebarMenu {
|
||||
@@ -55,7 +55,7 @@ body {
|
||||
|
||||
@media (min-width: 768px) {
|
||||
#sidebarMenu {
|
||||
visibility: visible!important;
|
||||
visibility: visible !important;
|
||||
transform: none;
|
||||
position: inherit;
|
||||
z-index: 1;
|
||||
@@ -64,27 +64,24 @@ body {
|
||||
|
||||
.toast.toast-success {
|
||||
color: #0f5132;
|
||||
background-color: #d1e7dd!important;
|
||||
border-color: #badbcc!important;
|
||||
background-color: #d1e7dd !important;
|
||||
border-color: #badbcc !important;
|
||||
}
|
||||
.toast.toast-danger {
|
||||
color: #842029;
|
||||
background-color: #f8d7da!important;
|
||||
border-color: #f5c2c7!important;
|
||||
background-color: #f8d7da !important;
|
||||
border-color: #f5c2c7 !important;
|
||||
}
|
||||
|
||||
.has-filter .fa-filter {
|
||||
color: var(--bs-success);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#parkingslot {
|
||||
border: 1px dashed;
|
||||
min-height: 5vh;
|
||||
max-height: 15vh;
|
||||
color: #AAAAAA;
|
||||
color: #aaaaaa;
|
||||
text-align: center;
|
||||
font-size: large;
|
||||
margin-top: 1.25rem;
|
||||
@@ -96,7 +93,7 @@ body {
|
||||
}
|
||||
|
||||
.course-picker {
|
||||
border: 1px dashed #AAAAAA;
|
||||
border: 1px dashed #aaaaaa;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 0;
|
||||
@@ -132,11 +129,11 @@ body {
|
||||
}
|
||||
|
||||
.eckerltest {
|
||||
box-shadow: 3px 3px 3px #ccc;
|
||||
box-shadow: 3px 3px 3px #ccc;
|
||||
}
|
||||
|
||||
.verband-selection {
|
||||
border: 1px dashed #AAAAAA;
|
||||
border: 1px dashed #aaaaaa;
|
||||
margin-bottom: 0.5rem;
|
||||
max-height: 450px;
|
||||
overflow-y: auto;
|
||||
@@ -145,7 +142,7 @@ body {
|
||||
}
|
||||
|
||||
.lecture-selection {
|
||||
border: 1px dashed #AAAAAA;
|
||||
border: 1px dashed #aaaaaa;
|
||||
margin-bottom: 0.5rem;
|
||||
max-height: 20vh;
|
||||
overflow-y: auto;
|
||||
@@ -154,7 +151,7 @@ body {
|
||||
}
|
||||
|
||||
.room-selection {
|
||||
border: 1px dashed #AAAAAA;
|
||||
border: 1px dashed #aaaaaa;
|
||||
margin-bottom: 0.5rem;
|
||||
padding: 0.5rem 0 0.5rem 0.5rem;
|
||||
}
|
||||
@@ -169,10 +166,8 @@ body {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
.bg-lecturer-wish {
|
||||
opacity: .15;
|
||||
opacity: 0.15;
|
||||
}
|
||||
.bg-lecturer-block {
|
||||
background: rgba(255, 0, 0, 0.15);
|
||||
@@ -195,18 +190,21 @@ body {
|
||||
|
||||
|
||||
.wish-w--2 {
|
||||
background-color: #FF2200;
|
||||
background-color: #ff2200;
|
||||
}
|
||||
.wish-w--1 {
|
||||
background-color: #FF9922;
|
||||
background-color: #ff9922;
|
||||
}
|
||||
.wish-w-1 {
|
||||
background-color: #CCFFCC;
|
||||
background-color: #ccffcc;
|
||||
}
|
||||
.wish-w-2 {
|
||||
background-color: #48FA66;
|
||||
background-color: #48fa66;
|
||||
}
|
||||
|
||||
.fhc-calendar-base-grid-line-event {
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
.room-option {
|
||||
display: grid;
|
||||
@@ -214,3 +212,74 @@ body {
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.updated-event {
|
||||
position: relative !important;
|
||||
z-index: 10;
|
||||
animation: modernFocus 1s ease-out;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.updated-event-long {
|
||||
position: relative !important;
|
||||
z-index: 10;
|
||||
animation: modernFocus 1.8s ease-out;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
@keyframes modernFocus {
|
||||
0% {
|
||||
background-color: #cfd4d8;
|
||||
box-shadow:
|
||||
0 0 0 0 rgba(120, 120, 120, 0.8),
|
||||
0 0 0 0 rgba(255, 255, 255, 0.6);
|
||||
}
|
||||
|
||||
30% {
|
||||
background-color: #eef1f3;
|
||||
box-shadow:
|
||||
0 0 0 8px rgba(120, 120, 120, 0.25),
|
||||
0 0 30px 8px rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
|
||||
60% {
|
||||
background-color: #f7f8f9;
|
||||
box-shadow:
|
||||
0 0 0 14px rgba(120, 120, 120, 0.15),
|
||||
0 0 45px 12px rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
100% {
|
||||
background-color: inherit;
|
||||
box-shadow:
|
||||
0 0 0 24px rgba(120, 120, 120, 0),
|
||||
0 0 60px 20px rgba(255, 255, 255, 0);
|
||||
}
|
||||
}
|
||||
|
||||
.spinner-overlay {
|
||||
position: absolute;
|
||||
inset: 0; /* top:0 right:0 bottom:0 left:0 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
z-index: 9999;
|
||||
background: rgba(255, 255, 255, 1);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border: 4px solid #ddd;
|
||||
border-top: 4px solid #007bff;
|
||||
border-radius: 50%;
|
||||
animation: spin 0.8s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import LineEvent from "./Line/Event.js";
|
||||
import LineBackground from "./Line/Background.js";
|
||||
import LineEvent from './Line/Event.js';
|
||||
import LineBackground from './Line/Background.js';
|
||||
|
||||
/**
|
||||
* TODO(chris):
|
||||
@@ -7,19 +7,19 @@ import LineBackground from "./Line/Background.js";
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: "GridLine",
|
||||
name: 'GridLine',
|
||||
components: {
|
||||
LineEvent,
|
||||
LineBackground,
|
||||
},
|
||||
inject: {
|
||||
axisRow: "axisRow",
|
||||
axisRow: 'axisRow',
|
||||
shouldCompactEvents: {
|
||||
from: "shouldCompactEvents",
|
||||
from: 'shouldCompactEvents',
|
||||
default: undefined,
|
||||
},
|
||||
compactibleEventTypes: {
|
||||
from: "compactibleEventTypes",
|
||||
from: 'compactibleEventTypes',
|
||||
default: undefined,
|
||||
},
|
||||
},
|
||||
@@ -50,19 +50,20 @@ export default {
|
||||
let formattedEvents = this.events.map((event) => {
|
||||
event.rows = [1, -1];
|
||||
if (event.startsHere) {
|
||||
event.rows[0] =
|
||||
"t_" + event.start.diff(this.date).toMillis();
|
||||
event.rows[0] = 't_' + event.start.diff(this.date).toMillis();
|
||||
}
|
||||
if (event.endsHere) {
|
||||
event.rows[1] = "t_" + event.end.diff(this.date).toMillis();
|
||||
event.rows[1] = 't_' + event.end.diff(this.date).toMillis();
|
||||
}
|
||||
|
||||
return event;
|
||||
});
|
||||
|
||||
if (this.shouldCompactEvents && this.compactibleEventTypes?.length) {
|
||||
formattedEvents =
|
||||
this.compactEvents(formattedEvents, this.compactibleEventTypes);
|
||||
formattedEvents = this.compactEvents(
|
||||
formattedEvents,
|
||||
this.compactibleEventTypes,
|
||||
);
|
||||
}
|
||||
|
||||
return formattedEvents;
|
||||
@@ -71,12 +72,9 @@ export default {
|
||||
methods: {
|
||||
compactEvents(events, compactibleEventTypes) {
|
||||
let formattedEvents = events
|
||||
.filter(
|
||||
(event) =>
|
||||
!compactibleEventTypes.includes(event.type),
|
||||
)
|
||||
.filter((event) => !compactibleEventTypes.includes(event.type))
|
||||
.map((event) => {
|
||||
event.display = "default";
|
||||
event.display = 'default';
|
||||
return event;
|
||||
});
|
||||
let eventsToBeCompacted = events.filter((event) =>
|
||||
@@ -110,17 +108,17 @@ export default {
|
||||
compactedEvents.forEach((compactedEvent) => {
|
||||
if (compactedEvent.events.length < 4) {
|
||||
formattedEvents.push({
|
||||
display: "compacted",
|
||||
display: 'compacted',
|
||||
...compactedEvent,
|
||||
});
|
||||
} else {
|
||||
formattedEvents.push({
|
||||
display: "compacted",
|
||||
display: 'compacted',
|
||||
events: compactedEvent.events.slice(0, 3),
|
||||
rows: compactedEvent.rows,
|
||||
});
|
||||
formattedEvents.push({
|
||||
display: "compactedExtra",
|
||||
display: 'compactedExtra',
|
||||
events: compactedEvent.events.slice(3),
|
||||
rows: compactedEvent.rows,
|
||||
});
|
||||
@@ -133,7 +131,6 @@ export default {
|
||||
template: /* html */ `
|
||||
<div
|
||||
class="fhc-calendar-base-grid-line"
|
||||
:data-day="date.toISODate()"
|
||||
style="position:relative;display:grid;grid-auto-flow:dense"
|
||||
:style="'grid-template-' + axisRow + 's:subgrid'"
|
||||
>
|
||||
|
||||
@@ -3,72 +3,74 @@ import drop from '../../../../../directives/drop.js';
|
||||
import CalClick from '../../../../../directives/Calendar/Click.js';
|
||||
|
||||
export default {
|
||||
name: "GridLineEvent",
|
||||
name: 'GridLineEvent',
|
||||
directives: {
|
||||
draggable,
|
||||
drop,
|
||||
CalClick
|
||||
CalClick,
|
||||
},
|
||||
emits: [
|
||||
'resize-start'
|
||||
],
|
||||
emits: ['resize-start'],
|
||||
data() {
|
||||
return {
|
||||
contextMenu: {
|
||||
show: false,
|
||||
x: 0,
|
||||
y: 0
|
||||
}
|
||||
y: 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
inject: {
|
||||
draggableEvents: "draggableEvents",
|
||||
draggableEvents: 'draggableEvents',
|
||||
resizableEvents: {
|
||||
from: "resizableEvents",
|
||||
default: () => () => false
|
||||
from: 'resizableEvents',
|
||||
default: () => () => false,
|
||||
},
|
||||
mode: "mode",
|
||||
mode: 'mode',
|
||||
contextMenuActions: {
|
||||
from: "contextMenuActions",
|
||||
default: () => ({})
|
||||
from: 'contextMenuActions',
|
||||
default: () => ({}),
|
||||
},
|
||||
onDrop: {
|
||||
from: "onDrop",
|
||||
default: () => null
|
||||
from: 'onDrop',
|
||||
default: () => null,
|
||||
},
|
||||
onDropEvent: {
|
||||
from: "onDropEvent",
|
||||
default: () => () => {}
|
||||
}
|
||||
from: 'onDropEvent',
|
||||
default: () => () => {},
|
||||
},
|
||||
},
|
||||
props: {
|
||||
event: {
|
||||
type: Object,
|
||||
required: true,
|
||||
validator(value) {
|
||||
return (value.start && value.end && value.orig);
|
||||
}
|
||||
}
|
||||
return value.start && value.end && value.orig;
|
||||
},
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
isHeaderOrFooter() {
|
||||
return ['header', 'footer'].includes(this.event.orig);
|
||||
},
|
||||
draggable() {
|
||||
return !this.isHeaderOrFooter && this.draggableEvents(this.event.orig, this.mode);
|
||||
return (
|
||||
!this.isHeaderOrFooter &&
|
||||
this.draggableEvents(this.event.orig, this.mode)
|
||||
);
|
||||
},
|
||||
resizable() {
|
||||
return !this.isHeaderOrFooter && this.resizableEvents(this.event.orig, this.mode);
|
||||
return (
|
||||
!this.isHeaderOrFooter &&
|
||||
this.resizableEvents(this.event.orig, this.mode)
|
||||
);
|
||||
},
|
||||
classes() {
|
||||
const classes = [];
|
||||
if (this.isHeaderOrFooter) {
|
||||
classes.push('event-' + this.event.orig);
|
||||
} else {
|
||||
if (this.event.startsHere)
|
||||
classes.push('event-begin');
|
||||
if (this.event.endsHere)
|
||||
classes.push('event-end');
|
||||
if (this.event.startsHere) classes.push('event-begin');
|
||||
if (this.event.endsHere) classes.push('event-end');
|
||||
}
|
||||
|
||||
classes.push(`calender_id-${this.event.orig.kalender_id}`);
|
||||
@@ -85,9 +87,14 @@ export default {
|
||||
activeContextActions() {
|
||||
if (this.isHeaderOrFooter) return [];
|
||||
const type = this.event.orig?.type ?? 'lehreinheit';
|
||||
const actions = this.contextMenuActions[type] ?? this.contextMenuActions['default'] ?? [];
|
||||
return actions.filter(action => !action.visible || action.visible(this.event.orig));
|
||||
}
|
||||
const actions =
|
||||
this.contextMenuActions[type] ??
|
||||
this.contextMenuActions['default'] ??
|
||||
[];
|
||||
return actions.filter(
|
||||
(action) => !action.visible || action.visible(this.event.orig),
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onResizeStart(edge, evt) {
|
||||
@@ -95,7 +102,7 @@ export default {
|
||||
edge,
|
||||
evt,
|
||||
el: this.$refs.eventEl,
|
||||
event: this.event
|
||||
event: this.event,
|
||||
});
|
||||
},
|
||||
onRightClick(evt) {
|
||||
@@ -116,40 +123,37 @@ export default {
|
||||
evt.dataTransfer.setData('fhc-grab-offset-x', evt.clientX - rect.left);
|
||||
},
|
||||
onDropOnCard(evt, items) {
|
||||
if (this.isHeaderOrFooter || !this.onDrop)
|
||||
return;
|
||||
if (this.isHeaderOrFooter || !this.onDrop) return;
|
||||
|
||||
const list = Array.isArray(items) ? items : [items];
|
||||
const obj = list[0];
|
||||
if (!obj)
|
||||
return;
|
||||
if (!obj) return;
|
||||
|
||||
if ((evt.ctrlKey || evt.metaKey) && obj.type === 'lehreinheit')
|
||||
{
|
||||
if ((evt.ctrlKey || evt.metaKey) && obj.type === 'lehreinheit') {
|
||||
return this.onDrop({
|
||||
item: [obj],
|
||||
ctrlKey: true,
|
||||
targetKalenderId: this.event.orig?.kalender_id ?? null
|
||||
targetKalenderId: this.event.orig?.kalender_id ?? null,
|
||||
});
|
||||
}
|
||||
|
||||
return this.onDropEvent(evt, items, this.event.start.startOf('day'));
|
||||
},
|
||||
},
|
||||
template:`
|
||||
template: `
|
||||
<div
|
||||
class="fhc-calendar-base-grid-line-event event"
|
||||
:class="classes"
|
||||
style="z-index: 11"
|
||||
:draggable="draggable"
|
||||
:data-id="'event-' + event.orig.kalender_id"
|
||||
:data-group-id="'event-group-' + event.orig.eindeutige_kalender_gruppen_id"
|
||||
ref="eventEl"
|
||||
@dragstart="onDragStart"
|
||||
v-draggable:move.noimage="draggable ? dragKalenderCollection : {}"
|
||||
v-drop:move.lehreinheit.kalender.reservierung="onDropOnCard"
|
||||
v-cal-click:event="isHeaderOrFooter ? event : event.orig"
|
||||
@contextmenu.prevent="onRightClick"
|
||||
:data-id="'event-' + event.orig.kalender_id"
|
||||
:data-group-id="'event-group-' + event.orig.eindeutige_kalender_gruppen_id"
|
||||
data-cy="calendar-event"
|
||||
>
|
||||
<div
|
||||
@@ -195,5 +199,5 @@ export default {
|
||||
</ul>
|
||||
</teleport>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
`,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import FhcCalendar from "./Base.js";
|
||||
import FhcCalendar from './Base.js';
|
||||
|
||||
import { useEventLoader } from '../../composables/EventLoader.js';
|
||||
|
||||
@@ -8,11 +8,10 @@ import ModeTable from './Mode/Table.js';
|
||||
import ApiKalender from '../../api/factory/tempus/kalender.js';
|
||||
import draggable from '../../directives/draggable.js';
|
||||
|
||||
|
||||
export default {
|
||||
name: "CalendarTempus",
|
||||
name: 'CalendarTempus',
|
||||
components: {
|
||||
FhcCalendar
|
||||
FhcCalendar,
|
||||
},
|
||||
inject: {
|
||||
renderers: {from: 'renderers'},
|
||||
@@ -23,9 +22,9 @@ export default {
|
||||
appConfig: {
|
||||
from: 'appConfig',
|
||||
default: {
|
||||
visible_status: 'all'
|
||||
}
|
||||
}
|
||||
visible_status: 'all',
|
||||
},
|
||||
},
|
||||
},
|
||||
directives: {
|
||||
draggable,
|
||||
@@ -33,35 +32,35 @@ export default {
|
||||
props: {
|
||||
timezone: {
|
||||
type: String,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
date: {
|
||||
type: [Date, String, Number, luxon.DateTime],
|
||||
default: luxon.DateTime.local()
|
||||
default: luxon.DateTime.local(),
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'Week'
|
||||
default: 'Week',
|
||||
},
|
||||
getPromiseFunc: {
|
||||
type: Function,
|
||||
required: true
|
||||
required: true,
|
||||
},
|
||||
parkedEvents: {
|
||||
type: Object,
|
||||
default: () => new Set()
|
||||
default: () => new Set(),
|
||||
},
|
||||
visibleLecturers: {
|
||||
type: Array,
|
||||
default: null
|
||||
default: null,
|
||||
},
|
||||
extraBackgrounds: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
default: () => [],
|
||||
},
|
||||
visibleStatus: {
|
||||
type: Array,
|
||||
default: () => ['all']
|
||||
default: () => ['all'],
|
||||
},
|
||||
showEvents: {
|
||||
type: Boolean,
|
||||
@@ -77,7 +76,8 @@ export default {
|
||||
"resize",
|
||||
"event-hover",
|
||||
"event-unhover",
|
||||
"open-reservierung"
|
||||
"open-reservierung",
|
||||
"events-reloaded",
|
||||
],
|
||||
|
||||
data() {
|
||||
@@ -90,11 +90,11 @@ export default {
|
||||
modeOptions: {
|
||||
day: {
|
||||
emptyMessage: Vue.computed(() => this.$p.t('lehre/noLvFound')),
|
||||
emptyMessageDetails: Vue.computed(() => this.$p.t('lehre/noLvFound'))
|
||||
emptyMessageDetails: Vue.computed(() => this.$p.t('lehre/noLvFound')),
|
||||
},
|
||||
week: {
|
||||
collapseEmptyDays: false
|
||||
}
|
||||
collapseEmptyDays: false,
|
||||
},
|
||||
},
|
||||
currentMode: this.mode,
|
||||
teachingunits: null,
|
||||
@@ -102,57 +102,62 @@ export default {
|
||||
showRaster: true,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
events() {
|
||||
this.$emit('events-reloaded');
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
backgrounds() {
|
||||
let now = luxon.DateTime.now().setZone(this.timezone);
|
||||
|
||||
let past = [];
|
||||
if (this.mode == 'Month')
|
||||
{
|
||||
past = [{
|
||||
class: 'background-past',
|
||||
end: now.startOf('day')
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
past = [{
|
||||
class: 'background-past',
|
||||
end: now,
|
||||
label: now.startOf('minute').toISOTime({ suppressSeconds: true, includeOffset: false })
|
||||
}];
|
||||
if (this.mode == 'Month') {
|
||||
past = [
|
||||
{
|
||||
class: 'background-past',
|
||||
end: now.startOf('day'),
|
||||
},
|
||||
];
|
||||
} else {
|
||||
past = [
|
||||
{
|
||||
class: 'background-past',
|
||||
end: now,
|
||||
label: now
|
||||
.startOf('minute')
|
||||
.toISOTime({ suppressSeconds: true, includeOffset: false }),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
...past,
|
||||
...(this.extraBackgrounds || [])
|
||||
];
|
||||
return [...past, ...(this.extraBackgrounds || [])];
|
||||
},
|
||||
visibleEvents()
|
||||
{
|
||||
visibleEvents() {
|
||||
let list = this.events;
|
||||
|
||||
if (Array.isArray(this.visibleLecturers))
|
||||
{
|
||||
if (Array.isArray(this.visibleLecturers)) {
|
||||
const visibleLectures = new Set(this.visibleLecturers);
|
||||
|
||||
list = list.filter(event => {
|
||||
if (!event.lektor?.length)
|
||||
return true;
|
||||
return event.lektor.some(lektor => visibleLectures.has(lektor.mitarbeiter_uid));
|
||||
list = list.filter((event) => {
|
||||
if (!event.lektor?.length) return true;
|
||||
return event.lektor.some((lektor) =>
|
||||
visibleLectures.has(lektor.mitarbeiter_uid),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
if (!this.visibleStatus.length || this.visibleStatus.includes('all'))
|
||||
return list;
|
||||
|
||||
return list.filter(event => this.visibleStatus.includes(event.status_kurzbz));
|
||||
return list.filter((event) =>
|
||||
this.visibleStatus.includes(event.status_kurzbz),
|
||||
);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
eventStyle(event) {
|
||||
if (!event.farbe)
|
||||
return undefined;
|
||||
if (!event.farbe) return undefined;
|
||||
return '--event-bg:#' + event.farbe;
|
||||
},
|
||||
updateRange(rangeInterval) {
|
||||
@@ -171,7 +176,7 @@ export default {
|
||||
ondrop(payload){
|
||||
this.$emit('drop', payload);
|
||||
},
|
||||
onresize(payload){
|
||||
onresize(payload) {
|
||||
this.$emit('resize', payload);
|
||||
},
|
||||
resetEventLoader() {
|
||||
@@ -183,13 +188,34 @@ export default {
|
||||
navigateNext() {
|
||||
this.$refs.calendar.clickNext();
|
||||
},
|
||||
clearOutCalendarEventEmphasis() {
|
||||
this.$refs.calendar.$el
|
||||
.querySelectorAll(
|
||||
'.fhc-calendar-base-grid .fhc-calendar-base-grid-line-event',
|
||||
)
|
||||
.forEach((el) => {
|
||||
const spinner = el.querySelector('.spinner-overlay');
|
||||
if (spinner) {
|
||||
spinner.remove();
|
||||
}
|
||||
|
||||
el.classList.remove(
|
||||
'updating-event',
|
||||
'updated-event',
|
||||
'updated-event-long',
|
||||
);
|
||||
});
|
||||
},
|
||||
},
|
||||
setup(props, context) {
|
||||
const rangeInterval = Vue.ref(null);
|
||||
|
||||
const { events, lv, reset } = useEventLoader(rangeInterval, props.getPromiseFunc);
|
||||
const { events, lv, reset } = useEventLoader(
|
||||
rangeInterval,
|
||||
props.getPromiseFunc,
|
||||
);
|
||||
|
||||
Vue.watch(lv, newValue => {
|
||||
Vue.watch(lv, (newValue) => {
|
||||
context.emit('update:lv', newValue);
|
||||
});
|
||||
|
||||
@@ -197,31 +223,27 @@ export default {
|
||||
rangeInterval,
|
||||
events,
|
||||
lv,
|
||||
reset
|
||||
reset,
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$api
|
||||
.call(ApiKalender.getStunden())
|
||||
.then(res => {
|
||||
return this.teachingunits = res.data.map(el => ({
|
||||
id: el.stunde,
|
||||
start: el.beginn,
|
||||
end: el.ende
|
||||
}));
|
||||
});
|
||||
this.$api.call(ApiKalender.getStunden()).then((res) => {
|
||||
return (this.teachingunits = res.data.map((el) => ({
|
||||
id: el.stunde,
|
||||
start: el.beginn,
|
||||
end: el.ende,
|
||||
})));
|
||||
});
|
||||
|
||||
this.$api
|
||||
.call(ApiKalender.getCalendarHours())
|
||||
.then(res => {
|
||||
this.hoursplan = {
|
||||
start: res.data.start,
|
||||
end: res.data.end
|
||||
};
|
||||
});
|
||||
this.$api.call(ApiKalender.getCalendarHours()).then((res) => {
|
||||
this.hoursplan = {
|
||||
start: res.data.start,
|
||||
end: res.data.end,
|
||||
};
|
||||
});
|
||||
},
|
||||
template: /* html */`
|
||||
template: /* html */ `
|
||||
<fhc-calendar
|
||||
ref="calendar"
|
||||
class="fhc-calendar-lvplan"
|
||||
|
||||
@@ -136,6 +136,7 @@ export default {
|
||||
showEvents: true,
|
||||
reservierungPending: false,
|
||||
bcc: null,
|
||||
currentlyUpdatedEvent: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -456,25 +457,34 @@ export default {
|
||||
if (hasLektoren)
|
||||
filter.uid = this.lecturers.map((lecture) => lecture.uid);
|
||||
|
||||
let response = null;
|
||||
if (this.previewRole === 'lektor')
|
||||
return [
|
||||
response = [
|
||||
this.$api.call(
|
||||
ApiKalender.getPlanLecturer(start.toISODate(), end.toISODate()),
|
||||
),
|
||||
];
|
||||
|
||||
if (this.previewRole === 'student')
|
||||
return [
|
||||
response = [
|
||||
this.$api.call(
|
||||
ApiKalender.getPlanStudent(start.toISODate(), end.toISODate()),
|
||||
),
|
||||
];
|
||||
|
||||
return [
|
||||
response = [
|
||||
this.$api.call(
|
||||
ApiKalender.getPlan(filter, start.toISODate(), end.toISODate()),
|
||||
),
|
||||
];
|
||||
|
||||
if (response) {
|
||||
response[0].then((result) => {
|
||||
this.scrollToAndEmphasizeUpdatedEvent();
|
||||
});
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
_parseDates(start, end) {
|
||||
const startDT = luxon.DateTime.fromISO(start);
|
||||
@@ -516,7 +526,11 @@ export default {
|
||||
ApiKalender.updateKalenderEvent(obj.orig.kalender_id, updatedInfos),
|
||||
)
|
||||
.then(() => {
|
||||
if (onSuccess) onSuccess();
|
||||
if (onSuccess) {
|
||||
onSuccess();
|
||||
this.$refs.calendar.$refs.calendar.$refs.mode.$refs.view.$refs.grid.disableAutoScroll();
|
||||
this.currentlyUpdatedEvent = obj.orig;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
@@ -527,12 +541,26 @@ export default {
|
||||
const { item, start, end } = payload;
|
||||
const obj = item[0];
|
||||
if (!obj?.orig?.kalender_id)
|
||||
return alert('Kein gültiges Kalender-Event zum Resizen');
|
||||
return;
|
||||
|
||||
const dates = this._parseDates(start, end);
|
||||
|
||||
if (!dates) return;
|
||||
|
||||
if (
|
||||
luxon.DateTime.fromISO(obj.orig.isostart).toMillis() ===
|
||||
dates.startDT.toMillis() &&
|
||||
luxon.DateTime.fromISO(obj.orig.isoend).toMillis() ===
|
||||
dates.endDT.toMillis()
|
||||
)
|
||||
return;
|
||||
|
||||
this.updateKalenderEventElementDisplay(
|
||||
obj.orig.eindeutige_kalender_gruppen_id,
|
||||
dates.startDT,
|
||||
dates.endDT,
|
||||
);
|
||||
|
||||
return this._updateKalenderEvent(
|
||||
obj,
|
||||
dates.startDT,
|
||||
@@ -581,8 +609,22 @@ export default {
|
||||
const dates = this._parseDates(start, end);
|
||||
if (!dates) return;
|
||||
|
||||
if (
|
||||
luxon.DateTime.fromISO(obj.orig.isostart).toMillis() ===
|
||||
dates.startDT.toMillis() &&
|
||||
luxon.DateTime.fromISO(obj.orig.isoend).toMillis() ===
|
||||
dates.endDT.toMillis()
|
||||
)
|
||||
return;
|
||||
|
||||
const { startDT, endDT, start_time, end_time } = dates;
|
||||
|
||||
this.updateKalenderEventElementDisplay(
|
||||
obj.orig.eindeutige_kalender_gruppen_id,
|
||||
startDT,
|
||||
endDT,
|
||||
);
|
||||
|
||||
if (obj.type === 'reservierung') {
|
||||
this.reservierungPending = true;
|
||||
this.$refs.reservierung.show(start_time, end_time);
|
||||
@@ -872,6 +914,148 @@ export default {
|
||||
focusSearchbar() {
|
||||
this.$refs.header?.focusSearchbar();
|
||||
},
|
||||
scrollToAndEmphasizeUpdatedEvent() {
|
||||
if (!this.currentlyUpdatedEvent) return;
|
||||
|
||||
document
|
||||
.querySelectorAll(
|
||||
'.fhc-calendar-base-grid .fhc-calendar-base-grid-line-event',
|
||||
)
|
||||
.forEach((el) => {
|
||||
const spinner = el.querySelector('.spinner-overlay');
|
||||
if (spinner) {
|
||||
spinner.remove();
|
||||
}
|
||||
|
||||
el.classList.remove(
|
||||
'updating-event',
|
||||
'updated-event',
|
||||
'updated-event-long',
|
||||
);
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
const eventEl = document.querySelector(
|
||||
`[data-group-id="event-group-${this.currentlyUpdatedEvent.eindeutige_kalender_gruppen_id}"]`,
|
||||
);
|
||||
if (!eventEl) return;
|
||||
|
||||
const calendar = document.querySelector('.fhc-calendar-base-grid');
|
||||
const eventRect = eventEl.getBoundingClientRect();
|
||||
|
||||
const offset = 300;
|
||||
|
||||
const isInsideScrolledView =
|
||||
eventEl.offsetLeft < calendar.scrollLeft + calendar.clientWidth &&
|
||||
eventEl.offsetLeft + eventEl.offsetWidth > calendar.scrollLeft &&
|
||||
eventEl.offsetTop < calendar.scrollTop + calendar.clientHeight &&
|
||||
eventEl.offsetTop + eventEl.offsetHeight > calendar.scrollTop;
|
||||
|
||||
const rect = eventEl.getBoundingClientRect();
|
||||
if (!isInsideScrolledView) {
|
||||
eventEl.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
inline: 'center',
|
||||
block: 'nearest',
|
||||
});
|
||||
}
|
||||
|
||||
let timeout = 0;
|
||||
let emphasizeUpdateClassName = isInsideScrolledView
|
||||
? 'updated-event'
|
||||
: 'updated-event-long';
|
||||
|
||||
if (!isInsideScrolledView) timeout = 300;
|
||||
|
||||
setTimeout(() => {
|
||||
eventEl.classList.add(emphasizeUpdateClassName);
|
||||
}, timeout);
|
||||
|
||||
this.currentlyUpdatedEvent = null;
|
||||
}, 100);
|
||||
},
|
||||
updateKalenderEventElementDisplay(calendarGruppenId, startDT, endDT) {
|
||||
if (!calendarGruppenId)
|
||||
return;
|
||||
|
||||
let startOfDay = startDT.startOf('day');
|
||||
let newPotentialStart = startDT.diff(startOfDay).toMillis() ?? 1;
|
||||
let newPotentialEnd = endDT.diff(startOfDay).toMillis();
|
||||
|
||||
const calendar = this.$refs.calendar?.$el;
|
||||
let element = calendar?.querySelector(
|
||||
`[data-group-id="event-group-${calendarGruppenId}"]`,
|
||||
);
|
||||
if (!element) return;
|
||||
|
||||
const targetGridLine = [...calendar.querySelectorAll(
|
||||
'.fhc-calendar-base-grid-line',
|
||||
)].find((gridLine) => {
|
||||
const [rowStart, columnStart, rowEnd] = getComputedStyle(
|
||||
gridLine,
|
||||
).gridArea.split(' / ');
|
||||
|
||||
return (
|
||||
rowStart === '1' &&
|
||||
columnStart === String(startDT.weekday) &&
|
||||
rowEnd === '-1'
|
||||
);
|
||||
});
|
||||
const changedDay =
|
||||
targetGridLine && element.parentElement !== targetGridLine;
|
||||
|
||||
setTimeout(() => {
|
||||
if (!calendar.contains(element)) return;
|
||||
|
||||
|
||||
if (changedDay) {
|
||||
targetGridLine.insertBefore(element, null);
|
||||
element.classList.add('tempus-temporary-calendar-event');
|
||||
}
|
||||
element.style.gridRowEnd = 't_' + newPotentialEnd;
|
||||
element.style.gridRowStart = 't_' + newPotentialStart;
|
||||
}, 100);
|
||||
|
||||
const outerDiv = document.createElement('div');
|
||||
outerDiv.className = 'spinner-overlay';
|
||||
|
||||
const innerDiv = document.createElement('div');
|
||||
innerDiv.className = 'spinner';
|
||||
|
||||
outerDiv.appendChild(innerDiv);
|
||||
|
||||
element.appendChild(outerDiv);
|
||||
|
||||
const eventRect = element.getBoundingClientRect();
|
||||
|
||||
const offset = 300;
|
||||
|
||||
const isInsideScrolledView =
|
||||
element.offsetLeft < calendar.scrollLeft + calendar.clientWidth &&
|
||||
element.offsetLeft + element.offsetWidth > calendar.scrollLeft &&
|
||||
element.offsetTop < calendar.scrollTop + calendar.clientHeight &&
|
||||
element.offsetTop + element.offsetHeight > calendar.scrollTop;
|
||||
|
||||
const rect = element.getBoundingClientRect();
|
||||
if (!isInsideScrolledView) {
|
||||
element.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
inline: 'center',
|
||||
block: 'nearest',
|
||||
});
|
||||
}
|
||||
},
|
||||
clearTemporaryEvents() {
|
||||
const calendar = this.$refs.calendar?.$el;
|
||||
if (!calendar) return;
|
||||
|
||||
const tempEvents = calendar.querySelectorAll(
|
||||
'.tempus-temporary-calendar-event',
|
||||
);
|
||||
tempEvents.forEach((event) => {
|
||||
event.remove();
|
||||
});
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
lecturers: {
|
||||
@@ -1021,6 +1205,7 @@ export default {
|
||||
@open-reservierung="openReservierung"
|
||||
:extra-backgrounds="extraBackgrounds"
|
||||
@update:range="handleRange"
|
||||
@events-reloaded="clearTemporaryEvents"
|
||||
class="responsive-calendar"
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1,17 +1,28 @@
|
||||
// TODO(chris): load events that are longer than the interval without doubling it
|
||||
|
||||
export function useEventLoader(rangeInterval, getPromiseFunc) {
|
||||
export function useEventLoader(
|
||||
rangeInterval,
|
||||
getPromiseFunc,
|
||||
isLoaderVisible = true,
|
||||
isLoaderInitiallyVisible = true,
|
||||
) {
|
||||
let hasFirstLoadOccurred = false;
|
||||
let loading_id = 0;
|
||||
|
||||
let tempEventsHolder = [];
|
||||
let rangeIntervalHolder = null;
|
||||
|
||||
const events = Vue.ref([]);
|
||||
const loadingEvents = Vue.ref([]);
|
||||
const allEvents = Vue.computed(() => events.value.concat(loadingEvents.value));
|
||||
const allEvents = Vue.computed(() =>
|
||||
events.value.concat(loadingEvents.value),
|
||||
);
|
||||
const lv = Vue.ref(null);
|
||||
const eventsLoaded = [];
|
||||
|
||||
const mergePromiseArr = (n, o) => {
|
||||
if (Array.isArray(n))
|
||||
return o.concat(n);
|
||||
return o.push(n), o;
|
||||
if (Array.isArray(n)) return o.concat(n);
|
||||
return (o.push(n), o);
|
||||
};
|
||||
|
||||
const markEventsLoaded = (start, end) => {
|
||||
@@ -20,10 +31,10 @@ export function useEventLoader(rangeInterval, getPromiseFunc) {
|
||||
// empty: add new chunk
|
||||
eventsLoaded.push(start.ts, end.ts);
|
||||
} else {
|
||||
if (eventsLoaded[eventsLoaded.length-1] + 1 == start.ts) {
|
||||
if (eventsLoaded[eventsLoaded.length - 1] + 1 == start.ts) {
|
||||
// add to the end of last chunk
|
||||
eventsLoaded[eventsLoaded.length-1] = end.ts;
|
||||
} else if (eventsLoaded[eventsLoaded.length-1] < start.ts) {
|
||||
eventsLoaded[eventsLoaded.length - 1] = end.ts;
|
||||
} else if (eventsLoaded[eventsLoaded.length - 1] < start.ts) {
|
||||
// add new chunk after the last chunk
|
||||
eventsLoaded.push(start.ts, end.ts);
|
||||
} else if (eventsLoaded[0] == end.ts + 1) {
|
||||
@@ -32,14 +43,13 @@ export function useEventLoader(rangeInterval, getPromiseFunc) {
|
||||
} else if (eventsLoaded[0] > end.ts) {
|
||||
eventsLoaded.unshift(start.ts, end.ts);
|
||||
} else {
|
||||
let index = eventsLoaded.findIndex(e => e >= start.ts);
|
||||
let index = eventsLoaded.findIndex((e) => e >= start.ts);
|
||||
|
||||
if (index % 2) {
|
||||
// starts inside an existing chunk
|
||||
if (eventsLoaded[index] >= end.ts)
|
||||
return []; // Already loaded
|
||||
if (eventsLoaded[index] >= end.ts) return []; // Already loaded
|
||||
|
||||
let indexIsLast = (index == eventsLoaded.length - 1);
|
||||
let indexIsLast = index == eventsLoaded.length - 1;
|
||||
|
||||
if (indexIsLast || eventsLoaded[index + 1] > end.ts) {
|
||||
// extend an existing chunk
|
||||
@@ -48,14 +58,16 @@ export function useEventLoader(rangeInterval, getPromiseFunc) {
|
||||
start = start.plus(nStart - start.ts);
|
||||
if (!indexIsLast && eventsLoaded[index + 1] == end.ts + 1)
|
||||
eventsLoaded.splice(index, 2);
|
||||
else
|
||||
eventsLoaded[index] = end.ts;
|
||||
else eventsLoaded[index] = end.ts;
|
||||
} else {
|
||||
// merge exising chunks
|
||||
// and load the rest if necessary
|
||||
if (eventsLoaded[index + 2] < end.ts) {
|
||||
let rStart = eventsLoaded[index + 2] + 1;
|
||||
result = mergePromiseArr(markEventsLoaded(start.plus(rStart - start.ts), end), result);
|
||||
result = mergePromiseArr(
|
||||
markEventsLoaded(start.plus(rStart - start.ts), end),
|
||||
result,
|
||||
);
|
||||
}
|
||||
|
||||
let nStart = eventsLoaded[index] + 1;
|
||||
@@ -71,24 +83,32 @@ export function useEventLoader(rangeInterval, getPromiseFunc) {
|
||||
// and load the rest if necessary
|
||||
if (eventsLoaded[1] < end.ts) {
|
||||
let rStart = eventsLoaded[1] + 1;
|
||||
result = mergePromiseArr(markEventsLoaded(start.plus(rStart - start.ts), end), result);
|
||||
result = mergePromiseArr(
|
||||
markEventsLoaded(start.plus(rStart - start.ts), end),
|
||||
result,
|
||||
);
|
||||
}
|
||||
let nEnd = eventsLoaded[0] - 1;
|
||||
end = end.plus(nEnd - end.ts);
|
||||
eventsLoaded[0] = start.ts;
|
||||
} else if (eventsLoaded[index] == start.ts) {
|
||||
// starts at the same position as an existing chunk
|
||||
if (eventsLoaded[index + 1] >= end.ts)
|
||||
return []; // Already loaded
|
||||
if (eventsLoaded[index + 1] >= end.ts) return []; // Already loaded
|
||||
// load the rest
|
||||
let rStart = eventsLoaded[index + 1] + 1;
|
||||
result = mergePromiseArr(markEventsLoaded(start.plus(rStart - start.ts), end), result);
|
||||
result = mergePromiseArr(
|
||||
markEventsLoaded(start.plus(rStart - start.ts), end),
|
||||
result,
|
||||
);
|
||||
} else {
|
||||
// extend an existing chunk
|
||||
// and load the rest if necessary
|
||||
if (eventsLoaded[index + 1] < end.ts) {
|
||||
let rStart = eventsLoaded[index + 1] + 1;
|
||||
result = mergePromiseArr(markEventsLoaded(start.plus(rStart - start.ts), end), result);
|
||||
result = mergePromiseArr(
|
||||
markEventsLoaded(start.plus(rStart - start.ts), end),
|
||||
result,
|
||||
);
|
||||
}
|
||||
let nEnd = eventsLoaded[index] - 1;
|
||||
end = end.plus(nEnd - end.ts);
|
||||
@@ -98,52 +118,57 @@ export function useEventLoader(rangeInterval, getPromiseFunc) {
|
||||
}
|
||||
}
|
||||
|
||||
if (start.ts >= end.ts)
|
||||
return result;
|
||||
if (start.ts >= end.ts) return result;
|
||||
|
||||
loadingEvents.value.push({
|
||||
loading_id: loading_id++,
|
||||
type: "loading",
|
||||
isostart: start.toISODate() + 'T' + start.toISOTime(),
|
||||
isoend: end.toISODate() + 'T' + end.toISOTime()
|
||||
});
|
||||
if (isLoaderVisible && !hasFirstLoadOccurred && isLoaderInitiallyVisible) {
|
||||
loadingEvents.value.push({
|
||||
loading_id: loading_id++,
|
||||
type: 'loading',
|
||||
isostart: start.toISODate() + 'T' + start.toISOTime(),
|
||||
isoend: end.toISODate() + 'T' + end.toISOTime(),
|
||||
});
|
||||
}
|
||||
|
||||
return mergePromiseArr(getPromiseFunc(start, end), result);
|
||||
};
|
||||
|
||||
const reload = () => {
|
||||
const range = Vue.toValue(rangeInterval);
|
||||
if (!(range instanceof luxon.Interval))
|
||||
return;
|
||||
const promises = markEventsLoaded(range.start, range.end);
|
||||
Promise
|
||||
.allSettled(promises)
|
||||
.then(results => {
|
||||
results.forEach(res => {
|
||||
if (
|
||||
res.status === 'fulfilled'
|
||||
&& res.value.meta.status === "success"
|
||||
) {
|
||||
if (res.value.meta.lv)
|
||||
lv.value = res.value.meta.lv;
|
||||
if (!(range instanceof luxon.Interval)) return;
|
||||
|
||||
events.value = events.value.concat(res.value.data);
|
||||
loadingEvents.value = [];
|
||||
}
|
||||
})
|
||||
if (!rangeIntervalHolder || !range.equals(rangeIntervalHolder)) {
|
||||
hasFirstLoadOccurred = false;
|
||||
rangeIntervalHolder = range;
|
||||
}
|
||||
|
||||
const promises = markEventsLoaded(range.start, range.end);
|
||||
|
||||
Promise.allSettled(promises).then((results) => {
|
||||
results.forEach((res) => {
|
||||
if (res.status === 'fulfilled' && res.value.meta.status === 'success') {
|
||||
if (res.value.meta.lv) lv.value = res.value.meta.lv;
|
||||
|
||||
tempEventsHolder = tempEventsHolder.concat(res.value.data);
|
||||
loadingEvents.value = [];
|
||||
}
|
||||
});
|
||||
|
||||
events.value = tempEventsHolder;
|
||||
});
|
||||
|
||||
hasFirstLoadOccurred = true;
|
||||
};
|
||||
|
||||
Vue.watchEffect(reload);
|
||||
|
||||
const reset = () => {
|
||||
loading_id = 0;
|
||||
events.value = [];
|
||||
loadingEvents.value = [];
|
||||
tempEventsHolder = [];
|
||||
//loadingEvents.value = [];
|
||||
eventsLoaded.splice(0, eventsLoaded.length);
|
||||
|
||||
reload();
|
||||
}
|
||||
};
|
||||
|
||||
return { events: allEvents, lv, reset }
|
||||
}
|
||||
return { events: allEvents, lv, reset };
|
||||
}
|
||||
|
||||
@@ -99,6 +99,8 @@ 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');
|
||||
require_once('dbupdate_3.4/78052_tempus_tag_events.php');
|
||||
require_once('dbupdate_3.4/78318_rename_column_of_eindeutige_gruppen_id_to_eindeutige_kalender_gruppen_id_in_tbl_kalender.php');
|
||||
require_once('dbupdate_3.4/78318_rename_column_of_eindeutige_gruppen_id_to_eindeutige_kalender_gruppen_id_in_tbl_kalender.php');
|
||||
require_once('dbupdate_3.4/75959_StudVw_Automatische_Tags.php');
|
||||
require_once('dbupdate_3.4/76160_lvv_favorites.php');
|
||||
@@ -106,8 +108,8 @@ require_once('dbupdate_3.4/77080_tabulator_presets_table.php');
|
||||
require_once('dbupdate_3.4/78292_gehaltsanpassungtyp.php');
|
||||
require_once('dbupdate_3.4/77949_tempus_synchronisation.php');
|
||||
require_once('dbupdate_3.4/78287_tempus_raumzuordnung.php');
|
||||
|
||||
require_once('dbupdate_3.4/78285_tempus_stundenraster.php');
|
||||
require_once('dbupdate_3.4/83437_kalender_notiz_tbl.php');
|
||||
|
||||
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
|
||||
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
if (! defined('DB_NAME')) exit('No direct script access allowed');
|
||||
|
||||
$result = $db->db_query("SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'tbl_notizzuordnung'
|
||||
AND column_name = 'eindeutige_kalender_gruppen_id'");
|
||||
|
||||
if ($db->db_num_rows($result) === 0)
|
||||
{
|
||||
$qry = "ALTER TABLE public.tbl_notizzuordnung
|
||||
ADD COLUMN eindeutige_kalender_gruppen_id UUID NULL DEFAULT NULL";
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>public.tbl_notizzuordnung: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>public.tbl_notizzuordnung: eindeutige_kalender_gruppen_id column added';
|
||||
}
|
||||
@@ -1,279 +0,0 @@
|
||||
<?php
|
||||
if (! defined('DB_NAME')) exit('No direct script access allowed');
|
||||
|
||||
if (!$result = @$db->db_query('SELECT 0 FROM lehre.tbl_kalender_notiz WHERE 0 = 1'))
|
||||
{
|
||||
//TODO zuordnung typ definieren
|
||||
$qry = 'CREATE TABLE lehre.tbl_kalender_notiz (
|
||||
eindeutige_kalender_gruppen_id UUID NOT NULL,
|
||||
notiz_id integer NOT NULL,
|
||||
|
||||
CONSTRAINT tbl_kalender_notiz_pk PRIMARY KEY (eindeutige_kalender_gruppen_id, notiz_id),
|
||||
CONSTRAINT tbl_kalender_notiz_notiz_fk FOREIGN KEY (notiz_id)
|
||||
REFERENCES public.tbl_notiz (notiz_id)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);';
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_kalender_notiz: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>lehre.tbl_kalender_notiz table created';
|
||||
|
||||
$qry = 'GRANT SELECT ON TABLE lehre.tbl_kalender_notiz TO web;';
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_kalender_notiz: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>Granted privileges to <strong>web</strong> on lehre.tbl_kalender_notiz';
|
||||
|
||||
$qry = 'GRANT SELECT, UPDATE, INSERT, DELETE ON TABLE lehre.tbl_kalender_notiz TO vilesci;';
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_kalender_notiz: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>Granted privileges to <strong>vilesci</strong> on lehre.tbl_kalender_notiz';
|
||||
|
||||
// Delete the related note when its calendar-note assignment no longer exists.
|
||||
$result = $db->db_query("SELECT 1
|
||||
FROM pg_catalog.pg_proc AS p
|
||||
JOIN pg_catalog.pg_namespace AS n ON n.oid = p.pronamespace
|
||||
WHERE n.nspname = 'lehre'
|
||||
AND p.proname = 'cleanup_notiz_on_kalender_notiz_delete'
|
||||
AND p.proargtypes = ''::oidvector");
|
||||
|
||||
if ($db->db_num_rows($result) === 0)
|
||||
{
|
||||
$qry = 'CREATE FUNCTION lehre.cleanup_notiz_on_kalender_notiz_delete()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
SET search_path = pg_catalog
|
||||
AS $function$
|
||||
BEGIN
|
||||
DELETE FROM public.tbl_notiz
|
||||
WHERE notiz_id = OLD.notiz_id
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender_notiz
|
||||
WHERE eindeutige_kalender_gruppen_id = OLD.eindeutige_kalender_gruppen_id
|
||||
AND notiz_id = OLD.notiz_id
|
||||
);
|
||||
|
||||
RETURN OLD;
|
||||
END;
|
||||
$function$;';
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_notiz cleanup function: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>lehre.tbl_notiz cleanup function created';
|
||||
}
|
||||
|
||||
$qry = 'CREATE TRIGGER cleanup_notiz_on_kalender_notiz_delete
|
||||
AFTER DELETE ON lehre.tbl_kalender_notiz
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE lehre.cleanup_notiz_on_kalender_notiz_delete();';
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_notiz cleanup trigger: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>lehre.tbl_notiz cleanup trigger created';
|
||||
}
|
||||
|
||||
// Delete note assignments after a physical delete or when every row in the
|
||||
// calendar group has an inactive status.
|
||||
$result = $db->db_query("SELECT 1
|
||||
FROM pg_catalog.pg_proc AS p
|
||||
JOIN pg_catalog.pg_namespace AS n ON n.oid = p.pronamespace
|
||||
WHERE n.nspname = 'lehre'
|
||||
AND p.proname = 'cleanup_kalender_notiz'
|
||||
AND p.proargtypes = ''::oidvector");
|
||||
|
||||
if ($db->db_num_rows($result) === 0)
|
||||
{
|
||||
$qry = 'CREATE FUNCTION lehre.cleanup_kalender_notiz()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
SET search_path = pg_catalog
|
||||
AS $function$
|
||||
DECLARE
|
||||
gruppen_id UUID;
|
||||
BEGIN
|
||||
IF TG_OP = \'DELETE\' THEN
|
||||
gruppen_id := OLD.eindeutige_kalender_gruppen_id;
|
||||
ELSIF TG_OP = \'UPDATE\' THEN
|
||||
IF (NEW.status_kurzbz IS DISTINCT FROM \'deleted\'
|
||||
AND NEW.status_kurzbz IS DISTINCT FROM \'archived\')
|
||||
OR OLD.status_kurzbz IS NOT DISTINCT FROM NEW.status_kurzbz
|
||||
THEN
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
|
||||
gruppen_id := NEW.eindeutige_kalender_gruppen_id;
|
||||
ELSE
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender
|
||||
WHERE eindeutige_kalender_gruppen_id = gruppen_id
|
||||
AND status_kurzbz IS DISTINCT FROM \'deleted\'
|
||||
AND status_kurzbz IS DISTINCT FROM \'archived\'
|
||||
)
|
||||
THEN
|
||||
DELETE FROM lehre.tbl_kalender_notiz
|
||||
WHERE eindeutige_kalender_gruppen_id = gruppen_id;
|
||||
END IF;
|
||||
|
||||
IF TG_OP = \'DELETE\' THEN
|
||||
RETURN OLD;
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$function$;';
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_kalender_notiz cleanup function: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>lehre.tbl_kalender_notiz cleanup function created';
|
||||
}
|
||||
|
||||
$result = $db->db_query("SELECT 1
|
||||
FROM pg_catalog.pg_trigger AS t
|
||||
JOIN pg_catalog.pg_class AS c ON c.oid = t.tgrelid
|
||||
JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
|
||||
WHERE n.nspname = 'lehre'
|
||||
AND c.relname = 'tbl_kalender'
|
||||
AND t.tgname = 'cleanup_kalender_notiz'
|
||||
AND NOT t.tgisinternal");
|
||||
|
||||
if ($db->db_num_rows($result) === 0)
|
||||
{
|
||||
$qry = 'CREATE TRIGGER cleanup_kalender_notiz
|
||||
AFTER DELETE OR UPDATE OF status_kurzbz ON lehre.tbl_kalender
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE lehre.cleanup_kalender_notiz();';
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_kalender_notiz cleanup trigger: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>lehre.tbl_kalender_notiz cleanup trigger created';
|
||||
}
|
||||
|
||||
// Delete resource assignments after a physical delete or when every row in the
|
||||
// calendar group has an inactive status.
|
||||
$result = $db->db_query("SELECT 1
|
||||
FROM pg_catalog.pg_proc AS p
|
||||
JOIN pg_catalog.pg_namespace AS n ON n.oid = p.pronamespace
|
||||
WHERE n.nspname = 'lehre'
|
||||
AND p.proname = 'cleanup_betriebsmittel_kalender'
|
||||
AND p.proargtypes = ''::oidvector");
|
||||
|
||||
if ($db->db_num_rows($result) === 0)
|
||||
{
|
||||
$qry = 'CREATE FUNCTION lehre.cleanup_betriebsmittel_kalender()
|
||||
RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
SECURITY DEFINER
|
||||
SET search_path = pg_catalog
|
||||
AS $function$
|
||||
DECLARE
|
||||
gruppen_id UUID;
|
||||
BEGIN
|
||||
IF TG_OP = \'DELETE\' THEN
|
||||
gruppen_id := OLD.eindeutige_kalender_gruppen_id;
|
||||
ELSIF TG_OP = \'UPDATE\' THEN
|
||||
IF (NEW.status_kurzbz IS DISTINCT FROM \'deleted\'
|
||||
AND NEW.status_kurzbz IS DISTINCT FROM \'archived\')
|
||||
OR OLD.status_kurzbz IS NOT DISTINCT FROM NEW.status_kurzbz
|
||||
THEN
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
|
||||
gruppen_id := NEW.eindeutige_kalender_gruppen_id;
|
||||
ELSE
|
||||
RETURN NULL;
|
||||
END IF;
|
||||
|
||||
IF NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM lehre.tbl_kalender
|
||||
WHERE eindeutige_kalender_gruppen_id = gruppen_id
|
||||
AND status_kurzbz IS DISTINCT FROM \'deleted\'
|
||||
AND status_kurzbz IS DISTINCT FROM \'archived\'
|
||||
)
|
||||
THEN
|
||||
DELETE FROM lehre.tbl_betriebsmittel_kalender
|
||||
WHERE eindeutige_kalender_gruppen_id = gruppen_id;
|
||||
END IF;
|
||||
|
||||
IF TG_OP = \'DELETE\' THEN
|
||||
RETURN OLD;
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$function$;';
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_betriebsmittel_kalender cleanup function: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>lehre.tbl_betriebsmittel_kalender cleanup function created';
|
||||
}
|
||||
|
||||
$result = $db->db_query("SELECT 1
|
||||
FROM pg_catalog.pg_trigger AS t
|
||||
JOIN pg_catalog.pg_class AS c ON c.oid = t.tgrelid
|
||||
JOIN pg_catalog.pg_namespace AS n ON n.oid = c.relnamespace
|
||||
WHERE n.nspname = 'lehre'
|
||||
AND c.relname = 'tbl_kalender'
|
||||
AND t.tgname = 'cleanup_betriebsmittel_kalender'
|
||||
AND NOT t.tgisinternal");
|
||||
|
||||
if ($db->db_num_rows($result) === 0)
|
||||
{
|
||||
$qry = 'CREATE TRIGGER cleanup_betriebsmittel_kalender
|
||||
AFTER DELETE OR UPDATE OF status_kurzbz ON lehre.tbl_kalender
|
||||
FOR EACH ROW
|
||||
EXECUTE PROCEDURE lehre.cleanup_betriebsmittel_kalender();';
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>lehre.tbl_betriebsmittel_kalender cleanup trigger: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>lehre.tbl_betriebsmittel_kalender cleanup trigger created';
|
||||
}
|
||||
|
||||
$result = $db->db_query("SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'tbl_notizzuordnung'
|
||||
AND column_name = 'eindeutige_kalender_gruppen_id'");
|
||||
|
||||
if ($db->db_num_rows($result) === 1)
|
||||
{
|
||||
$qry = "ALTER TABLE public.tbl_notizzuordnung
|
||||
DROP COLUMN eindeutige_kalender_gruppen_id";
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>public.tbl_notizzuordnung: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>public.tbl_notizzuordnung: eindeutige_kalender_gruppen_id column removed';
|
||||
}
|
||||
|
||||
$result = $db->db_query("SELECT 1
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = 'public'
|
||||
AND table_name = 'tbl_notizzuordnung'
|
||||
AND column_name = 'eindeutige_gruppen_id'");
|
||||
|
||||
if ($db->db_num_rows($result) === 1)
|
||||
{
|
||||
$qry = "ALTER TABLE public.tbl_notizzuordnung
|
||||
DROP COLUMN eindeutige_gruppen_id";
|
||||
|
||||
if (!$db->db_query($qry))
|
||||
echo '<strong>public.tbl_notizzuordnung: '.$db->db_last_error().'</strong><br>';
|
||||
else
|
||||
echo '<br>public.tbl_notizzuordnung: eindeutige_gruppen_id column removed';
|
||||
}
|
||||
@@ -31,6 +31,6 @@ class myauth extends \Sabre\DAV\Auth\Backend\AbstractBasic
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user