Compare commits

..

20 Commits

Author SHA1 Message Date
ma0068 b217681ee5 use model-type for interessenten anlegen, listNew 2026-07-14 15:23:06 +02:00
ma0068 7841a73fc0 prepare field bewerbung_abgeschicktamum for showing in frontend (datestamp in database) and add also model-type to datepicker 2026-07-14 15:05:54 +02:00
ma0068 2064008f9e add model-type to fields Betriebsmittel/ausgegebenam, Betriebsmittel/retouram, Funktionen/datumvon und Funktionen/datumbis 2026-07-14 14:31:13 +02:00
ma0068 19b9906c86 Aufnahmetermine: use model-type isodate for field anmeldedatum 2026-07-14 14:23:37 +02:00
ma0068 2c3913a763 Mobility: use model-type isodate for fields von and bis 2026-07-14 14:19:25 +02:00
ma0068 9111edf442 Dokumente: use model-type isodate for field nachgereicht_am 2026-07-14 14:06:59 +02:00
ma0068 b1c47da3c3 use model-type isodate for fields in StatusModal datum and bestaetigtam 2026-07-14 14:01:12 +02:00
ma0068 67eb238876 use model-type isodate for field Details Gebdatum 2026-07-14 13:37:19 +02:00
Harald Bamberger a139cc8d2e initialize with luxon date iso format 2026-07-14 13:24:04 +02:00
Harald Bamberger 35ecbdefa8 studvw prestudent ZGV date fields and konto date fields use iso date as model-type 2026-07-14 13:17:27 +02:00
Harald Bamberger 5f0b1ace51 Merge branch 'epic/LV-Evaluierung_STG-KF-Datenaggregation' 2026-07-14 07:33:24 +02:00
Harald Bamberger b891d8baa5 Merge branch 'master' into epic/LV-Evaluierung_STG-KF-Datenaggregation 2026-07-13 18:01:35 +02:00
Cristina 5dbcf9ce70 Added sancho_header_lvevaluierung_rollout.jpg and sancho_footer_lvevaluierung_rollout.jpg 2026-07-13 17:31:34 +02:00
adisposkofh c26db6cc40 minor fix to tabulator localized columns parsing 2026-07-09 11:44:04 +02:00
Cristina 8548b93ddc Added method getPreviousSameSemesterFrom in Studiensemester_model.php
Method returns the current study semester and the previous semesters of the same type (SS/WS).
2026-07-08 18:57:31 +02:00
Cristina bdc4782e9d Merge branch 'master' into epic/LV-Evaluierung_STG-KF-Datenaggregation 2026-07-08 18:54:02 +02:00
Cristina 0583990870 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-07-08 18:53:37 +02:00
Cristina 335753be8c Adapted Lvevaluierung Mail texte "Evaluierungszeitfenster" instead of "Evaluationszeitraum" 2026-07-06 12:19:28 +02:00
Cristina 8862f050e8 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-06-09 10:37:53 +02:00
Cristina 29f9b226ab Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-05-12 17:08:53 +02:00
22 changed files with 92 additions and 738 deletions
@@ -1,196 +0,0 @@
<?php
/* Copyright (C) 2024 fhcomplete.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
*/
if (!defined("BASEPATH")) exit("No direct script access allowed");
class Modulgrafik extends JOB_Controller
{
const DEFAULT_XOFFSET = 40;
const DEFAULT_YOFFSET = 30;
const DEFAULT_WIDTH = 160;
const DEFAULT_SEMESTER_LABEL_WIDTH = 80;
const DEFAULT_ECTS_WIDTH = 40;
const DEFAULT_HEIGHT = 50;
const DEFAULT_SPACING = 40;
const DEFAULT_FONTSIZE = 8;
protected $curx;
protected $cury;
public function __construct()
{
parent::__construct();
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$this->load->model('CL/Drawio_model', 'DrawioModel');
$this->load->library('DocsboxLib', null, 'DocsboxLib');
}
public function drawModulGrafik($studienplan_id)
{
$sql = <<<EOSQL
SELECT
sl.studienplan_lehrveranstaltung_id,
sl.lehrveranstaltung_id,
sl.studienplan_lehrveranstaltung_id_parent,
COALESCE(sl.studienplan_lehrveranstaltung_id_parent, sl.studienplan_lehrveranstaltung_id) AS lvgrp,
sl.semester,
lv.bezeichnung,
lv.ects,
lv.lehrtyp_kurzbz
FROM
lehre.tbl_studienplan_lehrveranstaltung sl
JOIN
lehre.tbl_lehrveranstaltung lv USING(lehrveranstaltung_id)
WHERE
sl.studienplan_id = {$studienplan_id}
AND
ects > '0.00'
ORDER BY
sl.semester ASC,
lvgrp ASC,
lv.lehrtyp_kurzbz DESC
EOSQL;
$result = $this->StudienplanModel->execReadOnlyQuery($sql);
$lvs = getData($result);
$errors = array();
$assoclvs = array();
$semester = array();
if($lvs)
{
ob_start();
foreach($lvs as &$lv)
{
if( !isset($semester[$lv->semester]) ) {
$semester[$lv->semester] = array();
}
$lv->parent = null;
$lv->childs = array();
$assoclvs[$lv->studienplan_lehrveranstaltung_id] = $lv;
}
foreach($assoclvs as &$assoclv)
{
if( $assoclv->studienplan_lehrveranstaltung_id_parent === NULL )
{
$semester[$assoclv->semester][] = $assoclv;
}
else
{
if( isset($assoclvs[$assoclv->studienplan_lehrveranstaltung_id_parent]) )
{
$assoclv->parent = $assoclvs[$assoclv->studienplan_lehrveranstaltung_id_parent];
$assoclvs[$assoclv->studienplan_lehrveranstaltung_id_parent]->childs[] = $assoclv;
}
else
{
$errors[] = "ERROR: Missing parent lv " . $assoclv->studienplan_lehrveranstaltung_id_parent . "\n";
}
}
}
function printchilds($childs, $level) {
if( count($childs) < 1 )
{
return;
}
foreach($childs as $child)
{
echo $level . $child->bezeichnung . " (" . $child->ects . ") " . $child->lehrtyp_kurzbz . "\n";
printchilds($child->childs, $level . "\t");
}
}
echo "<!--\n\n";
foreach($semester as $sem => $mods)
{
echo $sem . ". Semester: \n";
foreach($mods as $mod)
{
$level = "\t";
echo $level . $mod->bezeichnung . " (" . $mod->ects . ") " . $mod->lehrtyp_kurzbz . "\n";
printchilds($mod->childs, $level . "\t");
}
}
echo "-->\n\n";
if (count($errors) === 0)
{
$this->DrawioModel->renderFileStart();
$this->maxxoffset = self::DEFAULT_XOFFSET;
$this->DrawioModel->renderDiagramStart($studienplan_id, 'Modulgrafik');
$this->renderSemester($semester);
$this->DrawioModel->renderDiagramEnd();
$this->DrawioModel->renderFileEnd();
}
else
{
foreach ($errors as $error)
{
echo $error;
}
}
$output = ob_get_clean();
file_put_contents(sys_get_temp_dir().'/Modulgrafik.xml', $output);
$ret = DocsboxLib::convert(sys_get_temp_dir().'/Modulgrafik.xml', sys_get_temp_dir().'/Modulgrafik.png', 'png');
echo 'File: '.sys_get_temp_dir().'/Modulgrafik.png'."\n";
}
else
{
echo "Keine LVs gefunden.\n";
}
}
protected function renderSemester($semester)
{
$cury = self::DEFAULT_YOFFSET;
foreach($semester as $sem => $mods)
{
$curx = self::DEFAULT_XOFFSET;
$id = uniqid();
$ects = 30; //TODO calc
$this->DrawioModel->renderSemesterLabel($id, $sem, $ects, self::DEFAULT_XOFFSET, $cury, self::DEFAULT_SEMESTER_LABEL_WIDTH, self::DEFAULT_HEIGHT);
$curx += self::DEFAULT_SEMESTER_LABEL_WIDTH + self::DEFAULT_SPACING;
$maxmodulheight = 0;
foreach($mods as $mod)
{
$modid = uniqid();
$size = $this->DrawioModel->renderModulList($modid, $mod, $curx, $cury, self::DEFAULT_ECTS_WIDTH, self::DEFAULT_HEIGHT);
$curx += $size->width + self::DEFAULT_SPACING;
if( $size->height > $maxmodulheight)
{
$maxmodulheight = $size->height;
}
}
$cury += $maxmodulheight + self::DEFAULT_SPACING;
}
}
}
@@ -1,339 +0,0 @@
<?php
/* Copyright (C) 2024 fhcomplete.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
*/
if (!defined("BASEPATH")) exit("No direct script access allowed");
class Organigramm extends JOB_Controller
{
const DEFAULT_XOFFSET = 40;
const DEFAULT_YOFFSET = 30;
const DEFAULT_WIDTH = 160;
const DEFAULT_HEIGHT = 50;
const DEFAULT_SPACING = 40;
const DEFAULT_FONTSIZE = 8;
const RENDER_CHILDS_HORIZONTAL = 1;
const RENDER_CHILDS_VERTICAL = 2;
protected $maxxoffset;
protected $donotrenderchildsoftype;
public function __construct()
{
parent::__construct();
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$this->load->model('CL/Drawio_model', 'DrawioModel');
$this->load->library('DocsboxLib', null, 'DocsboxLib');
$this->maxxoffset = self::DEFAULT_XOFFSET;
$this->donotrenderchildsoftype = array();
}
public function getAllActiveOes()
{
$sql = <<<EOSQL
SELECT
oe.oe_kurzbz,
CASE
WHEN oe.oe_parent_kurzbz = 'atw' THEN 'gst'
WHEN oe.oe_parent_kurzbz = 'etw' THEN 'gst'
ELSE oe.oe_parent_kurzbz
END AS oe_parent_kurzbz,
oe.bezeichnung,
oe.organisationseinheittyp_kurzbz,
STRING_AGG(
DISTINCT p.vorname || ' ' || p.nachname,
', '
) AS leitung_uid
FROM
"public"."tbl_organisationseinheit" oe
LEFT JOIN public.tbl_benutzerfunktion bf ON bf.oe_kurzbz = oe.oe_kurzbz
AND (
bf.datum_bis IS NULL
OR bf.datum_bis > NOW() :: date
)
AND (
bf.funktion_kurzbz IS NULL
OR bf.funktion_kurzbz = 'Leitung'
)
LEFT JOIN public.tbl_benutzer b USING(uid)
LEFT JOIN public.tbl_person p USING(person_id)
WHERE
oe.aktiv = true
AND oe.oe_kurzbz NOT IN ('betriebsrat', 'oeh', 'FUEWahl', 'atw', 'etw', 'gf20')
GROUP BY
oe.oe_kurzbz,
oe.oe_parent_kurzbz,
oe.bezeichnung,
oe.organisationseinheittyp_kurzbz
ORDER BY
oe.oe_parent_kurzbz ASC NULLS FIRST,
oe.oe_kurzbz ASC;
EOSQL;
$result = $this->OrganisationseinheitModel->execReadOnlyQuery($sql);
$oes = getData($result);
$errors = array();
$assocoes = array();
$roots = array();
if($oes)
{
ob_start();
foreach($oes as &$oe)
{
$oe->parent = NULL;
$oe->childs = array();
$oe->renderchilds = self::RENDER_CHILDS_HORIZONTAL;
$oe->childstorender = array();
$oe->donotrenderchildsoftype = array();
$assocoes[$oe->oe_kurzbz] = $oe;
}
foreach($assocoes as &$assocoe)
{
if( $assocoe->oe_parent_kurzbz === NULL )
{
$roots[$assocoe->oe_kurzbz] = $assocoe;
$assocoe->donotrenderchildsoftype = array(
'Team',
'Lehrgang',
'Studiengang',
'Kompetenzfeld',
'Forschungsfeld',
'Container'
);
}
else
{
if( isset($assocoes[$assocoe->oe_parent_kurzbz]) )
{
$assocoe->parent = $assocoes[$assocoe->oe_parent_kurzbz];
$assocoes[$assocoe->oe_parent_kurzbz]->childs[] = $assocoe;
if( $assocoe->organisationseinheittyp_kurzbz === 'Fakultaet' )
{
$roots[$assocoe->oe_kurzbz] = $assocoe;
}
}
else
{
$errors[] = "ERROR: Missing parent oe " . $assocoe->oe_parent_kurzbz . "\n";
}
}
}
if(count($errors) === 0)
{
$pages = count($roots);
$this->DrawioModel->renderFileStart($pages);
foreach($roots AS &$root)
{
$this->maxxoffset = self::DEFAULT_XOFFSET;
$this->donotrenderchildsoftype = $root->donotrenderchildsoftype;
$this->prepareChildsToRender($root);
$this->DrawioModel->renderDiagramStart($root->oe_kurzbz, $root->bezeichnung);
$this->renderOE($root, 0, 0);
$this->DrawioModel->renderDiagramEnd();
}
$this->DrawioModel->renderFileEnd();
}
else
{
foreach ($errors as $error)
{
echo $error;
}
}
$output = ob_get_clean();
file_put_contents(sys_get_temp_dir().'/Organigramm.xml', $output);
$ret = DocsboxLib::convert(sys_get_temp_dir().'/Organigramm.xml', sys_get_temp_dir().'/Organigramm.png', 'png');
echo 'File: '.sys_get_temp_dir().'//Organigramm.png'."\n";
}
else
{
echo "Keine Oes gefunden.\n";
}
}
protected function prepareChildsToRender(&$oe)
{
$oe->childstorender = array();
$oe->renderchilds = self::RENDER_CHILDS_HORIZONTAL;
if( isset($oe->childsxoffset) )
{
unset($oe->childsxoffset);
}
foreach($oe->childs AS &$oechild )
{
$this->prepareChildsToRender($oechild);
if( !in_array($oechild->organisationseinheittyp_kurzbz, $this->donotrenderchildsoftype) )
{
$oe->childstorender[] = $oechild;
}
}
$nurLehrgaengeOderStudiengaengeOhneKinder = true;
foreach($oe->childstorender AS &$oechildtorender )
{
if( !(count($oechildtorender->childstorender) === 0) )
{
$nurLehrgaengeOderStudiengaengeOhneKinder = false;
}
}
if( $nurLehrgaengeOderStudiengaengeOhneKinder && $oe->parent !== NULL )
{
$oe->renderchilds = self::RENDER_CHILDS_VERTICAL;
}
}
protected function renderOE($oe, $level, $parentrenderedchildcount)
{
$width = self::DEFAULT_WIDTH;
$height = self::DEFAULT_HEIGHT;
$spacing = self::DEFAULT_SPACING;
$fontsize = self::DEFAULT_FONTSIZE;
$nextlevel = $level + 1;
$renderedchildcount = 0;
$curxoffset = $this->maxxoffset;
if( count($oe->childstorender) > 0 )
{
if( !isset($oe->childsxoffset) )
{
$oe->childsxoffset = (object) array(
'min' => $curxoffset,
'max' => $curxoffset
);
}
foreach($oe->childstorender AS $child)
{
$ret = $this->renderOE($child, $nextlevel, $renderedchildcount);
$renderedchildcount++;
if( $renderedchildcount === 1 )
{
$oe->childsxoffset->min = $ret->minx;
}
$oe->childsxoffset->max = $ret->maxx;
}
if( count($oe->childstorender) === $renderedchildcount )
{
$curxoffset = $oe->childsxoffset->min +
floor((($oe->childsxoffset->max - $oe->childsxoffset->min) / 2)) -
floor((($width + $spacing) / 2));
}
}
if( $oe->parent !== null && $oe->parent->renderchilds === self::RENDER_CHILDS_VERTICAL )
{
$x = $curxoffset;
$y = self::DEFAULT_YOFFSET
+ (($level - 1) * ($height + $spacing))
+ (($parentrenderedchildcount + 1) * ($height + floor($spacing / 2)));
}
else
{
$x = $curxoffset;
$y = self::DEFAULT_YOFFSET + ($level * ($height + $spacing));
}
$bezeichnung = htmlspecialchars($oe->bezeichnung);
$leitung = ($oe->leitung_uid !== null) ? htmlspecialchars($oe->leitung_uid) : 'N.N.';
$fillcolors = array(
'Team' => '#ffe6cc',
'Abteilung' => '#e6ffcc',
'Studiengang' => '#cce6ff',
'Lehrgang' => '#e6ccff',
'Fakultaet' => '#f8cecc',
'Department' => '#fff2cc',
'Forschungsfeld' => '#e1d5e7',
'Kompetenzfeld' => '#f5f5f5'
);
$fillcolor = (isset($fillcolors[$oe->organisationseinheittyp_kurzbz])) ? $fillcolors[$oe->organisationseinheittyp_kurzbz] : '#ffffff';
$value = <<<EOVAL
&lt;font style=&quot;font-size: {$fontsize}px;&quot;&gt;&lt;div style=&quot;&quot;&gt;[{$oe->organisationseinheittyp_kurzbz}]&lt;/div&gt;&lt;b style=&quot;&quot;&gt;{$bezeichnung}&lt;/b&gt;&lt;div&gt;({$leitung})&lt;/div&gt;&lt;/font&gt;" style="whiteSpace=wrap;html=1;align=center;verticalAlign=middle;treeFolding=1;treeMoving=1;newEdgeStyle={&quot;edgeStyle&quot;:&quot;elbowEdgeStyle&quot;,&quot;startArrow&quot;:&quot;none&quot;,&quot;endArrow&quot;:&quot;none&quot;};fillColor={$fillcolor};
EOVAL;
$this->DrawioModel->renderCell($oe->oe_kurzbz, $value, $x, $y, $width, $height);
if( $oe->oe_parent_kurzbz !== NULL )
{
$exitX = '0.5';
$exitY = '1';
$entryX = '0.5';
$entryY = '0';
$points = array();
if( $oe->parent !== null && $oe->parent->renderchilds === self::RENDER_CHILDS_VERTICAL)
{
$exitX = '0';
$exitY = '0.5';
$entryX = '0';
$entryY = '0.5';
$points = array(
(object) array(
'x' => ($x - floor($spacing / 2)),
'y' => ($y + floor($height / 2))
)
);
}
$this->DrawioModel->renderEdge($oe->oe_parent_kurzbz, $oe->oe_kurzbz, $exitX, $exitY, $entryX, $entryY, $points);
}
if( $oe->parent !== null && $oe->parent->renderchilds === self::RENDER_CHILDS_VERTICAL )
{
if( count($oe->parent->childstorender) === ($parentrenderedchildcount + 1) )
{
if( $this->maxxoffset < ($x + $width + $spacing) )
{
$this->maxxoffset = ($x + $width + $spacing);
}
return (object) array(
'minx' => $curxoffset,
'maxx' => ($x + $width + $spacing)
);
}
return (object) array(
'minx' => $curxoffset,
'maxx' => $x
);
}
if( $this->maxxoffset < ($x + $width + $spacing) )
{
$this->maxxoffset = ($x + $width + $spacing);
}
return (object) array(
'minx' => $curxoffset,
'maxx' => ($x + $width + $spacing)
);
}
}
+9 -15
View File
@@ -1,5 +1,5 @@
<?php
/* Copyright (C) 2024 fhcomplete.net
/* Copyright (C) 2022 fhcomplete.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
@@ -32,7 +32,7 @@ class DocsboxLib
const STATUS_QUEUED = 'queued'; // Docsbox status when a file has been queued for the conversion
const STATUS_STARTED = 'started'; // Docsbox status when a file has started being worked
const STATUS_WORKING = 'working'; // Docsbox status when a file is being converted
const JSON_FORMATS = '{"formats": ["%s"]}'; // JSON object to be sent to docsbox to specify the file format
const OUTPUT_FILENAME = 'out.zip.pdf'; // File name used by docsbox to save a converted document
const DEFAULT_FORMAT = 'pdf'; // Default supported format
@@ -50,7 +50,7 @@ class DocsboxLib
if (($format == null) || ($format != null && ctype_space($format) === true)) $format = self::DEFAULT_FORMAT;
// Posts the file to docsbox
$queueId = self::_postFile($inputFileName, $format);
$queueId = self::_postFile($inputFileName);
// If an error occurred
if ($queueId == null) return self::ERROR;
@@ -60,7 +60,7 @@ class DocsboxLib
if ($resultUrl == null) return self::ERROR;
// Download and rename the converted file
$downloaded = self::_downloadFile($inputFileName, $resultUrl, $outputFileName, $format);
$downloaded = self::_downloadFile($resultUrl, $outputFileName);
// If an error occurred
if (!$downloaded) return self::ERROR;
@@ -74,7 +74,7 @@ class DocsboxLib
* Posts the given file to a Docsboxserver and checks the response to return a valid queue id
* On failure it returns a null value
*/
private static function _postFile($inputFileName, $format)
private static function _postFile($inputFileName)
{
$queueId = null;
@@ -82,14 +82,8 @@ class DocsboxLib
{
// Posts the given file and expects a response in JSON format
$postFileResponse = \Httpful\Request::post(DOCSBOX_SERVER.DOCSBOX_PATH_API)
->sendsType(\Httpful\Mime::FORM)
->expectsJson()
->body(
array(
'options' => sprintf(self::JSON_FORMATS, $format)
)
)
->attach(array('file' => $inputFileName))
->expectsJson()
->send();
// Checks that:
@@ -227,7 +221,7 @@ class DocsboxLib
/**
* Download the converted file using the provided URL, unzip it, and renames it into the provided file name
*/
private static function _downloadFile($inputFileName, $resultUrl, $outputFileName, $format)
private static function _downloadFile($resultUrl, $outputFileName)
{
$downloaded = false; // pessimistic assumption
@@ -259,7 +253,7 @@ class DocsboxLib
// Opened, extracted and closed!
// Rename the extracted file to the given output file name
if (@rename($inputFileName.'.'.$format, $outputFileName))
if (rename($outputDirectory.'/'.self::OUTPUT_FILENAME, $outputFileName))
{
$downloaded = true;
}
@@ -267,7 +261,7 @@ class DocsboxLib
{
error_log(
'An error occurred while renaming the extracted file: '.
$inputFileName.'.'.$format.' into: '.
$outputDirectory.'/'.self::OUTPUT_FILENAME.' into: '.
$outputFileName
);
}
-170
View File
@@ -1,170 +0,0 @@
<?php
/* Copyright (C) 2024 fhcomplete.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
*/
class Drawio_model extends CI_Model
{
/**
*
*/
public function renderFileStart($pages=1, $agent='FH-Complete', $timemodified='now')
{
$modified = (new DateTime($timemodified, new DateTimeZone('UTC')))->format(DateTime::ATOM);
echo <<<HEADER
<mxfile modified="{$modified}" host="Electron" agent="{$agent}" type="device" pages="{$pages}">
HEADER;
}
/**
*
*/
public function renderFileEnd()
{
echo <<<FOOTER
</mxfile>
FOOTER;
}
/**
*
*/
public function renderDiagramStart($diagram_id, $diagram_bezeichnung)
{
$bezeichnung = htmlspecialchars($diagram_bezeichnung);
echo <<<STARTDIAGRAMM
<diagram id="diagram_{$diagram_id}" name="{$bezeichnung}">
<mxGraphModel dx="1177" dy="687" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
STARTDIAGRAMM;
}
/**
*
*/
public function renderDiagramEnd()
{
echo <<<ENDDIAGRAMM
</root>
</mxGraphModel>
</diagram>
ENDDIAGRAMM;
}
/**
*
*/
public function renderCell($id, $value, $x, $y, $width, $height)
{
echo <<<OE
<mxCell id="{$id}" value="{$value}" parent="1" vertex="1">
<mxGeometry x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="geometry" />
</mxCell>
OE;
}
/**
*
*/
public function renderEdge($source, $target, $exitX, $exitY, $entryX, $entryY, $points=array())
{
if( count($points) > 0 )
{
$pointsxml = '';
foreach($points as $point)
{
$pointsxml .= <<<EOPOINT
<mxPoint x="{$point->x}" y="{$point->y}" />
EOPOINT;
}
$edgegeom = <<<EDGEPOINTS
<mxGeometry relative="1" as="geometry">
<Array as="points">
{$pointsxml}
</Array>
</mxGeometry>
EDGEPOINTS;
}
else
{
$edgegeom = ' <mxGeometry relative="1" as="geometry" />';
}
echo <<<EDGE
<mxCell id="edge_{$source}_{$target}" value="" style="edgeStyle=elbowEdgeStyle;elbow=vertical;sourcePerimeterSpacing=0;targetPerimeterSpacing=0;startArrow=none;endArrow=none;rounded=0;curved=0;exitX={$exitX};exitY={$exitY};exitDx=0;exitDy=0;entryX={$entryX};entryY={$entryY};entryDx=0;entryDy=0;" parent="1" source="{$source}" target="{$target}" edge="1">
{$edgegeom}
</mxCell>
EDGE;
}
/**
*
*/
public function renderSemesterLabel($id, $sem, $ects, $x, $y, $width, $height)
{
echo <<<RENDERSEM
<mxCell id="{$id}" value="&lt;b&gt;{$sem}. Semester&lt;br&gt;&lt;/b&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;{$ects} ECTS&lt;/span&gt;&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
<mxGeometry x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="geometry" />
</mxCell>
RENDERSEM;
}
/**
*
*/
public function renderModulList($listid, $mod, $x, $y, $ects_width, $lv_height)
{
$width = ceil($mod->ects * $ects_width);
$height = (count($mod->childs) + 1) * $lv_height;
$modul_ects = (int) $mod->ects;
echo <<<RENDERMOD
<mxCell id="{$listid}" value="{$mod->bezeichnung} ({$modul_ects})" style="swimlane;fontStyle=0;childLayout=stackLayout;horizontal=1;startSize={$lv_height};horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=0;marginBottom=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="geometry">
<mxRectangle x="{$x}" y="{$y}" width="{$width}" height="{$height}" as="alternateBounds" />
</mxGeometry>
</mxCell>
RENDERMOD;
$childnumber = 0;
foreach ($mod->childs as $child)
{
$childnumber++;
$childid = uniqid();
$childheight = $childnumber * $lv_height;
$child_ects = (int) $child->ects;
echo <<<RENDERMODFOR
<mxCell id="{$childid}" value="{$child->bezeichnung} ({$child_ects})" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;whiteSpace=wrap;html=1;" vertex="1" parent="{$listid}">
<mxGeometry y="{$childheight}" width="{$width}" height="{$lv_height}" as="geometry" />
</mxCell>
RENDERMODFOR;
}
return (object) array(
'width' => $width,
'height' => $height
);
}
}
@@ -122,6 +122,47 @@ class Studiensemester_model extends DB_Model
return $this->execQuery($query, array($studiensemester_kurzbz, $limit));
}
/**
* Returns the current study semester and the previous semesters of the same type (SS/WS).
*
* Example:
* - SS2026, limit 3: SS2026, SS2025, SS2024
* - WS2025, limit 2: WS2025, WS2024
*
* @param $studiensemester_kurzbz
* @param $limit
*/
public function getPreviousSameSemesterFrom($studiensemester_kurzbz, $limit = 1)
{
$qry = '
SELECT
studiensemester_kurzbz,
start,
ende
FROM
public.tbl_studiensemester
WHERE
SUBSTRING(studiensemester_kurzbz FROM 1 FOR 2) = SUBSTRING(? FROM 1 FOR 2)
AND start <= (
SELECT start
FROM public.tbl_studiensemester
WHERE studiensemester_kurzbz = ?
)
ORDER BY
start DESC
LIMIT ?
';
return $this->execQuery($qry,
[
$studiensemester_kurzbz,
$studiensemester_kurzbz,
$limit
]
);
}
/**
* getNearest
*/
@@ -260,7 +260,6 @@ class Benutzerfunktion_model extends DB_Model
return $this->execQuery($query, $parameters_array);
}
/**
* Get active Kompetenzfeldleitung bei UID.
*
@@ -296,7 +295,6 @@ class Benutzerfunktion_model extends DB_Model
return $this->execQuery($query, $parameters_array);
}
public function insertBenutzerfunktion($Json)
{
unset($Json['benutzerfunktion_id']);
-6
View File
@@ -287,7 +287,6 @@ class dokument_export
{
case 'pdf':
case 'doc':
case 'docx':
$ret = 0;
$this->temp_filename = $this->temp_folder . '/out.' . $this->outputformat;
@@ -370,11 +369,6 @@ class dokument_export
header('Content-Disposition: attachment; filename="'.$this->filename.'.doc"');
header('Content-Length: '.$fsize);
break;
case 'docx':
header('Content-type: application/vnd.ms-word');
header('Content-Disposition: attachment; filename="'.$this->filename.'.docx"');
header('Content-Length: '.$fsize);
break;
case 'odt':
header('Content-type: application/vnd.oasis.opendocument.text');
@@ -433,6 +433,7 @@ export default {
:label="$p.t('wawi/ausgegebenam')"
name="ausgegebenam"
v-model="formData.ausgegebenam"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -449,6 +450,7 @@ export default {
:label="$p.t('wawi/retouram')"
name="retouram"
v-model="formData.retouram"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -551,6 +551,7 @@ export default {
container-class="mb-3 col-3"
type="DatePicker"
v-model="formData.datum_von"
model-type="yyyy-MM-dd"
name="datum_von"
:label="$p.t('ui/from') + ' *'"
auto-apply
@@ -566,6 +567,7 @@ export default {
container-class="mb-3 col-3"
type="DatePicker"
v-model="formData.datum_bis"
model-type="yyyy-MM-dd"
name="datum_bis"
:label="$p.t('global/bis')"
auto-apply
@@ -470,6 +470,7 @@ export default {
:label="$p.t('admission', 'anmeldundRtAm')"
type="DatePicker"
v-model="formData.anmeldedatum"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -293,6 +293,7 @@ export default {
:label="$p.t('person', 'geburtsdatum')"
type="DatePicker"
v-model="data.gebdatum"
model-type="yyyy-MM-dd"
name="gebdatum"
:clearable="false"
no-today
@@ -103,6 +103,7 @@ export default {
<form-input
type="DatePicker"
v-model="formData.nachgereicht_am"
model-type="yyyy-MM-dd"
name="nachgereicht_am"
:label="$p.t('dokumente/nachreichungAm')"
auto-apply
@@ -27,7 +27,7 @@ export default {
return {
filter: false,
studiengang_kz: false,
counterdate: new Date()
counterdate: luxon.DateTime.now().setZone(FHC_JS_DATA_STORAGE_OBJECT.timezone).toISODate()
};
},
computed: {
@@ -259,6 +259,7 @@ export default {
<form-input
type="DatePicker"
v-model="counterdate"
model-type="yyyy-MM-dd"
input-group
:enable-time-picker="false"
text-input
@@ -79,6 +79,7 @@ export default {
<form-input
type="DatePicker"
v-model="data.buchungsdatum"
model-type="yyyy-MM-dd"
name="buchungsdatum"
:label="$p.t('konto/buchungsdatum')"
:enable-time-picker="false"
@@ -88,7 +88,7 @@ export default {
this.data = {
buchungstyp_kurzbz: '',
betrag: '-0.00',
buchungsdatum: new Date(),
buchungsdatum: luxon.DateTime.now().setZone(FHC_JS_DATA_STORAGE_OBJECT.timezone).toISODate(),
buchungstext: '',
mahnspanne: 30,
studiensemester_kurzbz: this.currentSemester,
@@ -154,6 +154,7 @@ export default {
<form-input
type="DatePicker"
v-model="data.buchungsdatum"
model-type="yyyy-MM-dd"
name="buchungsdatum"
:label="$p.t('konto/buchungsdatum')"
:enable-time-picker="false"
@@ -467,6 +467,7 @@ export default {
:label="$p.t('ui', 'von')"
type="DatePicker"
v-model="formData.von"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -501,6 +502,7 @@ export default {
:label="$p.t('global', 'bis')"
type="DatePicker"
v-model="formData.bis"
model-type="yyyy-MM-dd"
auto-apply
:enable-time-picker="false"
text-input
@@ -325,6 +325,7 @@ export default {
:label="$p.t('infocenter', 'zgvDatum')"
type="DatePicker"
v-model="data.zgvdatum"
model-type="yyyy-MM-dd"
name="zgvdatum"
no-today
auto-apply
@@ -389,6 +390,7 @@ export default {
:label="$p.t('lehre', 'zgvMasterDatum')"
type="DatePicker"
v-model="data.zgvmadatum"
model-type="yyyy-MM-dd"
name="zgvmadatum"
no-today
auto-apply
@@ -454,6 +456,7 @@ export default {
:label="$p.t('lehre', 'zgvDoktorDatum')"
type="DatePicker"
v-model="data.zgvdoktordatum"
model-type="yyyy-MM-dd"
name="zgvdoktordatum"
no-today
auto-apply
@@ -135,6 +135,11 @@ export default{
.then(result => {
this.statusNew = false;
this.formData = result.data;
//to show Date in correct format in the modal (is timestamp in database)
if (this.formData.bewerbung_abgeschicktamum) {
this.formData.bewerbung_abgeschicktamum =
this.formData.bewerbung_abgeschicktamum.substring(0, 10);
}
this.originalDatum = new Date(result.data.datum);
return prestudent;
})
@@ -276,6 +281,7 @@ export default{
container-class="mb-3"
type="DatePicker"
v-model="formData.datum"
model-type="yyyy-MM-dd"
name="datum"
:label="$p.t('global/datum')"
auto-apply
@@ -291,6 +297,7 @@ export default{
container-class="mb-3"
type="DatePicker"
v-model="formData.bestaetigtam"
model-type="yyyy-MM-dd"
name="bestaetigtam"
:label="$p.t('lehre/bestaetigt_am')"
auto-apply
@@ -306,6 +313,7 @@ export default{
container-class="mb-3"
type="DatePicker"
v-model="formData.bewerbung_abgeschicktamum"
model-type="yyyy-MM-dd"
name="bewerbung_abgeschicktamum"
:label="$p.t('lehre/bewerbung_abgeschickt_am')"
auto-apply
@@ -285,6 +285,7 @@ export default {
uid="stv-list-new-gebdatum"
name="gebdatum"
v-model="formDataPerson['gebdatum']"
model-type="yyyy-MM-dd"
:disabled="!!person"
@update:model-value="loadSuggestions"
text-input
+16 -8
View File
@@ -218,15 +218,23 @@ export const CoreFilterCmpt = {
},
columnsForFilter() {
if (!this.filteredColumns || !this.datasetMetadata) return [];
const localizedColumnTitles = this.tabulator.getLang().columns;
const isTabulatorLocalized = !!this.$props.tabulatorOptions.locale;
const filterTitles = this.filteredColumns.reduce((a, c) => {
a[c.field] =
isTabulatorLocalized && localizedColumnTitles[c.field]
? localizedColumnTitles[c.field]
: c.title;
return a;
}, {});
let filterTitles;
if (isTabulatorLocalized) {
const localizedColumnTitles = this.tabulator.getLang().columns;
filterTitles = this.filteredColumns.reduce((a, c) => {
a[c.field] = localizedColumnTitles[c.field];
return a;
}, {});
} else {
filterTitles = this.filteredColumns.reduce((a, c) => {
a[c.field] = c.title;
return a;
}, {});
}
return this.datasetMetadata.map((el) => ({
...el,
...{ title: filterTitles[el.name] },
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB