diff --git a/application/components/filters/Vertragsverwaltung.php b/application/components/filters/Vertragsverwaltung.php new file mode 100644 index 000000000..b96aee8ea --- /dev/null +++ b/application/components/filters/Vertragsverwaltung.php @@ -0,0 +1,36 @@ + 'core', + 'datasetName' => 'vertragsverwaltung', + 'query' => ' + SELECT + uid, + person_id, + vorname, + nachname, + gebdatum, + vertragsarten, + unternehmen, + ids, + aktiv + FROM + ( + SELECT + b.uid , p.person_id, + p.vorname, p.nachname, + gebdatum, + STRING_AGG(DISTINCT va.bezeichnung, \', \') AS Vertragsarten, + STRING_AGG(DISTINCT u.bezeichnung, \', \') AS Unternehmen, + STRING_AGG(d.dienstverhaeltnis_id::TEXT, \', \') AS ids, + b.aktiv + FROM + hr.tbl_dienstverhaeltnis d + JOIN public.tbl_benutzer b ON d.mitarbeiter_uid = b.uid + JOIN public.tbl_person p ON p.person_id = b.person_id + JOIN public.tbl_organisationseinheit u ON d.oe_kurzbz = u.oe_kurzbz + JOIN hr.tbl_vertragsart va ON d.vertragsart_kurzbz = va.vertragsart_kurzbz + GROUP BY b.uid, p.person_id, p.vorname, p.nachname, b.aktiv + ) as vertragsdaten + ', + 'requiredPermissions' => 'vertrag/mitarbeiter' + ); diff --git a/application/config/Events.php b/application/config/Events.php index 3e0a5248f..80a8f03b3 100644 --- a/application/config/Events.php +++ b/application/config/Events.php @@ -6,30 +6,30 @@ use CI3_Events as Events; Events::on('loadRenderers', function ($renderers) { $fhc_core_renderers =& $renderers(); $fhc_core_renderers["lehreinheit"] = array( - 'calendarEvent' => APP_ROOT.'public/js/components/Cis/Renderer/Lehreinheit/calendarEvent.js', - 'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Lehreinheit/modalTitle.js', - 'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Lehreinheit/modalContent.js', - 'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css' + 'calendarEvent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Lehreinheit/calendarEvent.js'), + 'modalTitle' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Lehreinheit/modalTitle.js'), + 'modalContent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Lehreinheit/modalContent.js'), + 'calendarEventStyles' => APP_ROOT . 'public/css/Cis4/CoreCalendarEvents.css' ); }); Events::on('loadRenderers', function ($renderers) { $fhc_core_renderers =& $renderers(); $fhc_core_renderers["reservierung"] = array( - 'calendarEvent' => APP_ROOT.'public/js/components/Cis/Renderer/Reservierungen/calendarEvent.js', - 'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Reservierungen/modalTitle.js', - 'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Reservierungen/modalContent.js', - 'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css' + 'calendarEvent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Reservierungen/calendarEvent.js'), + 'modalTitle' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Reservierungen/modalTitle.js'), + 'modalContent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Reservierungen/modalContent.js'), + 'calendarEventStyles' => APP_ROOT . 'public/css/Cis4/CoreCalendarEvents.css' ); }); Events::on('loadRenderers', function ($renderers) { $fhc_core_renderers =& $renderers(); $fhc_core_renderers["ferien"] = array( - 'calendarEvent' => APP_ROOT.'public/js/components/Cis/Renderer/Feiertage/calendarEvent.js', - 'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Feiertage/modalTitle.js', - 'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Feiertage/modalContent.js', - 'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css' + 'calendarEvent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Feiertage/calendarEvent.js'), + 'modalTitle' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Feiertage/modalTitle.js'), + 'modalContent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Feiertage/modalContent.js'), + 'calendarEventStyles' => APP_ROOT . 'public/css/Cis4/CoreCalendarEvents.css' ); }); diff --git a/application/config/abgabe.php b/application/config/abgabe.php new file mode 100644 index 000000000..90aedbd8b --- /dev/null +++ b/application/config/abgabe.php @@ -0,0 +1,45 @@ + cis4 +$config['URL_STUDENTS'] = 'cis.php/Cis/Abgabetool/Student'; +// used as APP_ROOT.URL_MITARBEITER -> old cis +$config['URL_MITARBEITER'] = 'index.ci.php/Cis/Abgabetool/Mitarbeiter'; +// used as APP_ROOT.URL_MITARBEITER -> old cis +$config['URL_ASSISTENZ'] = 'index.ci.php/Cis/Abgabetool/Assistenz'; + +// lehre.tbl_paabgabetyp bezeichnung +//$config['ALLOWED_ABGABETYPEN_BETREUER'] = ['Zwischenabgabe', 'Quality Gate 1', 'Quality Gate 2']; +$config['ALLOWED_ABGABETYPEN_BETREUER'] = ['abstract','zwischen', 'qualgate1', 'qualgate2']; // tbl_paabgabetyp pk +// paabgabetypen for which betreuer is benachrichtigt via sammelmail +$config['RELEVANT_PAABGABETYPEN_SAMMELMAIL_BETREUER'] = ['qualgate1', 'qualgate2', 'end']; +// paabgabetypen for which assistenz is benachrichtigt via sammelmail +$config['RELEVANT_PAABGABETYPEN_SAMMELMAIL_ASSISTENZ'] = ['end']; +// paabgabetypen for which student is benachrichtigt via sammelmail -> basically all of them but still defined for consistency +$config['RELEVANT_PAABGABETYPEN_SAMMELMAIL_STUDENT'] = ['qualgate1', 'qualgate2', 'zwischen', 'note', 'abstract', 'end', 'enda']; +//$config['ALLOWED_NOTEN_ABGABETOOL'] = ['Bestanden', 'Nicht bestanden']; +$config['ALLOWED_NOTEN_ABGABETOOL'] = [10, 14]; // tbl_note pk +// benotete projektarbeiten sperren weitere terminanlage & bearbeitung, diese noten sind ausnahmen dieser Regel +// wie zB "Nicht beurteilt" & "Noch nicht eingetragen" +$config['NONFINAL_NOTEN_ABGABETOOL'] = [9]; +$config['beurteilung_link_fallback'] = 'addons/fhtw/content/projektbeurteilung/projektbeurteilungDocumentExport.php?projektarbeit_id=?&betreuerart_kurzbz=?&person_id=?'; + +$config['PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ERSTBEGUTACHTER'] = 'index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter'; +$config['PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ZWEITBEGUTACHTER'] = 'index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter'; + +$config['SIGNATUR_CHECK_PAABGABETYPEN'] = ['end']; + +// to be used as "https://moodle.technikum-wien.at/course/view.php?idnumber=dl{$stg_kz}" for stg specific moodle routing +$config['STG_MOODLE_LINK'] = 'https://moodle.technikum-wien.at/course/view.php?idnumber=dl'; + +$config['ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'] = true; +$config['ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'] = true; + +$config['BETREUER_SAMMELMAIL_BUTTON_STUDENT'] = true; diff --git a/application/config/cis.php b/application/config/cis.php index 8d3bc347e..430539392 100644 --- a/application/config/cis.php +++ b/application/config/cis.php @@ -4,7 +4,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); // CMS Content Id for CIS4 Menu Root -$config['cis_menu_root_content_id'] = 11087; +$config['cis_menu_root_content_id'] = 11091; // send Mails for ProfilUpdate $config['cis_send_profil_update_mails'] = true; // Vilesci CI BaseUrl diff --git a/application/config/javascript.php b/application/config/javascript.php index 6f82810e2..7b8342ef8 100644 --- a/application/config/javascript.php +++ b/application/config/javascript.php @@ -7,3 +7,6 @@ $config['use_vuejs_dev_version'] = false; $config['use_bundled_javascript'] = false; // systemerror_mailto use in FHC-Alert Plugin - if empty Link will not be rendered $config['systemerror_mailto'] = ''; +// use fhcomplete_build_version as path element after public (requires apache mod_rewrite) +// see /public/.htaccess_sample for details +$config['use_fhcomplete_build_version_in_path'] = false; diff --git a/application/config/navigation.php b/application/config/navigation.php index f7ba8dca3..c70aba57c 100644 --- a/application/config/navigation.php +++ b/application/config/navigation.php @@ -163,6 +163,13 @@ $config['navigation_header'] = array( 'expand' => true, 'sort' => 50, 'requiredPermissions' => 'lehre/gruppenmanager:r' + ), + 'vertragsverwaltung' => array( + 'link' => site_url('vertragsverwaltung'), + 'description' => 'Vertragsverwaltung', + 'expand' => true, + 'sort' => 51, + 'requiredPermissions' => 'vertrag/mitarbeiter:r' ) ) ), @@ -335,6 +342,18 @@ $config['navigation_menu']['system/issues/Issues/*'] = array( 'target' => '_blank', 'requiredPermissions' => array('admin:rw') ), + +); + +$config['navigation_menu']['vertragsverwaltung/*'] = array( + 'vertragsverwaltung' => array( + 'link' => site_url('vertragsverwaltung'), + 'description' => 'Vertragsverwaltung', + 'icon' => 'home', + 'sort' => 100, + 'target' => '_blank', + 'requiredPermissions' => array('vertrag/mitarbeiter:r') + ) ); $config['navigation_menu']['apps'] = [ diff --git a/application/config/routes.php b/application/config/routes.php index eba6688ff..aa4ba9db8 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -65,6 +65,13 @@ $route['Cis/LvPlan/.*'] = 'Cis/LvPlan/index/$1'; $route['Cis/MyLvPlan/.*'] = 'Cis/MyLvPlan/index/$1'; $route['Cis/MyLv/.*'] = 'Cis/MyLv/index/$1'; +$route['Abgabetool/Assistenz'] = 'Cis/Abgabetool/Assistenz'; +$route['Abgabetool/Assistenz/(:any)'] = 'Cis/Abgabetool/Assistenz/$1'; +$route['Abgabetool/Mitarbeiter'] = 'Cis/Abgabetool/Mitarbeiter'; +$route['Abgabetool/Student'] = 'Cis/Abgabetool/Student'; +$route['Abgabetool/Student/(:any)'] = 'Cis/Abgabetool/Student/$1'; +$route['Abgabetool/Deadlines'] = 'Cis/Abgabetool/Deadlines'; + // Studierendenverwaltung List Routes $route['api/frontend/v1/stv/[sS]tudents/inout'] = 'api/frontend/v1/stv/Students/index'; $route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv/Students/index'; diff --git a/application/config/stv.php b/application/config/stv.php index 8942c35e6..34a30a96e 100644 --- a/application/config/stv.php +++ b/application/config/stv.php @@ -130,3 +130,16 @@ $config['students_tab_order'] = [ 'combinePeople', 'archive', ]; + +$config['stv_prestudent_tags'] = [ + 'prioone' => ['readonly' => false], + 'priotwo' => ['readonly' => true], + 'hinweis' => ['readonly' => false], + 'hinweis_assistenz' => ['readonly' => true], + 'hinweis_kf' => ['readonly' => true], + 'hinweis_lehrende' => ['readonly' => false], + 'hinweis_stg_kf' => ['readonly' => true], + 'finished_stg' => ['readonly' => true], + 'finished_kf' => ['readonly' => true], + 'inwork_kf' => ['readonly' => true], +]; diff --git a/application/controllers/Cis/Abgabetool.php b/application/controllers/Cis/Abgabetool.php index 1895f7472..04338b1a9 100644 --- a/application/controllers/Cis/Abgabetool.php +++ b/application/controllers/Cis/Abgabetool.php @@ -14,10 +14,10 @@ class Abgabetool extends Auth_Controller { parent::__construct([ 'index' => self::PERM_LOGGED, - 'getStudentProjektarbeitAbgabeFile' => self::PERM_LOGGED, - 'Mitarbeiter' => self::PERM_LOGGED, - 'Student' => self::PERM_LOGGED, - 'Deadlines' => self::PERM_LOGGED + 'Mitarbeiter' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'), + 'Assistenz' => array('basis/abgabe_assistenz:rw'), + 'Student' => array('basis/abgabe_student:rw', 'basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'), + 'Deadlines' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw') ]); } @@ -29,80 +29,69 @@ class Abgabetool extends Auth_Controller */ public function index() { + // TODO: routing from index based on berechtigung? $viewData = array( 'uid'=>getAuthUID(), ); - $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']); + if(defined('CIS4') && CIS4) { + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']); + } else { + $this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'Abgabetool']); + } } - public function Student() + public function Student($student_uid_prop = '') { - $viewData = array( 'uid'=>getAuthUID(), ); - - $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']); + + if(defined('CIS4') && CIS4) { + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']); + } else { + $this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolStudent', 'student_uid_prop' => $student_uid_prop]); + } } public function Mitarbeiter() { - $viewData = array( 'uid'=>getAuthUID(), ); - $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolMitarbeiter']); + if(defined('CIS4') && CIS4) { + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolMitarbeiter']); + } else { + $this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolMitarbeiter']); + } } + public function Assistenz($stg_kz_prop = '') + { + + $viewData = array( + 'uid'=>getAuthUID(), + ); + + if(defined('CIS4') && CIS4) { + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolAssistenz']); + } else { + $this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolAssistenz', 'stg_kz_prop' => $stg_kz_prop]); + } + } + public function Deadlines() { - $viewData = array( 'uid'=>getAuthUID(), ); - $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'DeadlinesOverview']); - } - - - public function getStudentProjektarbeitAbgabeFile() - { - $this->_ci =& get_instance(); - $this->_ci->load->helper('download'); - - $paabgabe_id = $this->_ci->input->get('paabgabe_id'); - $student_uid = $this->_ci->input->get('student_uid'); - - if (!isset($paabgabe_id) || isEmptyString($paabgabe_id) || !isset($student_uid) || isEmptyString($student_uid)) - $this->terminateWithJsonError($this->p->t('global', 'wrongParameters'), 'general'); - - $this->_ci->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); - - $isZugeteilterBetreuer = count($this->_ci->ProjektarbeitModel->checkZuordnung($student_uid, getAuthUID())->retval) > 0; - - if(getAuthUID() == $student_uid || $isZugeteilterBetreuer) { - $file_path = PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf'; - if(file_exists($file_path)) { - - header('Content-Description: File Transfer'); - header('Content-Type: application/octet-stream'); - header('Expires: 0'); - header('Cache-Control: must-revalidate'); - header('Pragma: public'); - header('Content-Disposition: attachment; filename="'.basename($file_path).'"'); - header('Content-Length: ' . filesize($file_path)); - - flush(); // send headers first just in case - readfile($file_path); // read file content to output buffer - - } else { - $this->terminateWithJsonError('File not found'); - } + if(defined('CIS4') && CIS4) { + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'DeadlinesOverview']); } else { - $this->terminateWithJsonError('Keine Zuordnung!'); + $this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'DeadlinesOverview']); } } } diff --git a/application/controllers/Cis/MyLv.php b/application/controllers/Cis/MyLv.php index 49a938553..819d56b05 100644 --- a/application/controllers/Cis/MyLv.php +++ b/application/controllers/Cis/MyLv.php @@ -33,9 +33,4 @@ class MyLv extends Auth_Controller $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLv']); } - - public function Info($studien_semester,$lvid) - { - $this->load->view('Cis/LvInfo',['lvid'=> $lvid, 'studien_semester' => $studien_semester]); - } } diff --git a/application/controllers/Studentenverwaltung.php b/application/controllers/Studentenverwaltung.php index 3fba97e91..1699ba740 100644 --- a/application/controllers/Studentenverwaltung.php +++ b/application/controllers/Studentenverwaltung.php @@ -28,13 +28,13 @@ class Studentenverwaltung extends Auth_Controller 'basis/prestudentstatus' => $this->permissionlib->isBerechtigt('basis/prestudentstatus'), 'assistenz_stgs' => $this->permissionlib->getSTG_isEntitledFor('assistenz'), 'admin' => $this->permissionlib->isBerechtigt('admin'), - 'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'), + 'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz', 'suid'), 'student/keine_studstatuspruefung' => $this->permissionlib->isBerechtigt('student/keine_studstatuspruefung'), 'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht'), 'system/change_outputformat' => $this->permissionlib->getOE_isEntitledFor('system/change_outputformat'), - 'student/editBakkZgv' => $this->permissionlib->isBerechtigt('student/editBakkZgv'), - 'student/editMakkZgv' => $this->permissionlib->isBerechtigt('student/editMakkZgv'), - 'student/editDokZgv' => $this->permissionlib->isBerechtigt('student/editDokZgv'), + 'student/editBakkZgv' => $this->permissionlib->getSTG_isEntitledFor('student/editBakkZgv') ?: array(), + 'student/editMakkZgv' => $this->permissionlib->getSTG_isEntitledFor('student/editMakkZgv') ?: array(), + 'student/editDokZgv' => $this->permissionlib->getSTG_isEntitledFor('student/editDokZgv') ?: array(), 'student/editBismelden' => $this->permissionlib->isBerechtigt('student/editBismelden') ], 'variables' => [ @@ -43,3 +43,5 @@ class Studentenverwaltung extends Auth_Controller ]); } } + + diff --git a/application/controllers/Vertragsverwaltung.php b/application/controllers/Vertragsverwaltung.php new file mode 100644 index 000000000..f68ed1737 --- /dev/null +++ b/application/controllers/Vertragsverwaltung.php @@ -0,0 +1,30 @@ +method] = ['vertrag/mitarbeiter:r']; + #$permissions[$router->method] = ['admin:rw']; + parent::__construct($permissions); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + } + + /** + * @return void + */ + public function _remap() + { + $this->load->view('Vertragsverwaltung', [ + 'permissions' => [ + 'vertragsverwaltung_schreibrechte' => $this->permissionlib->isBerechtigt('vertrag/mitarbeiter', 'suid') + ] + ]); + } +} diff --git a/application/controllers/api/frontend/v1/Abgabe.php b/application/controllers/api/frontend/v1/Abgabe.php new file mode 100644 index 000000000..43dc18d1c --- /dev/null +++ b/application/controllers/api/frontend/v1/Abgabe.php @@ -0,0 +1,1418 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use CI3_Events as Events; + +class Abgabe extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getConfig' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'), + 'getConfigStudent' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_student:rw', 'basis/abgabe_lektor:rw'), + 'getStudentProjektarbeiten' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_student:rw', 'basis/abgabe_lektor:rw'), + 'getStudentProjektabgaben' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_student:rw', 'basis/abgabe_lektor:rw'), + 'postStudentProjektarbeitZwischenabgabe' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_student:rw'), + 'postStudentProjektarbeitEndupload' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_student:rw'), + 'getMitarbeiterProjektarbeiten' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'), + 'postProjektarbeitAbgabe' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'), + 'deleteProjektarbeitAbgabe' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'), + 'postSerientermin' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'), + 'fetchDeadlines' => array('basis/abgabe_assistenz:rw', 'basis/abgabe_lektor:rw'), + 'getPaAbgabetypen' => self::PERM_LOGGED, + 'getNoten' => self::PERM_LOGGED, + 'getProjektarbeitenForStudiengang' =>array('basis/abgabe_assistenz:rw'), + 'getStudiengaenge' => array('basis/abgabe_assistenz:rw'), + 'getStudentProjektarbeitAbgabeFile' => array('basis/abgabe_student:rw', 'basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'), + 'postStudentProjektarbeitZusatzdaten' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'), + 'getSignaturStatusForProjektarbeitAbgaben' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw') + ]); + + $this->load->library('PhrasesLib'); + $this->load->library('SignatureLib'); + + // Loads LogLib with different debug trace levels to get data of the job that extends this class + // It also specify parameters to set database fields + $this->load->library('LogLib', array( + 'classIndex' => 5, + 'functionIndex' => 5, + 'lineIndex' => 4, + 'dbLogType' => 'API', // required + 'dbExecuteUser' => 'RESTful API', + 'requestId' => 'API', + 'requestDataFormatter' => function ($data) { + return json_encode($data); + } + ), 'logLib'); + + $this->loadPhrases( + array( + 'global', + 'ui', + 'abgabetool' + ) + ); + $this->load->config('abgabe'); + $this->load->helper('hlp_sancho_helper'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * loads config related to abgabetool, found in application/config/abgabe + */ + public function getConfig() { + $old_abgabe_beurteilung_link =$this->config->item('old_abgabe_beurteilung_link'); + $turnitin_link = $this->config->item('turnitin_link'); + $abgabetypenBetreuer = $this->config->item('ALLOWED_ABGABETYPEN_BETREUER'); + $ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'); + $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER = $this->config->item('ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'); + $BETREUER_SAMMELMAIL_BUTTON_STUDENT = $this->config->item('BETREUER_SAMMELMAIL_BUTTON_STUDENT'); + + $ret = array( + 'old_abgabe_beurteilung_link' => $old_abgabe_beurteilung_link, + 'turnitin_link' => $turnitin_link, + 'abgabetypenBetreuer' => $abgabetypenBetreuer, + 'ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT' => $ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT, + 'ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER' => $ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER, + 'BETREUER_SAMMELMAIL_BUTTON_STUDENT' => $BETREUER_SAMMELMAIL_BUTTON_STUDENT, + ); + + $this->terminateWithSuccess($ret); + } + + /** + * loads config related to abgabetool for students to avoid handing out links reserved for employees + */ + public function getConfigStudent() { + $moodle_link =$this->config->item('STG_MOODLE_LINK'); + + $ret = array( + 'moodle_link' => $moodle_link, + ); + + $this->terminateWithSuccess($ret); + } + + /** + * fetches all projektabgabetermine for a given projektarbeit_id used in cis4 student abgabetool & lektor abgabetool + */ + public function getStudentProjektabgaben() { + $projektarbeit_id = $this->input->get("projektarbeit_id",TRUE); + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + if ($projektarbeit_id === NULL || trim((string)$projektarbeit_id) === '') { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $result = $this->ProjektarbeitModel->load($projektarbeit_id); + $projektarbeitArr = $this->getDataOrTerminateWithError($result, 'general'); + + if(count($projektarbeitArr) > 0) { + $projektarbeit = $projektarbeitArr[0]; + } else { + $this->terminateWithError($this->p->t('abgabetool','c4projektarbeitNichtGefunden'), 'general'); + } + + $res = $this->ProjektarbeitModel->getStudentInfoForProjektarbeitId($projektarbeit_id); + if(isError($res)) { + $this->terminateWithError($this->p->t('abgabetool', 'c4errorLoadingStudentForProjektarbeitID'), 'general'); + } + + if(!hasData($res)) { + $this->terminateWithError($this->p->t('abgabetool', 'c4noAssignedStudentForProjektarbeitID'), 'general'); + } + $data = getData($res)[0]; + $student_uid = $data->uid; + + $zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID()); + if(getAuthUID() == $student_uid || $zugeordnet) { + $projektarbeitIsCurrent = false; + $returnFunc = function ($result) use (&$projektarbeitIsCurrent) { + $projektarbeitIsCurrent = $result; + }; + Events::trigger('projektarbeit_is_current', $projektarbeit_id, $returnFunc); + + $ret = $this->ProjektarbeitModel->getProjektarbeitAbgabetermine($projektarbeit_id); + + foreach ($ret->retval as $termin) { + $this->checkAbgabeSignatur($termin, $projektarbeit->student_uid); + } + + $this->terminateWithSuccess(array($ret, $projektarbeitIsCurrent)); + } + } + + /** + * fetches all projektarbeiten and betreuer for a given student_uid used in cis4 student abgabetool + */ + public function getStudentProjektarbeiten() + { + $uid = $this->input->get("uid",TRUE); + + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + // if uid is missing or empty, fall back to getAuthUID() + if ($uid === NULL || trim((string)$uid) === '') { + $uid = getAuthUID(); + } + + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID()); + if ($isMitarbeiter) { + $result = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer($uid); + } else { + $result = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer(getAuthUID()); + } + + $projektarbeiten = getData($result); + + if(count($projektarbeiten)) { + foreach($projektarbeiten as $pa) { + + $pa->student = getData($this->PersonModel->getFullName($uid)); + + $downloadPaFunc = function ($babgeschickt, $zweitbetreuer_abgeschickt) use ($pa) { + $pa->babgeschickt = $babgeschickt; + $pa->zweitbetreuer_abgeschickt = $zweitbetreuer_abgeschickt; + }; + + Events::trigger('projektbeurteilung_check_available', $pa->projektarbeit_id, $pa->bperson_id, $downloadPaFunc); + + if(isset($pa->babgeschickt) && $pa->babgeschickt) { + $downloadLink1 = ''; + $downloadLinkFunc1 = function ($link) use (&$downloadLink1) { + $downloadLink1 = $link; + }; + + Events::trigger('projektbeurteilung_download_link', $pa->projektarbeit_id, $pa->betreuerart_kurzbz, $pa->bperson_id, $downloadLinkFunc1); + + // use config fallback in case the event fails + if($downloadLink1 == '') { + $fallback = $this->config->item('beurteilung_link_fallback'); + + $search = array( + 'betreuerart_kurzbz=?', + 'projektarbeit_id=?', + 'person_id=?' + ); + + $replace = array( + 'betreuerart_kurzbz=' . $pa->betreuerart_kurzbz, + 'projektarbeit_id=' . $pa->projektarbeit_id, + 'person_id=' . $pa->bperson_id + ); + + $fallback = str_replace($search, $replace, $fallback); + $downloadLink1 = APP_ROOT.$fallback; + + } + $pa->downloadLink1 = $downloadLink1; + } + + $pa->email = $pa->mitarbeiter_uid.'@'.DOMAIN; + + if($pa->zweitbetreuer_person_id !== null) { + + if($pa->zweitbetreuer_abgeschickt) { + $downloadLink2 = ''; + $downloadLinkFunc2 = function ($link) use (&$downloadLink2) { + $downloadLink2 = $link; + }; + + Events::trigger('projektbeurteilung_download_link', $pa->projektarbeit_id, $pa->zweitbetreuer_betreuerart_kurzbz, $pa->zweitbetreuer_person_id, $downloadLinkFunc2); + + // use config fallback in case the event fails + if($downloadLink2 == '') { + $fallback = $this->config->item('beurteilung_link_fallback'); + + $search = array( + 'betreuerart_kurzbz=?', + 'projektarbeit_id=?', + 'person_id=?' + ); + + $replace = array( + 'betreuerart_kurzbz=' . $pa->zweitbetreuer_betreuerart_kurzbz, + 'projektarbeit_id=' . $pa->projektarbeit_id, + 'person_id=' . $pa->zweitbetreuer_person_id + ); + + $fallback = str_replace($search, $replace, $fallback); + $downloadLink2 = APP_ROOT.$fallback; + + } + + $pa->downloadLink2 = $downloadLink2; + } + + $result = $this->ProjektarbeitModel->getProjektbetreuerAnrede($pa->zweitbetreuer_person_id); + + $data = getData($result); + if(count($data) > 0) { + $pa->zweitbetreuer = $data[0]; + } + } + } + } + + $this->terminateWithSuccess(array($projektarbeiten)); + } + + + + /** + * projektarbeit - upload for zwischenabgaben in cis4 student abgabetool + */ + public function postStudentProjektarbeitZwischenabgabe() + { + $this->checkUploadSize(); + + $projektarbeit_id = $this->input->post('projektarbeit_id'); + $paabgabe_id = $this->input->post('paabgabe_id'); + $student_uid = $this->input->post('student_uid'); + $bperson_id = $this->input->post('bperson_id'); + $paabgabetyp_kurzbz = $this->input->post('paabgabetyp_kurzbz'); + + if ($projektarbeit_id === NULL || trim((string)$projektarbeit_id) === '' + || $paabgabe_id === NULL || trim((string)$paabgabe_id) === '' + || $student_uid === NULL || trim((string)$student_uid) === '' + || $paabgabetyp_kurzbz === NULL || trim((string)$paabgabetyp_kurzbz) === '') { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $this->checkProjektarbeitForFinishedStatus($projektarbeit_id); + + $zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID()); + if(getAuthUID() == $student_uid || $zugeordnet) { + + + $path = PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf'; + + if ((isset($_FILES) and isset($_FILES['file']) and ! $_FILES['file']['error'])) { + move_uploaded_file($_FILES['file']['tmp_name'], $path); + + if(file_exists($path)) { + + chmod($path, 0640); + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + $res = $this->PaabgabeModel->update($paabgabe_id, array( + 'abgabedatum' => date('Y-m-d'), + 'updatevon' => getAuthUID(), + 'updateamum' => date('Y-m-d H:i:s') + )); + + $this->logLib->logInfoDB(array('zwischenupload',$res, array( + 'abgabedatum' => date('Y-m-d'), + 'updatevon' => getAuthUID(), + 'updateamum' => date('Y-m-d H:i:s') + ), getAuthUID(), getAuthPersonId(), $student_uid)); + + $this->terminateWithSuccess($res); + } else { + $this->terminateWithError('Error moving File', 'general'); + } + + } else { + $this->terminateWithError('File missing', 'general'); + } + } else { + $this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent')); + } + +} + + /** + * upload für finale abgaben aka Endupload in cis4 student abgabetool + */ + public function postStudentProjektarbeitEndupload() + { + $this->checkUploadSize(); + + $projektarbeit_id = $this->input->post('projektarbeit_id'); + $paabgabe_id = $this->input->post('paabgabe_id'); + $student_uid = $this->input->post('student_uid'); + $sprache = $this->input->post('sprache'); + $abstract = $this->input->post('abstract'); + $abstract_en = $this->input->post('abstract_en'); + $schlagwoerter = $this->input->post('schlagwoerter'); + $schlagwoerter_en = $this->input->post('schlagwoerter_en'); + $seitenanzahl = $this->input->post('seitenanzahl'); + $bperson_id = $this->input->post('bperson_id'); + $paabgabetyp_kurzbz = $this->input->post('paabgabetyp_kurzbz'); + + if ($projektarbeit_id === NULL || trim((string)$projektarbeit_id) === '' + || $paabgabe_id === NULL || trim((string)$paabgabe_id) === '' + || $student_uid === NULL || trim((string)$student_uid) === '' + || $paabgabetyp_kurzbz === NULL || trim((string)$paabgabetyp_kurzbz) === '' + || $abstract === NULL || $abstract_en === NULL + || $schlagwoerter === NULL || $schlagwoerter_en === NULL + || $seitenanzahl === NULL || $sprache === NULL) { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $this->checkPaabgabeDeadline($paabgabe_id); + + $this->checkProjektarbeitForFinishedStatus($projektarbeit_id); + + $zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID()); + if(getAuthUID() == $student_uid || $zugeordnet) { + if ((isset($_FILES) and isset($_FILES['file']) and !$_FILES['file']['error'])) { + move_uploaded_file($_FILES['file']['tmp_name'], PAABGABE_PATH . $paabgabe_id . '_' . $student_uid . '.pdf'); + + if (file_exists(PAABGABE_PATH . $paabgabe_id . '_' . $student_uid . '.pdf')) { + + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + $result = $this->ProjektarbeitModel->load($projektarbeit_id); + $projektarbeitArr = $this->getDataOrTerminateWithError($result, 'general'); + + if (count($projektarbeitArr) > 0) { + $projektarbeit = $projektarbeitArr[0]; + } else { + $this->terminateWithError($this->p->t('abgabetool', 'c4projektarbeitNichtGefunden'), 'general'); + } + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + $result = $this->PaabgabeModel->load($paabgabe_id); + $paabgabeArr = $this->getDataOrTerminateWithError($result, 'general'); + + if (count($paabgabeArr) > 0) { + $paabgabe = $paabgabeArr[0]; + } else { + $this->terminateWithError($this->p->t('abgabetool', 'c4projektabgabeNichtGefunden'), 'general'); + } + + $this->checkAbgabeSignatur($paabgabe, $projektarbeit->student_uid); + $signaturstatus = $paabgabe->signatur; + + // update projektarbeit cols + $this->ProjektarbeitModel->updateProjektarbeit($projektarbeit_id, $sprache, $abstract, $abstract_en + , $schlagwoerter, $schlagwoerter_en, $seitenanzahl); + + + // update paabgabe datum + $res = $this->PaabgabeModel->update($paabgabe_id, array( + 'abgabedatum' => date('Y-m-d'), + 'updatevon' => getAuthUID(), + 'updateamum' => date('Y-m-d H:i:s') + )); + + $res = $this->PaabgabeModel->load($res->retval); + $abgabe = getData($res)[0]; + $abgabe->signatur = $signaturstatus; + + $this->sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid); + + $this->logLib->logInfoDB(array('endupload', $res, array( + 'abgabedatum' => date('Y-m-d'), + 'updatevon' => getAuthUID(), + 'updateamum' => date('Y-m-d H:i:s') + ), getAuthUID(), getAuthPersonId(), array($projektarbeit_id, $sprache, $abstract, $abstract_en + , $schlagwoerter, $schlagwoerter_en, $seitenanzahl))); + + $this->terminateWithSuccess($abgabe); + } else { + $this->terminateWithError('Error moving File', 'general'); + } + + } else { + $this->terminateWithError('File missing', 'general'); + } + } else { + $this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent')); + } + + } + + // validate paabgabe deadline against servertime just in case a student spoofs their local clock and thus + // unlocks the upload ui + private function checkPaabgabeDeadline($paabgabe_id) { + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + + $result = $this->PaabgabeModel->load($paabgabe_id); + $paabgabeArr = $this->getDataOrTerminateWithError($result, 'general'); + + if (count($paabgabeArr) > 0) { + $paabgabe = $paabgabeArr[0]; + } else { + $this->terminateWithError($this->p->t('abgabetool', 'c4projektabgabeNichtGefunden'), 'general'); + } + + // in that case any submission date is fine + if($paabgabe->fixtermin === false) return; + + $tz = new DateTimeZone('Europe/Berlin'); + $now = new DateTimeImmutable('now', $tz); + $deadline = DateTimeImmutable::createFromFormat( + 'Y-m-d H:i:s', + $paabgabe->datum . ' 23:59:59', + $tz + ); + + if($now >= $deadline) { + $this->terminateWithError($this->p->t('abgabetool', 'c4deadlineExceeded')); + } + } + + /** + * tabulator tabledata fetch for abgabetool/mitarbeiter + * initially fetches all currently active projektarbeiten with assigned mentorship + * showAll functionality also retrieves older finished projektarbeiten + */ + public function getMitarbeiterProjektarbeiten() { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + $boolParamStr = $this->input->get('showall'); + $trueStrings = ['true', '1']; + $falseStrings = ['false', '0']; + + // Handle missing or invalid parameter + if ($boolParamStr === null) { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + $boolParamStrLower = strtolower($boolParamStr); + + $showAllBool = false; // fallback if input strings are anything else for whatever reason + if (in_array($boolParamStrLower, $trueStrings, true)) { + $showAllBool = true; + } elseif (in_array($boolParamStrLower, $falseStrings, true)) { + $showAllBool = false; + } + + $projektarbeiten = $this->ProjektarbeitModel->getMitarbeiterProjektarbeiten(getAuthUID(), $showAllBool); + + + $mapFunc = function($projektarbeit) { + return $projektarbeit->projektarbeit_id; + }; + $projektarbeiten_ids = array_map($mapFunc, $projektarbeiten->retval); + + if(count($projektarbeiten_ids) > 0) { + $ret = $this->ProjektarbeitModel->getProjektarbeitenAbgabetermine($projektarbeiten_ids); + $projektabgaben = $this->getDataOrTerminateWithError($ret, 'general'); + } + + forEach($projektarbeiten->retval as $pa) { + + $result = $this->ProjektarbeitModel->getProjektbetreuerAnrede($pa->betreuer_person_id); + $anredeArr = $this->getDataOrTerminateWithError($result, 'general'); + $pa->betreuer = $anredeArr[0]; + + $oldLink = ''; // show this when paIsCurrent == false -> moodle course template + $newLink = ''; // get curated path for betreuer type + $returnFunc = function ( $resultOld, $resultNew) use (&$oldLink, &$newLink) { + $newLink = $resultNew; + $oldLink = $resultOld; + }; + + Events::trigger('projektbeurteilung_formular_link', $pa->betreuerart_kurzbz, APP_ROOT, $pa->projektarbeit_id, $pa->student_uid, $returnFunc); + $pa->beurteilungLinkNew = $newLink; + $pa->beurteilungLinkOld = $oldLink; + + // has previously been retrieved via getStudentProjektabgaben but is fetched in advance to avoid having to reload abgaben + $projektarbeitIsCurrent = false; + $returnFunc = function ($result) use (&$projektarbeitIsCurrent) { + $projektarbeitIsCurrent = $result; + }; + Events::trigger('projektarbeit_is_current', $pa->projektarbeit_id, $returnFunc); + $pa->isCurrent = $projektarbeitIsCurrent; + + $filterFunc = function($projektabgabe) use ($pa) { + return $projektabgabe->projektarbeit_id == $pa->projektarbeit_id; + }; + + $pa->abgabetermine = array_values(array_filter($projektabgaben, $filterFunc)); + } + + + $this->terminateWithSuccess(array($projektarbeiten, DOMAIN)); + } + + /** + * called by abgabetool/mitarbeiter in mitarbeiterdetail.js when adding a single new abgabetermin + * initially fetches all + */ + public function postProjektarbeitAbgabe() { + $projektarbeit_id = $this->input->post('projektarbeit_id'); + $paabgabe_id = $this->input->post('paabgabe_id'); + $paabgabetyp_kurzbz = $this->input->post('paabgabetyp_kurzbz'); + $datum = $this->input->post('datum'); + $fixtermin = $this->input->post('fixtermin'); + $kurzbz = $this->input->post('kurzbz'); + $note = $this->input->post('note'); + $beurteilungsnotiz = $this->input->post('beurteilungsnotiz'); + $upload_allowed = $this->input->post('upload_allowed'); + $betreuer_person_id = $this->input->post('betreuer_person_id'); + + if ($projektarbeit_id === NULL || trim((string)$projektarbeit_id) === '' + || $paabgabe_id === NULL || trim((string)$paabgabe_id) === '' + || $datum === NULL || trim((string)$datum) === '' + || $kurzbz === NULL + || $paabgabetyp_kurzbz === NULL || trim((string)$paabgabetyp_kurzbz) === '') { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $this->checkProjektarbeitForFinishedStatus($projektarbeit_id); + + $zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID()); + if(!$zugeordnet) { + $this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent')); + } + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + + $existingPaabgabe = null; + if($paabgabe_id == -1) { + $result = $this->PaabgabeModel->insert( + array( + 'projektarbeit_id' => $projektarbeit_id, + 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, + 'fixtermin' => $fixtermin, + 'datum' => $datum, + 'kurzbz' => $kurzbz, + 'note' => $note, + 'beurteilungsnotiz' => $beurteilungsnotiz, + 'upload_allowed' => $upload_allowed, + 'insertvon' => getAuthUID(), + 'insertamum' => date('Y-m-d H:i:s') + ) + ); + $this->logLib->logInfoDB(array('paabgabe created',array( + 'projektarbeit_id' => $projektarbeit_id, + 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, + 'fixtermin' => $fixtermin, + 'datum' => $datum, + 'kurzbz' => $kurzbz, + 'note' => $note, + 'beurteilungsnotiz' => $beurteilungsnotiz, + 'upload_allowed' => $upload_allowed, + 'insertvon' => getAuthUID(), + 'insertamum' => date('Y-m-d H:i:s') + ), getAuthUID(), getAuthPersonId())); + } else { + // load existing entry of paabgabe and check if note has changed to negativ, to avoid sending when + // only notiz has changed. + + // TODO: what if paabgabe is a qualgate1, is benotet negativ and then its type is changed to gate2? + + $existingResult = $this->PaabgabeModel->load($paabgabe_id); + $existingPaabgabeArr = getData($existingResult); + if(count($existingPaabgabeArr) > 0) $existingPaabgabe = $existingPaabgabeArr[0]; + + $result = $this->PaabgabeModel->update( + $paabgabe_id, + array( + 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, + 'datum' => $datum, + 'kurzbz' => $kurzbz, + 'note' => $note, + 'fixtermin' => $fixtermin, + 'beurteilungsnotiz' => $beurteilungsnotiz, + 'upload_allowed' => $upload_allowed, + 'updatevon' => getAuthUID(), + 'updateamum' => date('Y-m-d H:i:s') + ) + ); + + $this->logLib->logInfoDB(array('paabgabe updated',$result, array( + 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, + 'datum' => $datum, + 'kurzbz' => $kurzbz, + 'note' => $note, + 'fixtermin' => $fixtermin, + 'beurteilungsnotiz' => $beurteilungsnotiz, + 'upload_allowed' => $upload_allowed, + 'updatevon' => getAuthUID(), + 'updateamum' => date('Y-m-d H:i:s') + ), getAuthUID(), getAuthPersonId())); + } + + // check if $paaabgabe is a qual gate and its note is deemed negative + // -> send email to student with that info + $paabgabe_id = $this->getDataOrTerminateWithError($result, 'general'); + + $result = $this->PaabgabeModel->load($paabgabe_id); + $paabgabeArr = $this->getDataOrTerminateWithError($result, 'general'); + $paabgabe = $paabgabeArr[0]; + + // check if abgabe even has note + if($paabgabe->note) { + $this->load->model('education/Note_model', 'NoteModel'); + $result = $this->NoteModel->load($paabgabe->note); + $noteArr = $this->getDataOrTerminateWithError($result, 'general'); + $note = $noteArr[0]; + if($note->positiv === false) { + + if($existingPaabgabe && $existingPaabgabe->note) { + $result = $this->NoteModel->load($paabgabe->note); + $noteArr = $this->getDataOrTerminateWithError($result, 'general'); + $note = $noteArr[0]; + if($note->positiv === false) { + // do nothing since this means $beurteilungsnotiz change or smth else + } else { // benotung legitimately changed -> email + $this->sendQualGateNegativEmail($projektarbeit_id, $betreuer_person_id, $paabgabe); + } + } else { // nothing existing previously -> send that mail + $this->sendQualGateNegativEmail($projektarbeit_id, $betreuer_person_id, $paabgabe); + } + + } + } + + $this->terminateWithSuccess([$paabgabe, $existingPaabgabe]); + } + + /** + * called by abgabetool/mitarbeiter in mitarbeiterdetail.js when deleting an abgabetermin + * deletion is only possible if user is assistenz OR betreuer deletes their own custom termin + * none of these roles are allowed to delete if students uploaded something for that termin + */ + public function deleteProjektarbeitAbgabe() { + $paabgabe_id = $this->input->post('paabgabe_id'); + + if ($paabgabe_id === NULL || trim((string)$paabgabe_id) === '') { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $this->checkProjektarbeitForFinishedStatus($this->getProjektarbeitIDForPaabgabeID($paabgabe_id)); + + $zugeordnet = $this->checkZuordnungByPaabgabe($paabgabe_id, getAuthUID()); + + if(!$zugeordnet) { + $this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent'), 'general'); + } + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + + $paabgabeResult = $this->PaabgabeModel->load($paabgabe_id); + $paabgabeArr = $this->getDataOrTerminateWithError($paabgabeResult, 'general'); + + if(count($paabgabeArr) == 0) { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $result = $this->PaabgabeModel->delete($paabgabe_id); + $result = $this->getDataOrTerminateWithError($result, 'general'); + + // TODO: consider this in nightly email job + $this->logLib->logInfoDB(array($paabgabeArr[0], getAuthUID(), getAuthPersonId())); + $this->terminateWithSuccess($result); + } + + /** + * endpoint for adding the same paabgabe for multiple projektarbeiten + * can be slow for large n since it queries twice per projektarbeit_id + */ + public function postSerientermin() { + $projektarbeit_ids = $this->input->post('projektarbeit_ids'); + $datum = $this->input->post('datum'); + $paabgabetyp_kurzbz = $this->input->post('paabgabetyp_kurzbz'); + $bezeichnung = $this->input->post('bezeichnung'); + $kurzbz = $this->input->post('kurzbz'); + $fixtermin = $this->input->post('fixtermin'); + $upload_allowed = $this->input->post('upload_allowed'); + + if ($projektarbeit_ids === NULL || !is_array($projektarbeit_ids) || empty($projektarbeit_ids) + || $datum === NULL || trim((string)$datum) === '' + || $kurzbz === NULL + || $bezeichnung === NULL || trim((string)$bezeichnung) === '' + || $paabgabetyp_kurzbz === NULL || trim((string)$paabgabetyp_kurzbz) === '') { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + // old script checks if there already are tbl_paabgabe entries with exact date, type & kurzbz + // for each termin - good to check that in principle but should not matter in this place. if necessary + // duplicate abgabetermine can be easily deleted manually, also via cronjob@night. + + // since this entry includes the kurzbz string match, it should have only ever mattered when there were + // multiple users entering the exact same set of (date, type, kurzbz) - which is a much more narrow case than the + // general "saveMultiple" function should handle + + // old script afterwards again queries if user is not the zweitbetreuer of any id - this is blocked in the ui + // and should never unintentionally happen + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + $res = []; + $abgaben = []; + foreach ($projektarbeit_ids as $projektarbeit_id) { + + $this->checkProjektarbeitForFinishedStatus($projektarbeit_id); + + $zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID()); + if(!$zugeordnet) { + $this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent'), 'general'); + } + + $result = $this->PaabgabeModel->insert( + array( + 'projektarbeit_id' => $projektarbeit_id, + 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, + 'fixtermin' => $fixtermin, + 'datum' => $datum, + 'kurzbz' => $kurzbz, + 'upload_allowed' => $upload_allowed, + 'insertvon' => getAuthUID(), + 'insertamum' => date('Y-m-d H:i:s') + ) + ); + + $dataAbgabe = $this->getDataOrTerminateWithError($result, 'general'); + + $abgaben[]= getData($this->PaabgabeModel->load($dataAbgabe))[0]; + } + + $this->logLib->logInfoDB(array('serientermin angelegt',array( + 'projektarbeit_id' => $projektarbeit_id, + 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, + 'fixtermin' => $fixtermin, + 'datum' => $datum, + 'kurzbz' => $kurzbz, + 'upload_allowed' => $upload_allowed, + 'insertvon' => getAuthUID(), + 'insertamum' => date('Y-m-d H:i:s') + ), getAuthUID(), getAuthPersonId())); + + $this->terminateWithSuccess($abgaben); + } + + /** + * called by Abgabetool/Deadlines + * fetches the next upcoming abgabtermine for a given betreuer person_id + * resembles the legacy abgabetool functionality of "show deadlines" + */ + public function fetchDeadlines() { + $person_id = $this->input->post('person_id'); + + if ($person_id === NULL || trim((string)$person_id) === '') { + $person_id = getAuthPersonId(); + } + + if($person_id !== getAuthPersonId()) { + $this->load->library('PermissionLib'); + $isAdmin = $this->permissionlib->isBerechtigt('admin'); + if(!$isAdmin) $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general'); + } + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + $result = $this->PaabgabeModel->getDeadlines($person_id); + $data = $this->getDataOrTerminateWithError($result, 'general'); + + $this->terminateWithSuccess($data); + } + + /** + * called by Abgabetool/Mitarbeiter & Abgabetool/Assistenz + * fetches all available paabgabetypen to enable a logical selection of them + * based on active status and role assistenz/betreuer + */ + public function getPaAbgabetypen() { + $this->load->model('education/Paabgabetyp_model', 'PaabgabetypModel'); + + $result = $this->PaabgabetypModel->getAll(); + $paabgabetypen = $this->getDataOrTerminateWithError($result, 'general'); + + + $this->terminateWithSuccess($paabgabetypen); + } + + /** + * helper function to fetch the correct email for a projektarbeits erstbetreuer + */ + private function getProjektbetreuerEmailByProjektarbeitID($projektarbeit_id) { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + $result = $this->ProjektarbeitModel->getProjektbetreuerEmail($projektarbeit_id); + if(count($result->retval) > 0) { + $email = getData($result); + return $email[0]->uid ? $email[0]->uid.'@'.DOMAIN : $email[0]->private_email; + } else return ''; + + } + + /** + * helper function to fetch the correct email for a projektarbeits zweitbetreuer by their person id + * can be used for erstbetreuer aswell if necessary + */ + private function getProjektbetreuerEmailByPersonID($person_id) { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + $result = $this->ProjektarbeitModel->getProjektbetreuerEmailByPersonID($person_id); + $email = $this->getDataOrTerminateWithError($result, 'general'); + + return $email[0]->uid ? $email[0]->uid.'@'.DOMAIN : $email[0]->private_email; + } + + //TODO: SWITCH TO NOTEN API ONCE NOTENTOOL IS IN MASTER TO AVOID DUPLICATE API + + /** + * GET METHOD + * returns List of all available & active NotenOptions + */ + public function getNoten() { + $this->load->model('education/Note_model', 'NoteModel'); + + $result = $this->NoteModel->getAllActive(); + $noten = $this->getDataOrTerminateWithError($result, 'general'); + + $allowed_noten_abgabetool = $this->config->item('ALLOWED_NOTEN_ABGABETOOL'); + + $nonfinal_noten_abgabetool = $this->config->item('NONFINAL_NOTEN_ABGABETOOL'); + + + $this->terminateWithSuccess(array($noten, $allowed_noten_abgabetool, $nonfinal_noten_abgabetool)); + } + + /** + * helper function to send a sancho mail to students if a betreuer or assistenz grades a quality gate + * termin as negative (nicht bestanden) + */ + private function sendQualGateNegativEmail($projektarbeit_id, $betreuer_person_id, $paabgabe) { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + $result = $this->ProjektarbeitModel->load($projektarbeit_id); + $projektarbeitArr = $this->getDataOrTerminateWithError($result, 'general'); + $projektarbeit = $projektarbeitArr[0]; + + $result = $this->ProjektarbeitModel->getProjektbetreuerAnrede($betreuer_person_id); + $anredeArr = $this->getDataOrTerminateWithError($result, 'general'); + $anrede = $anredeArr[0]; + + $student_uid = $projektarbeit->student_uid; + + $this->load->model('education/Paabgabetyp_model', 'PaabgabetypModel'); + $result = $this->PaabgabetypModel->load($paabgabe->paabgabetyp_kurzbz); + $paabgabetyp_kurzbzArr = $this->getDataOrTerminateWithError($result, 'general'); + $paabgabetyp_kurzbz = $paabgabetyp_kurzbzArr[0]; + + // Mail an Student wenn Qualgate negativ beurteilt wurde + $this->load->model('crm/Student_model', 'StudentModel'); + $result = $this->StudentModel->load([$student_uid]); + $studentArr = $this->getDataOrTerminateWithError($result, 'general'); + $student = $studentArr[0]; + + if(!$student) { + $this->terminateWithError($this->p->t('abgabetool','c4userNichtGefunden'), 'general'); + } + + $subject = $this->p->t('abgabetool', 'c4qualgateNegativEmailSubjectv2'); + $tomail = $student_uid.'@'.DOMAIN; + + $datetime = new DateTime($paabgabe->datum); + $dateEmailFormatted = $datetime->format('d.m.Y'); + + $data = array( + 'betreuerfullname' => $anrede->first, + 'qualgatebezeichnung' => $paabgabetyp_kurzbz->bezeichnung, + 'datum' => $dateEmailFormatted, + 'projektarbeitname' => $projektarbeit->titel + ); + + // students still get theirs on event, since it is very unlikely that this + // leads to spam on their end + + $mailres = sendSanchoMail( + 'QualGateNegativ', + $data, + $tomail, + $subject + ); + + } + + /** + * tabulator tabledata fetch for abgabetool/assistenz + * initially fetches all ungraded projektarbeiten with all their abgabetermine + */ + public function getProjektarbeitenForStudiengang() { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + $studiengang_kz = $this->input->get("studiengang_kz", TRUE); + $benotet = $this->input->get("benotet", TRUE); + + if ($studiengang_kz === NULL || trim((string)$studiengang_kz) === '') { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + // TODO: recheck getSTGEntitlement here! + $stg_allowed = $this->permissionlib->getSTG_isEntitledFor('basis/abgabe_assistenz:rw'); + if($stg_allowed == false) { + $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general'); + } + + // check if provided studiengang_kz is included in stg_allowed to proceed + if(!in_array($studiengang_kz, $stg_allowed)) { + $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general'); + } + + $result = $this->ProjektarbeitModel->getProjektarbeitenForStudiengang($studiengang_kz, $benotet); + $projektarbeiten = $this->getDataOrTerminateWithError($result, 'general'); + + if(count($projektarbeiten) == 0) { // avoid further abgabetermin queries if the are no projektarbeiten + $this->terminateWithSuccess(array($projektarbeiten, DOMAIN)); + } + + $mapFunc = function($projektarbeit) { + return $projektarbeit->projektarbeit_id; + }; + $projektarbeiten_ids = array_map($mapFunc, $projektarbeiten); + + $ret = $this->ProjektarbeitModel->getProjektarbeitenAbgabetermine($projektarbeiten_ids); + $projektabgaben = $this->getDataOrTerminateWithError($ret, 'general'); + + // map the abgaben into projektarbeiten + foreach($projektarbeiten as $projektarbeit) { + $projektarbeit->betreuer_mail = $this->getProjektbetreuerEmailByProjektarbeitID($projektarbeit->projektarbeit_id); + + if($projektarbeit->zweitbetreuer_person_id !== null) { + $projektarbeit->zweitbetreuer_mail = $this->getProjektbetreuerEmailByPersonID($projektarbeit->zweitbetreuer_person_id); + } + + $filterFunc = function($projektabgabe) use ($projektarbeit) { + return $projektabgabe->projektarbeit_id == $projektarbeit->projektarbeit_id; + }; + + $projektarbeit->abgabetermine = array_values(array_filter($projektabgaben, $filterFunc)); + } + + $this->terminateWithSuccess(array($projektarbeiten, DOMAIN)); + } + + // TODO: this could be in a generic info controller and reused + /** + * GET METHOD + * returns List of all studiengang_kz a user has the assigned permission 'basis/abgabe_assistenz:rw' for + * used in Abgabetool/Assistenz to populate Studiengang Dropdown + */ + public function getStudiengaenge() { + $this->load->library('PermissionLib'); + + $stg_allowed = $this->permissionlib->getSTG_isEntitledFor('basis/abgabe_assistenz:rw'); + + if($stg_allowed == false) { + $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general'); + } + + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + + $result = $this->StudiengangModel->getStudiengaengeFiltered($stg_allowed); + $data = $this->getDataOrTerminateWithError($result, 'general'); + + $this->terminateWithSuccess($data); + } + + /** + * GET METHOD + * endpoint to download the abgabe of a paabgabe termin zwischenabgabe or endupload + */ + public function getStudentProjektarbeitAbgabeFile() + { + $this->load->helper('download'); + + $projektarbeit_id = $this->input->get('projektarbeit_id'); + $paabgabe_id = $this->input->get('paabgabe_id'); + $student_uid = $this->input->get('student_uid'); + + if ($paabgabe_id === NULL || trim((string)$paabgabe_id) === '' + || $projektarbeit_id === NULL || trim((string)$projektarbeit_id) === '' + || $student_uid === NULL || trim((string)$student_uid) === '') { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + // zuordnung function is supposed for mitarbeiter_uids, students should be allowed to download their own files + // without adapting zuordnung logic + $zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID()); + if(getAuthUID() == $student_uid || $zugeordnet) { + $file_path = PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf'; + + + if(file_exists($file_path)) { + $this->terminateWithFileOutput('application/octet-stream', file_get_contents($file_path), basename($file_path)); + } else { + $this->terminateWithError('File not found', 'general'); + } + } else { + $this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent'), 'general'); + } + } + + /** + * POST METHOD + * endpoint to enable Assistenz/Betreuer to edit the zusatzdate of a projektarbeit, in case the student somehow + * can't do it themself + */ + public function postStudentProjektarbeitZusatzdaten(){ + $projektarbeit_id = $this->input->post('projektarbeit_id'); + $sprache = $this->input->post('sprache'); + $abstract = $this->input->post('abstract'); + $abstract_en = $this->input->post('abstract_en'); + $schlagwoerter = $this->input->post('schlagwoerter'); + $schlagwoerter_en = $this->input->post('schlagwoerter_en'); + $seitenanzahl = $this->input->post('seitenanzahl'); + + if ($projektarbeit_id === NULL || trim((string)$projektarbeit_id) === '' + || $sprache === NULL || trim((string)$sprache) === '' + || $seitenanzahl === NULL || trim((string)$seitenanzahl) === '' + || $abstract === NULL || trim((string)$abstract) === '' + || $abstract_en === NULL || trim((string)$abstract_en) === '' + || $schlagwoerter === NULL || trim((string)$schlagwoerter) === '' + || $schlagwoerter_en === NULL || trim((string)$schlagwoerter_en) === '') { + + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + + + $result = $this->ProjektarbeitModel->load($projektarbeit_id); + $projektarbeitArr = $this->getDataOrTerminateWithError($result, 'general'); + + if(count($projektarbeitArr) > 0) { + $projektarbeit = $projektarbeitArr[0]; + } else { + $this->terminateWithError($this->p->t('abgabetool','c4projektarbeitNichtGefunden'), 'general'); + } + + $this->checkProjektarbeitForFinishedStatus($projektarbeit_id); + + $zugeordnet = $this->checkZuordnung($projektarbeit_id, getAuthUID()); + if(!$zugeordnet) { + $this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent'), 'general'); + } + + // update projektarbeit cols + $this->ProjektarbeitModel->updateProjektarbeit($projektarbeit_id,$sprache,$abstract,$abstract_en + ,$schlagwoerter, $schlagwoerter_en, $seitenanzahl); + + $this->logLib->logInfoDB(array('zusatzdatenEditMitarbeiter', array( + 'updatevon' => getAuthUID(), + 'updateamum' => date('Y-m-d H:i:s') + ), getAuthUID(), getAuthPersonId(), array($projektarbeit_id,$sprache,$abstract,$abstract_en + ,$schlagwoerter, $schlagwoerter_en, $seitenanzahl))); + + $result = $this->ProjektarbeitModel->load($projektarbeit_id); + + $this->terminateWithSuccess($result); + } + + // used to lazy load signatur status for assistenzen, since they could run into very long fetch times + // since they fetch the projektarbeiten with paabgaben included and could have a lot of huge endupload files + // in their stg resulting in huge loading times -> use this api call on opening detail component instead + public function getSignaturStatusForProjektarbeitAbgaben() { + $paabgabe_ids = $this->input->post('paabgabe_ids'); + $student_uid = $this->input->post('student_uid'); + + if ($paabgabe_ids === NULL || $student_uid === NULL || trim((string)$student_uid) === '') { + $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); + } + + $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); + + $result = $this->PaabgabeModel->loadByIDs($paabgabe_ids); + $data = $this->getDataOrTerminateWithError($result); + + foreach($data as $paabgabetermin) { + $this->checkAbgabeSignatur($paabgabetermin, $student_uid); + } + + $this->terminateWithSuccess($data); + } + + /** + * helper function to check the signature status of uploaded files for zwischenabgabe & endupload + */ + private function checkAbgabeSignatur($abgabe, $student_uid) { + $paabgabetypenToCheck = $this->config->item('SIGNATUR_CHECK_PAABGABETYPEN'); + + if(!in_array($abgabe->paabgabetyp_kurzbz, $paabgabetypenToCheck)) { + return; + } + + if (!defined('SIGNATUR_URL')) { + $abgabe->signatur = 'error'; + return; + } + + $path = PAABGABE_PATH.$abgabe->paabgabe_id.'_'.$student_uid.'.pdf'; + + $signaturVorhanden = null; // if frontend receives null -> indicates no file found at path + if(file_exists($path)) { + + // Check if the document is signed + $signList = SignatureLib::list($path); + if (is_array($signList) && count($signList) > 0) + { + // The document is signed + $signaturVorhanden = true; + } + elseif ($signList === null) + { + // frontend knows to handle it this way for signatures + $signaturVorhanden = 'error'; + } + else + { + $signaturVorhanden = false; + } + + $abgabe->signatur = $signaturVorhanden; + } + } + + private function sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid) { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + $resBetr = $this->ProjektarbeitModel->getProjektbetreuerAnrede($bperson_id); + + + $result = $this->ProjektarbeitModel->load($projektarbeit_id); + $projektarbeitArr = $this->getDataOrTerminateWithError($result, 'general'); + + if(count($projektarbeitArr) > 0) { + $projektarbeit = $projektarbeitArr[0]; + } else { + $this->terminateWithError($this->p->t('abgabetool','c4projektarbeitNichtGefunden'), 'general'); + } + + $projektarbeitIsCurrent = false; + $returnFunc = function ($result) use (&$projektarbeitIsCurrent) { + $projektarbeitIsCurrent = $result; + }; + Events::trigger('projektarbeit_is_current', $projektarbeit_id, $returnFunc); + if(!$projektarbeitIsCurrent) { + $this->terminateWithError($this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeit'), 'general'); + } + + // Link to Abgabetool + if (defined('CIS4') && CIS4) { + $ci3BootstrapFilePath = "cis.php"; + } else { + $ci3BootstrapFilePath = "index.ci.php"; + } + + $path = $this->config->item('URL_MITARBEITER'); + $url = APP_ROOT.$path; + + // getProjektbetreuerAnrede fetches distinct on person_id, so there should be one row. zweitbetreuer is handled seperately afterwards + foreach($resBetr->retval as $betreuerRow) { + + // query student benutzer view for every betreuer row + $studentUser = $this->ProjektarbeitModel->getProjektarbeitBenutzer($student_uid)->retval[0]; + + // 1. Begutachter mail ohne Token + $mail_baselink = APP_ROOT.$this->config->item('PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ERSTBEGUTACHTER'); +// $mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter"; + $mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$studentUser->uid; + $projekttyp_kurzbz = $projektarbeit->projekttyp_kurzbz; + $subject = $projektarbeit->projekttyp_kurzbz == 'Diplom' ? 'Masterarbeitsbetreuung' : 'Bachelorarbeitsbetreuung'; + $abgabetyp = $paabgabetyp_kurzbz == 'end' ? 'Endabgabe' : 'Zwischenabgabe'; + + $maildata = array(); + $maildata['geehrt'] = "geehrte".($betreuerRow->anrede=="Herr"?"r":""); + $maildata['anrede'] = $betreuerRow->anrede; + $maildata['betreuer_voller_name'] = $betreuerRow->first; + $maildata['student_anrede'] = $studentUser->anrede; + $maildata['student_voller_name'] = trim($studentUser->titelpre." ".$studentUser->vorname." ".$studentUser->nachname." ".$studentUser->titelpost); + $maildata['abgabetyp'] = $abgabetyp; + $maildata['parbeituebersichtlink'] = "

Zur Projektarbeitsübersicht

"; + $maildata['bewertunglink'] = $projektarbeitIsCurrent && $paabgabetyp_kurzbz == 'end' ? "

Zur Beurteilung der Arbeit

" : ""; + $maildata['token'] = ""; + + $email = $this->getProjektbetreuerEmailByProjektarbeitID($projektarbeit_id); + + if(!$email) $this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailBegutachterv2'), 'general'); + + $mailres = sendSanchoMail( + 'ParbeitsbeurteilungEndupload', + $maildata, + $email, + $subject, + 'sancho_header_min_bw.jpg', + 'sancho_footer_min_bw.jpg', + get_uid()."@".DOMAIN); + + if(!$mailres) + { + $this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailBegutachterv2'), 'general'); + } + + // 2. Begutachter mail, wenn Endabgabe, mit Token wenn extern + if ($paabgabetyp_kurzbz == 'end') + { + // Zweitbegutachter holen + $this->load->model('education/Projektbetreuer_model', 'ProjektbetreuerModel'); + $zweitbegutachterRetval = getData($this->ProjektbetreuerModel->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $studentUser->uid)); + + if ($zweitbegutachterRetval && count($zweitbegutachterRetval) > 0) + { + + foreach ($zweitbegutachterRetval as $begutachter) + { + // token generieren, wenn noch nicht vorhanden und notwendig (wird in methode überprüft) + $tokenGenRes = $this->ProjektbetreuerModel->generateZweitbegutachterToken($begutachter->person_id, $projektarbeit_id); + + if (!$tokenGenRes) + { + $this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailZweitBegutachterv2'), 'general'); + } + + $begutachterMitTokenRetval = getData($this->ProjektbetreuerModel->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $studentUser->uid, $begutachter->person_id)); + + if (!$begutachterMitTokenRetval && count($begutachterMitTokenRetval) <= 0) + { + $this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailZweitBegutachterv2'), 'general'); + } + + $begutachterMitToken = $begutachterMitTokenRetval[0]; + + $path = $begutachterMitToken->betreuerart_kurzbz == 'Zweitbegutachter' ? 'ProjektarbeitsbeurteilungZweitbegutachter' : 'ProjektarbeitsbeurteilungErstbegutachter'; + $mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/$path"; + $mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$studentUser->uid; + $intern = isset($begutachterMitToken->uid); + $mail_link = $intern ? $mail_fulllink : $mail_baselink; + + $zweitbetmaildata = array(); + $zweitbetmaildata['geehrt'] = "geehrte" . ($begutachterMitToken->anrede == "Herr" ? "r" : ""); + $zweitbetmaildata['anrede'] = $begutachterMitToken->anrede; + $zweitbetmaildata['betreuer_voller_name'] = $begutachterMitToken->voller_name; + $zweitbetmaildata['student_anrede'] = $maildata['student_anrede']; + $zweitbetmaildata['student_voller_name'] = $maildata['student_voller_name']; + $zweitbetmaildata['abgabetyp'] = $abgabetyp; + $zweitbetmaildata['parbeituebersichtlink'] = $intern ? $maildata['parbeituebersichtlink'] : ""; + $zweitbetmaildata['bewertunglink'] = $projektarbeitIsCurrent ? "

Zur Beurteilung der Arbeit

" : ""; + $zweitbetmaildata['token'] = $projektarbeitIsCurrent && isset($begutachterMitToken->zugangstoken) && !$intern ? "

Zugangstoken: " . $begutachterMitToken->zugangstoken . "

" : ""; + + $mailres = sendSanchoMail( + 'ParbeitsbeurteilungEndupload', + $zweitbetmaildata, + $begutachterMitToken->email, + $subject, + 'sancho_header_min_bw.jpg', + 'sancho_footer_min_bw.jpg', + get_uid()."@".DOMAIN + ); + + if (!$mailres) + { + $this->terminateWithError($this->p->t('abgabetool', 'c4fehlerMailBegutachterv2'), 'general'); + } + + } + } + } + } + } + + private function checkZuordnung($projektarbeit_id, $betreuer_uid) { + // check if authenticated user is zugewiesen as betreuer to projektarbeit or has admin/assistenz berechtigung + // over the studiengang of the student working on that projektarbeit_id + + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + $res = $this->ProjektarbeitModel->getStudentInfoForProjektarbeitId($projektarbeit_id); + if(isError($res)) { + $this->terminateWithError($this->p->t('abgabetool', 'c4errorLoadingStudentForProjektarbeitID'), 'general'); + } + + if(!hasData($res)) { + $this->terminateWithError($this->p->t('abgabetool', 'c4noAssignedStudentForProjektarbeitID'), 'general'); + } + $data = getData($res)[0]; + $student_uid = $data->uid; + $studiengang_kz = $data->studiengang_kz; + + $res = $this->ProjektarbeitModel->checkZuordnung($student_uid, $betreuer_uid); + if(isError($res)) { + $this->terminateWithError($this->p->t('abgabetool', 'c4errorLoadingBetreuerStudentZuordnung'), 'general'); + } + + // if this is true betreuer has zuordnung to the given $projektarbeit_id and conversely the $student_uid + // assigned to that project + if(hasData($res)) { + return true; + } else { + $berechtigt = $this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id); + if($berechtigt) { + return true; + } + + // otherwhise if there is no zuordnung via global admin or assistenz berechtigung, + // check if the given uid has permissions over the studiengang of the student + // via the abgabetool specific berechtigungen + // 'basis/abgabe_assistenz:rw' OR 'basis/abgabe_lektor:rw' + + if ($this->permissionlib->isBerechtigt('basis/abgabe_assistenz', 'suid', $studiengang_kz)) { + return true; + } + + if ($this->permissionlib->isBerechtigt('basis/abgabe_lektor', 'suid', $studiengang_kz)){ + return true; + } + } + + return false; + } + + private function getProjektarbeitIDForPaabgabeID($paabgabe_id) { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + + $res = $this->ProjektarbeitModel->getProjektarbeitByPaabgabeID($paabgabe_id); + if(isError($res)) { + $this->terminateWithError($this->p->t('abgabetool', 'c4errorLoadingProjektarbeitForPaabgabeID'), 'general'); + } + + if(!hasData($res)) { + $this->terminateWithError($this->p->t('abgabetool', 'c4noAssignedProjektarbeitForPaabgabeID'), 'general'); + } + $data = getData($res)[0]; + return $data->projektarbeit_id; + } + + private function checkZuordnungByPaabgabe($paabgabe_id, $betreuer_uid) { + $projektarbeit_id = $this->getProjektarbeitIDForPaabgabeID($paabgabe_id); + return $this->checkZuordnung($projektarbeit_id, $betreuer_uid); + } + + // loads a projektarbeit table row by id and looks if a note has been set. A non null note field + // currently indicates that a projektarbeit has been finished and should not accept further crud manipulation + private function checkProjektarbeitForFinishedStatus($projektarbeit_id) { + $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + $res = $this->ProjektarbeitModel->load($projektarbeit_id); + + if(isError($res) || !hasData($res)) { + $this->terminateWithError($this->p->t('abgabetool','c4projektarbeitNichtGefunden'), 'general'); + } + + $data = getData($res)[0]; + if($data->note !== NULL) { + $this->terminateWithError($this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeit'), 'general'); + } + } + +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/Documents.php b/application/controllers/api/frontend/v1/Documents.php index 7b2fc4a15..dcc0bb9ac 100644 --- a/application/controllers/api/frontend/v1/Documents.php +++ b/application/controllers/api/frontend/v1/Documents.php @@ -208,7 +208,6 @@ class Documents extends FHCAPI_Controller $this->load->model('system/Vorlage_model', 'VorlageModel'); $result = $this->VorlageModel->load($xsl); - $this->addMeta("ress", $result); $vorlage = current($this->getDataOrTerminateWithError($result)); if (!$vorlage) show_404(); @@ -251,6 +250,9 @@ class Documents extends FHCAPI_Controller 'studiensemester_kurzbz' => $ss, 'student_uid' => $akteData['uid'] ]); + + if (!hasData($result)) $this->terminateWithError($this->p->t("stv", "error_noLehrverbandAssigned")); + $res = current($this->getDataOrTerminateWithError($result)); $studiengang_kz = $res->studiengang_kz; diff --git a/application/controllers/api/frontend/v1/Lehre.php b/application/controllers/api/frontend/v1/Lehre.php index d5d0282bd..10d945a3e 100644 --- a/application/controllers/api/frontend/v1/Lehre.php +++ b/application/controllers/api/frontend/v1/Lehre.php @@ -38,34 +38,9 @@ class Lehre extends FHCAPI_Controller parent::__construct([ 'lvStudentenMail' => self::PERM_LOGGED, 'LV' => self::PERM_LOGGED, - 'Pruefungen' => self::PERM_LOGGED, - 'getStudentProjektarbeiten' => self::PERM_LOGGED, // TODO: abgabetool berechtigung? - 'getStudentProjektabgaben' => self::PERM_LOGGED, - 'postStudentProjektarbeitZwischenabgabe' => self::PERM_LOGGED, - 'postStudentProjektarbeitEndupload' => self::PERM_LOGGED, - 'getMitarbeiterProjektarbeiten' => self::PERM_LOGGED, - 'postProjektarbeitAbgabe' => self::PERM_LOGGED, - 'deleteProjektarbeitAbgabe' => self::PERM_LOGGED, - 'postSerientermin' => self::PERM_LOGGED, - 'fetchDeadlines' => self::PERM_LOGGED // TODO: mitarbeiter recht prüfen + 'Pruefungen' => self::PERM_LOGGED ]); - - $this->load->library('PhrasesLib'); - - $this->loadPhrases( - array( - 'global', - 'ui', - 'abgabetool' - ) - ); - - $this->load->helper('hlp_sancho_helper'); - require_once(FHCPATH . 'include/studiengang.class.php'); - require_once(FHCPATH . 'include/student.class.php'); - require_once(FHCPATH . 'include/projektarbeit.class.php'); - require_once(FHCPATH . 'include/projektbetreuer.class.php'); } //------------------------------------------------------------------------------------------------------------------ @@ -125,557 +100,5 @@ class Lehre extends FHCAPI_Controller $this->terminateWithSuccess($result); } - - /** - * fetches all projektabgabetermine for a given projektarbeit_id used in cis4 student abgabetool - */ - public function getStudentProjektabgaben() { - $projektarbeit_id = $this->input->get("projektarbeit_id",TRUE); - - // TODO: error messages - - if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id)) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - $projektarbeit_obj = new projektarbeit(); - if($projektarbeit_id==-1) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - if(!$projektarbeit_obj->load($projektarbeit_id)) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - $paIsCurrent = $projektarbeit_obj->projektarbeitIsCurrent($projektarbeit_id); - - $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); - $ret = $this->ProjektarbeitModel->getProjektarbeitAbgabetermine($projektarbeit_id); - - // TODO: fetch zweitbetreuer - - $this->terminateWithSuccess(array($ret, $paIsCurrent)); - } - - /** - * fetches all projektarbeiten and betreuer for a given student_uid used in cis4 student abgabetool - */ - public function getStudentProjektarbeiten($uid) - { - $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); - $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); - - if (!isset($uid) || isEmptyString($uid)) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - $isZugeteilterBetreuer = count($this->ProjektarbeitModel->checkZuordnung($uid, getAuthUID())->retval) > 0; - $this->addMeta('isZugeteilterBetreuer', $isZugeteilterBetreuer); - $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID()); - - if ($isMitarbeiter && $isZugeteilterBetreuer){ - $projektarbeiten = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer($uid); - } else { - $projektarbeiten = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer(getAuthUID()); - } - - $this->terminateWithSuccess(array($projektarbeiten, DOMAIN, $uid)); - } - - - - /** - * projektarbeit - upload for zwischenabgaben in cis4 student abgabetool - */ - public function postStudentProjektarbeitZwischenabgabe() - { - - $projektarbeit_id = $_POST['projektarbeit_id']; - $paabgabe_id = $_POST['paabgabe_id']; - $student_uid = $_POST['student_uid']; - $bperson_id = $_POST['bperson_id']; - $paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz']; - - if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id) - || !isset($paabgabe_id) || isEmptyString($paabgabe_id) - || !isset($student_uid) || isEmptyString($student_uid) - || !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz)) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - if ((isset($_FILES) and isset($_FILES['file']) and ! $_FILES['file']['error'])) { - move_uploaded_file($_FILES['file']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf'); - - if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf')) { - - exec('chmod 640 "'.PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf'.'"'); - - $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); - $res = $this->PaabgabeModel->update($paabgabe_id, array( - 'abgabedatum' => date('Y-m-d'), - 'updatevon' => getAuthUID(), - 'updateamum' => date('Y-m-d H:i:s') - )); - - $this->sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid); - $this->terminateWithSuccess($res); - } else { - $this->terminateWithError('Error moving File'); - } - - } else { - $this->terminateWithError('File missing'); - } - - } - - /** - * upload für finale abgaben aka Endupload in cis4 student abgabetool - */ - public function postStudentProjektarbeitEndupload() - { - - $projektarbeit_id = $_POST['projektarbeit_id']; - $paabgabe_id = $_POST['paabgabe_id']; - $student_uid = $_POST['student_uid']; - $sprache = $_POST['sprache']; - $abstract = $_POST['abstract']; - $abstract_en = $_POST['abstract_en']; - $schlagwoerter = $_POST['schlagwoerter']; - $schlagwoerter_en = $_POST['schlagwoerter_en']; - $seitenanzahl = $_POST['seitenanzahl']; - $bperson_id = $_POST['bperson_id']; - $paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz']; - - if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id) - || !isset($paabgabe_id) || isEmptyString($paabgabe_id) - || !isset($student_uid) || isEmptyString($student_uid) - || !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz)) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - // TODO: maybe check for other params aswell? - - if ((isset($_FILES) and isset($_FILES['file']) and ! $_FILES['file']['error'])) { - move_uploaded_file($_FILES['file']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf'); - - if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf')) { - - // Loads Libraries - $this->load->library('SignatureLib'); - - // Check if the document is signed - $signaturVorhanden = true; - $signList = SignatureLib::list(PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf'); - if (is_array($signList) && count($signList) > 0) - { - // The document is signed - $uploadedDocumentSigned = 'The document is signed'; - } - elseif ($signList === null) - { - $uploadedDocumentSigned = 'WARNING: signature server error'; - } - else - { - $signaturVorhanden = false; - $uploadedDocumentSigned = 'No document signature found'; - } - $this->addMeta('signaturInfo', $uploadedDocumentSigned); - - if ($signaturVorhanden === false) - { - $this->signaturFehltEmail($student_uid); - } - - // TODO error handle get data has data the updates - // update projektarbeit cols - $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); - $this->ProjektarbeitModel->updateProjektarbeit($projektarbeit_id,$sprache,$abstract,$abstract_en - ,$schlagwoerter, $schlagwoerter_en, $seitenanzahl); - - - // update paabgabe datum - $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); - $res = $this->PaabgabeModel->update($paabgabe_id, array( - 'abgabedatum' => date('Y-m-d'), - 'updatevon' => getAuthUID(), - 'updateamum' => date('Y-m-d H:i:s') - )); - - $this->sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid); - - $this->terminateWithSuccess($res); - } else { - $this->terminateWithError('Error moving File'); - } - - } else { - $this->terminateWithError('File missing'); - } - - } - - private function signaturFehltEmail($student_uid) { - - - // Mail an Studiengang wenn keine Signatur gefunden wurde - $student = new student(); - if(!$student->load($student_uid)) - $this->terminateWithError($this->p->t('global','userNichtGefunden'), 'general'); - - $stg_obj = new studiengang(); - if(!$stg_obj->load($student->studiengang_kz)) - $this->terminateWithError($this->p->t('global','fehlerBeimLesenAusDatenbank'), 'general'); - - $subject = 'Abgabe ohne Signatur'; - $tomail = $stg_obj->email; - $data = array( - 'vorname' => $student->vorname, - 'nachname' => $student->nachname, - 'studiengang' => $stg_obj->bezeichnung - ); - - $mailres = sendSanchoMail( - 'ParbeitsbeurteilungSiganturFehlt', - $data, - $tomail, - $subject, - 'sancho_header_min_bw.jpg', - 'sancho_footer_min_bw.jpg' - ); - } - - private function sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid) { - - $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); - - $resBetr = $this->ProjektarbeitModel->getProjektbetreuerAnrede($bperson_id); - - $projektarbeit_obj = new projektarbeit(); - - if(!$projektarbeit_obj->load($projektarbeit_id)) - $this->terminateWithError('Ungueltiger Eintrag'); - - $num_rows_sem = $projektarbeit_obj->projektarbeitIsCurrent($projektarbeit_id); - - if( null === $num_rows_sem || false === $num_rows_sem ) - { - $this->terminateWithError($this->p->t('abgabetool','fehlerAktualitaetProjektarbeit'), 'general'); - } - - foreach($resBetr->retval as $betreuerRow) { - - // query student benutzer view for every betreuer row - $studentUser = $this->ProjektarbeitModel->getProjektarbeitBenutzer($student_uid)->retval[0]; - - // TODO: hasdata, getData etc - - // 1. Begutachter mail ohne Token - $mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter"; - $mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$studentUser->uid; - $projekttyp_kurzbz = $projektarbeit_obj->projekttyp_kurzbz; - $subject = $projektarbeit_obj->projekttyp_kurzbz == 'Diplom' ? 'Masterarbeitsbetreuung' : 'Bachelorarbeitsbetreuung'; - $abgabetyp = $paabgabetyp_kurzbz == 'end' ? 'Endabgabe' : 'Zwischenabgabe'; - - $maildata = array(); - $maildata['geehrt'] = "geehrte".($betreuerRow->anrede=="Herr"?"r":""); - $maildata['anrede'] = $betreuerRow->anrede; - $maildata['betreuer_voller_name'] = $betreuerRow->first; - $maildata['student_anrede'] = $studentUser->anrede; - $maildata['student_voller_name'] = trim($studentUser->titelpre." ".$studentUser->vorname." ".$studentUser->nachname." ".$studentUser->titelpost); - $maildata['abgabetyp'] = $abgabetyp; - $maildata['parbeituebersichtlink'] = "

Zur Projektarbeitsübersicht

"; - $maildata['bewertunglink'] = $num_rows_sem >= 1 && $paabgabetyp_kurzbz == 'end' ? "

Zur Beurteilung der Arbeit

" : ""; - $maildata['token'] = ""; - - $mailres = sendSanchoMail( - 'ParbeitsbeurteilungEndupload', - $maildata, - $betreuerRow->mitarbeiter_uid."@".DOMAIN, - $subject, - 'sancho_header_min_bw.jpg', - 'sancho_footer_min_bw.jpg', - get_uid()."@".DOMAIN); - - if(!$mailres) - { - $this->terminateWithError($this->p->t('abgabetool', 'fehlerMailBegutachter'), 'general'); - } - - // 2. Begutachter mail, wenn Endabgabe, mit Token wenn extern - if ($paabgabetyp_kurzbz == 'end') - { - // Zweitbegutachter holen - $zweitbegutachter = new projektbetreuer(); - $zweitbegutachterRes = $zweitbegutachter->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $studentUser->uid); - - if ($zweitbegutachterRes) - { - $zweitbegutachterResults = $zweitbegutachter->result; - - foreach ($zweitbegutachterResults as $begutachter) - { - // token generieren, wenn noch nicht vorhanden und notwendig (wird in methode überprüft) - $tokenGenRes = $zweitbegutachter->generateZweitbegutachterToken($begutachter->person_id, $projektarbeit_id); - - if (!$tokenGenRes) - { - $this->terminateWithError($this->p->t('abgabetool', 'fehlerMailZweitBegutachter'), 'general'); - } - - // Zweitbegutachter (evtl. mit Token) holen - $zweitbegutachterMitToken = new projektbetreuer(); - $begutachterMitTokenRes = $zweitbegutachterMitToken->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $studentUser->uid, $begutachter->person_id); - - if (!$begutachterMitTokenRes) - { - $this->terminateWithError($this->p->t('abgabetool', 'fehlerMailZweitBegutachter'), 'general'); - } - - // Email an Zweitbegutachter senden - if (isset($zweitbegutachterMitToken->result[0])) - { - $begutachterMitToken = $zweitbegutachterMitToken->result[0]; - - $path = $begutachterMitToken->betreuerart_kurzbz == 'Zweitbegutachter' ? 'ProjektarbeitsbeurteilungZweitbegutachter' : 'ProjektarbeitsbeurteilungErstbegutachter'; - $mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/$path"; - $mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$studentUser->uid; - $intern = isset($begutachterMitToken->uid); - $mail_link = $intern ? $mail_fulllink : $mail_baselink; - - $zweitbetmaildata = array(); - $zweitbetmaildata['geehrt'] = "geehrte" . ($begutachterMitToken->anrede == "Herr" ? "r" : ""); - $zweitbetmaildata['anrede'] = $begutachterMitToken->anrede; - $zweitbetmaildata['betreuer_voller_name'] = $begutachterMitToken->voller_name; - $zweitbetmaildata['student_anrede'] = $maildata['student_anrede']; - $zweitbetmaildata['student_voller_name'] = $maildata['student_voller_name']; - $zweitbetmaildata['abgabetyp'] = $abgabetyp; - $zweitbetmaildata['parbeituebersichtlink'] = $intern ? $maildata['parbeituebersichtlink'] : ""; - $zweitbetmaildata['bewertunglink'] = $num_rows_sem >= 1 ? "

Zur Beurteilung der Arbeit

" : ""; - $zweitbetmaildata['token'] = $num_rows_sem >= 1 && isset($begutachterMitToken->zugangstoken) && !$intern ? "

Zugangstoken: " . $begutachterMitToken->zugangstoken . "

" : ""; - - $mailres = sendSanchoMail( - 'ParbeitsbeurteilungEndupload', - $zweitbetmaildata, - $begutachterMitToken->email, - $subject, - 'sancho_header_min_bw.jpg', - 'sancho_footer_min_bw.jpg', - get_uid()."@".DOMAIN - ); - - if (!$mailres) - { - $this->terminateWithError($this->p->t('abgabetool', 'fehlerMailBegutachter'), 'general'); - } - } - } - } - } - } - } - - public function getMitarbeiterProjektarbeiten() { - $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); - - $boolParamStr = $this->input->get('showall'); - $trueStrings = ['true', '1']; - $falseStrings = ['false', '0']; - - // Handle missing or invalid parameter - if ($boolParamStr === null) { - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - } - $boolParamStrLower = strtolower($boolParamStr); - - if (in_array($boolParamStrLower, $trueStrings, true)) { - $showAllBool = true; - } elseif (in_array($boolParamStrLower, $falseStrings, true)) { - $showAllBool = false; - } else { -// $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - } - - $projektarbeiten = $this->ProjektarbeitModel->getMitarbeiterProjektarbeiten(getAuthUID(), $showAllBool); - - $this->terminateWithSuccess(array($projektarbeiten, DOMAIN)); - } - - public function postProjektarbeitAbgabe() { - $projektarbeit_id = $_POST['projektarbeit_id']; - $paabgabe_id = $_POST['paabgabe_id']; - $paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz']; - $datum = $_POST['datum']; - $fixtermin = $_POST['fixtermin']; - $kurzbz = $_POST['kurzbz']; - - if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id) - || !isset($paabgabe_id) || isEmptyString($paabgabe_id) - || !isset($datum) || isEmptyString($datum) - || !isset($datum) || isEmptyString($datum) - || !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz)) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); - - if($paabgabe_id == -1) { - $result = $this->PaabgabeModel->insert( - array( - 'projektarbeit_id' => $projektarbeit_id, - 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, - 'fixtermin' => $fixtermin, - 'datum' => $datum, - 'kurzbz' => $kurzbz, - 'insertvon' => getAuthUID(), - 'insertamum' => date('Y-m-d H:i:s') - ) - ); - - $this->terminateWithSuccess($result); - } else { - $result = $this->PaabgabeModel->update( - $paabgabe_id, - array( - 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, - 'datum' => $datum, - 'kurzbz' => $kurzbz, - 'updatevon' => getAuthUID(), - 'updateamum' => date('Y-m-d H:i:s') - ) - ); - - $this->terminateWithSuccess($result); - } - } - - public function deleteProjektarbeitAbgabe() { - $paabgabe_id = $_POST['paabgabe_id']; - - if (!isset($paabgabe_id) || isEmptyString($paabgabe_id)) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); - - $result = $this->PaabgabeModel->load($paabgabe_id); - $result = $this->getDataOrTerminateWithError($result); - - if(count($result) == 0) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - // TODO: berechtigung? - if($result[0]->insertvon === getAuthUID()) { - $result = $this->PaabgabeModel->delete($paabgabe_id); - $result = $this->getDataOrTerminateWithError($result); - $this->terminateWithSuccess($result); - } - - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - } - - /** - * endpoint for adding the same paabgabe for multiple projektarbeiten - * can be slow for large n since it queries twice per projektarbeit_id - */ - public function postSerientermin() { - $projektarbeit_ids = $_POST['projektarbeit_ids']; - $datum = $_POST['datum']; - $paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz']; - $bezeichnung = $_POST['bezeichnung']; - $kurzbz = $_POST['kurzbz']; - - if (!isset($projektarbeit_ids) || !is_array($projektarbeit_ids) || empty($projektarbeit_ids) - || !isset($datum) || isEmptyString($datum) - || !isset($kurzbz) || isEmptyString($kurzbz) - || !isset($bezeichnung) || isEmptyString($bezeichnung) - || !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz)) - $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general'); - - // old script checks if there already are tbl_paabgabe entries with exact date, type & kurzbz - // for each termin - good to check that in principle but should not matter in this place. if necessary - // duplicate abgabetermine can be easily deleted manually, also via cronjob@night. - - // since this entry includes the kurzbz string match, it should have only ever mattered when there were - // multiple users entering the exact same set of (date, type, kurzbz) - which is a much more narrow case than the - // general "saveMultiple" function should handle - - // old script afterwards again queries if user is not the zweitbetreuer of any id - this is blocked in the ui - // and should never unintentionally happen - - // TODO: check berechtigung &/|| zuordnung? - - $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); - $this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); - - $res = []; - foreach ($projektarbeit_ids as $projektarbeit_id) { - - $result = $this->PaabgabeModel->insert( - array( - 'projektarbeit_id' => $projektarbeit_id, - 'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz, - 'fixtermin' => false, - 'datum' => $datum, - 'kurzbz' => $kurzbz, - 'insertvon' => getAuthUID(), - 'insertamum' => date('Y-m-d H:i:s') - ) - ); - - $data = $this->getDataOrTerminateWithError($result); - -// $res[] = $data; - - // send mail to student - $result = $this->ProjektarbeitModel->getStudentInfoForProjektarbeitId($projektarbeit_id); - $data = $this->getDataOrTerminateWithError($result); - -// $this->addMeta('emaildata'.$projektarbeit_id, $data); - - $datetime = new DateTime($datum); - $dateEmailFormatted = $datetime->format('d.m.Y'); - - $anredeFillString = $data[0]->anrede=="Herr"?"r":""; - - $fullFormattedNameString = trim($data[0]->titelpre." ".$data[0]->vorname." ".$data[0]->nachname." ".$data[0]->titelpost); - $res[] = $fullFormattedNameString; - - // Prepare mail content - $body_fields = array( - 'anrede' => $data[0]->anrede, - 'anredeFillString' => $anredeFillString, - 'datum' => $dateEmailFormatted, - 'bezeichnung' => $bezeichnung, - 'fullFormattedNameString' => $fullFormattedNameString, - 'kurzbz' => $kurzbz - ); - - $email = $data[0]->uid."@".DOMAIN; - - sendSanchoMail( - 'neuerAbgabetermin', - $body_fields, - $email, - $this->p->t('abgabetool', 'neuerTerminBachelorMasterbetreuung') - ); - } - - $this->terminateWithSuccess($res); - - } - - public function fetchDeadlines() { - $person_id = $_POST['person_id']; - - if (!isset($person_id) || isEmptyString($person_id)) - $person_id = getAuthPersonId(); - - - if($person_id !== getAuthPersonId()) { - $this->load->library('PermissionLib'); - $isAdmin = $this->permissionlib->isBerechtigt('admin'); - if(!$isAdmin) $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general'); - } - - $this->load->model('education/Paabgabe_model', 'PaabgabeModel'); - $result = $this->PaabgabeModel->getDeadlines($person_id); - $data = $this->getDataOrTerminateWithError($result); - - $this->terminateWithSuccess($data); - } } diff --git a/application/controllers/api/frontend/v1/detailheader/Detailheader.php b/application/controllers/api/frontend/v1/detailheader/Detailheader.php new file mode 100644 index 000000000..ada10c5b6 --- /dev/null +++ b/application/controllers/api/frontend/v1/detailheader/Detailheader.php @@ -0,0 +1,53 @@ + ['vertrag/mitarbeiter:r'], + 'getPersonAbteilung' => ['vertrag/mitarbeiter:r'], + 'getLeitungOrg' => ['vertrag/mitarbeiter:r'], + ]); + } + + public function getHeader($person_id) + { + $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); + + $result = $this->Mitarbeitermodel->getHeader($person_id); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + + public function getPersonAbteilung($mitarbeiter_uid) + { + $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); + + $result = $this->Mitarbeitermodel->getPersonAbteilung($mitarbeiter_uid); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + + public function getLeitungOrg($oekurzbz) + { + $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); + + $result = $this->Mitarbeitermodel->getLeitungOrg($oekurzbz); + + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess(current($data)); + } + +} + + diff --git a/application/controllers/api/frontend/v1/fotoHandling/Foto.php b/application/controllers/api/frontend/v1/fotoHandling/Foto.php new file mode 100644 index 000000000..4945ddd85 --- /dev/null +++ b/application/controllers/api/frontend/v1/fotoHandling/Foto.php @@ -0,0 +1,237 @@ + ['admin:r', 'assistenz:r'], + 'deleteFoto' => ['admin:r', 'assistenz:r'], + ]); + + //Load Models and Libraries + $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model("crm/Akte_model", "AkteModel"); + $this->load->model('person/Fotostatusperson_model', 'FotostatusPersonModel'); + + $this->loadPhrases([ + 'ui', + 'header' + ]); + } + + public function uploadFoto($person_id) + { + if(!$person_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person_id']), self::ERROR_TYPE_GENERAL); + } + + $data = json_decode(file_get_contents("php://input"), true); + + if (!empty($data['image'])) + { + $base64 = $data['image']; + $resizedImage1 = $this->_resize($base64, 827, 1063); + + if (is_null($resizedImage1)) + return $this->terminateWithError($this->p->t('header', 'error_fotoupload'), self::ERROR_TYPE_GENERAL); + + $akte = $this->AkteModel->loadWhere(array('person_id' => $person_id, 'dokument_kurzbz' => 'Lichtbil')); + + $akteUpdateData = array( + 'dokument_kurzbz' => 'Lichtbil', + 'person_id' => $person_id, + 'inhalt' => $resizedImage1, + 'mimetype' => 'image/jpg', + 'erstelltam' => date('c'), + 'gedruckt' => false, + 'titel' => 'Lichtbild_' . $person_id . '.jpg', + 'bezeichnung' => 'Lichtbild gross', + 'insertamum' => date('c'), + 'insertvon' => getAuthUID(), + ); + + if (hasData($akte)) { + $akte_id = getData($akte)[0]->akte_id; + + $akteUpdateData['updateamum'] = date('c'); + $akteUpdateData['updatevon'] = getAuthUID(); + $akteResult = $this->AkteModel->update(array('akte_id' => $akte_id), $akteUpdateData); + } else { + $akteResult = $this->AkteModel->insert($akteUpdateData); + } + + if (isError($akteResult)) { + return $this->terminateWithError(getError($akteResult), self::ERROR_TYPE_GENERAL); + } + + $resizedImage2 = $this->_resize($base64, 101, 130); + + if (is_null($resizedImage2)) + return $this->terminateWithError($this->p->t('header', 'error_fotoupload'), self::ERROR_TYPE_GENERAL); + + $result = $this->_updateFoto($person_id, $resizedImage2); + + if (!isError($result)) { + $this->FotostatusPersonModel->insert(array( + 'person_id' => $person_id, + 'fotostatus_kurzbz' => 'hochgeladen', + 'datum' => date('Y-m-d'), + 'updateamum' => date('c'), + 'updatevon' => getAuthUID(), + 'insertamum' => date('c'), + 'insertvon' => getAuthUID(), + )); + + return $this->terminateWithSuccess($base64); + } + } + else + { + $this->terminateWithError($this->p->t('header', 'error_noPhoto'), self::ERROR_TYPE_GENERAL); + } + } + + public function deleteFoto($person_id) + { + if(!$person_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person_id']), self::ERROR_TYPE_GENERAL); + } + + $result = $this->_deleteFoto($person_id); + + if (isError($result)) + { + return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + } + return $this->terminateWithSuccess($result); + } + + private function _resize($imageData, $maxwidth, $maxheight, $quality = 90) + { + $meta = getimagesize($imageData); + if (!$meta) + { + return null; + } + + $src_width = $meta[0]; + $src_height = $meta[1]; + $mime = $meta['mime']; + + switch ($mime) { + case 'image/jpeg': + case 'image/jpg': + $imagecreated = imagecreatefromjpeg($imageData); + break; + case 'image/png': + $imagecreated = imagecreatefrompng($imageData); + break; + case 'image/gif': + $imagecreated = imagecreatefromgif($imageData); + break; + default: + return null; + } + + + if (!$imagecreated) + { + return null; + } + + $src_aspect_ratio = $src_width / $src_height; + $thu_aspect_ratio = $maxwidth / $maxheight; + + if ($src_width <= $maxwidth && $src_height <= $maxheight) + { + $thu_width = $src_width; + $thu_height = $src_height; + } + elseif ($thu_aspect_ratio > $src_aspect_ratio) + { + $thu_width = (int) ($maxheight * $src_aspect_ratio); + $thu_height = $maxheight; + } + else + { + $thu_width = $maxwidth; + $thu_height = (int) ($maxwidth / $src_aspect_ratio); + } + + $imageScaled = imagecreatetruecolor($thu_width, $thu_height); + + if ($mime === 'image/png') + { + $background = imagecolorallocate($imageScaled , 0, 0, 0); + imagecolortransparent($imageScaled, $background); + imagealphablending($imageScaled, false); + imagesavealpha($imageScaled, true); + } + + imagecopyresampled($imageScaled, $imagecreated, 0, 0, 0, 0, $thu_width, $thu_height, $src_width, $src_height); + + if ($mime === "image/gif") + { + $background = imagecolorallocate($imageScaled, 0, 0, 0); + imagecolortransparent($imageScaled, $background); + } + + if (!empty($imageScaled)) + { + ob_start(); + + if ($mime == 'image/png') + imagepng($imageScaled, NULL); + else if ($mime === 'image/gif') + imagegif($imageScaled, NULL); + else + imagejpeg($imageScaled, NULL, $quality); + + $resizedImageData = ob_get_contents(); + ob_end_clean(); + @imagedestroy($imagecreated); + @imagedestroy($imageScaled); + + + if (!empty($resizedImageData)) + { + return base64_encode($resizedImageData); + } + return null; + } + return null; + } + + private function _updateFoto($person_id, $foto) + { + $personJson['foto'] = $foto; + $result = $this->PersonModel->update($person_id, $personJson); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + return $result; + } + + private function _deleteFoto($person_id) + { + $personJson['foto'] = null; + $result = $this->PersonModel->update($person_id, $personJson); + + if (isError($result)) + { + return error($result->msg, EXIT_ERROR); + } + + return $result; + } +} diff --git a/application/controllers/api/frontend/v1/lv/Setup.php b/application/controllers/api/frontend/v1/lv/Setup.php index a2c167dd6..eea4befa5 100644 --- a/application/controllers/api/frontend/v1/lv/Setup.php +++ b/application/controllers/api/frontend/v1/lv/Setup.php @@ -47,22 +47,22 @@ class Setup extends FHCAPI_Controller { $tabs['details'] = array ( 'title' => 'Details', - 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Details.js', + 'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Details.js'), 'config' => [] ); $tabs['gruppen'] = array ( 'title' => 'Gruppen', - 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Gruppen.js', + 'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Gruppen.js'), 'config' => [] ); $tabs['lektor'] = array ( 'title' => 'LektorInnenzuteilung', - 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Lektor.js', + 'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Lektor.js'), 'config' => [] ); $tabs['notiz'] = array ( 'title' => 'Notizen', - 'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Notiz.js', + 'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Notiz.js'), 'config' => [] ); $this->terminateWithSuccess($tabs); diff --git a/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php b/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php new file mode 100644 index 000000000..30dae9a50 --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizAnrechnung.php @@ -0,0 +1,44 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "anrechnung_id") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizBestellung.php b/application/controllers/api/frontend/v1/notiz/NotizBestellung.php new file mode 100644 index 000000000..e30628f33 --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizBestellung.php @@ -0,0 +1,43 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "bestellung_id") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php index f8e1f816b..a3b96d477 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php +++ b/application/controllers/api/frontend/v1/notiz/NotizLehreinheit.php @@ -17,5 +17,106 @@ class NotizLehreinheit extends Notiz_Controller 'getMitarbeiter' => ['admin:r', 'assistenz:r'], 'isBerechtigt' => ['admin:r', 'assistenz:r'], ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + //Permission checks for allowed Oes + $allowedOes = $this->permissionlib->getOE_isEntitledFor('assistenz') ?: []; + + if ($this->router->method == 'addNewNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $lehreinheit_id = $post_data['id']; + + if(!$lehreinheit_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes); + } + + if ($this->router->method == 'updateNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $notiz_id = $post_data['notiz_id']; + + if(!$notiz_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL); + } + + //get lehreinheit_id + $result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]); + + $data = $this->getDataOrTerminateWithError($result); + $lehreinheit_id = current($data)->lehreinheit_id; + + if(!$lehreinheit_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes); + } + + if ($this->router->method == 'deleteNotiz') + { + $notiz_id = $this->input->post('notiz_id'); + $lehreinheit_id = $this->input->post('id'); + + if(!$notiz_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL); + } + + if(!$lehreinheit_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes); + } + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); } -} \ No newline at end of file + + private function _checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes) + { + //get oe from lehreinheit + $result = $this->LehreinheitModel->getOes($lehreinheit_id); + $data = $this->getDataOrTerminateWithError($result); + $oes = current($data); + + if (!in_array($oes, $allowedOes)) + { + return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg') . " " . $oes, self::ERROR_TYPE_GENERAL); + } + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "lehreinheit_id") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } + + +} diff --git a/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php b/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php new file mode 100644 index 000000000..f7de4b47b --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizMitarbeiter.php @@ -0,0 +1,44 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "mitarbeiter_uid") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizPerson.php b/application/controllers/api/frontend/v1/notiz/NotizPerson.php index 23a8fd199..a047129d7 100644 --- a/application/controllers/api/frontend/v1/notiz/NotizPerson.php +++ b/application/controllers/api/frontend/v1/notiz/NotizPerson.php @@ -20,33 +20,100 @@ class NotizPerson extends Notiz_Controller 'isBerechtigt' => ['admin:r', 'assistenz:r'], 'getCountNotes' => ['admin:r', 'assistenz:r'], ]); + + //Load Models + $this->load->model('person/Benutzer_model', 'BenutzerModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + + //Permission checks for allowed Oes + if ($this->router->method == 'addNewNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $person_id = $post_data['id']; + + $allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []; + + if(!$person_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkIfBerechtigungForOnePrestudentExists($person_id, $allowedStgs); + } + + if ( $this->router->method == 'updateNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $notiz_id = $post_data['notiz_id']; + + if(!$notiz_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL); + } + + //get person_id + $result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]); + + $data = $this->getDataOrTerminateWithError($result); + $person_id = current($data)->person_id; + + $allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []; + $this->_checkIfBerechtigungForOnePrestudentExists($person_id, $allowedStgs); + } + + if ($this->router->method == 'deleteNotiz' ) + { + $notiz_id = $this->input->post('notiz_id'); + $person_id = $this->input->post('id'); + + if(!$notiz_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL); + } + + if(!$person_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'person ID']), self::ERROR_TYPE_GENERAL); + } + + $allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []; + $this->_checkIfBerechtigungForOnePrestudentExists($person_id, $allowedStgs); + } } public function isBerechtigt($id, $typeId) { if($typeId != "person_id") { - return $this->terminateWithError($this->p->t('ui', 'error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui', 'error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); } - //TODO define permission if (!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) { $result = $this->p->t('lehre', 'error_keineSchreibrechte'); - - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->outputJsonSuccess(true); + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); } - public function loadDokumente() + //stv: if person has permission of one studiengang of person -> permission to add/update/delete Note + private function _checkIfBerechtigungForOnePrestudentExists($person_id, $allowedStgs) { - $notiz_id = $this->input->post('notiz_id'); + $result = $this->PrestudentModel->loadWhere(['person_id' => $person_id]); + $data = $this->getDataOrTerminateWithError($result); - // TODO(chris): make CI variant of endpoint - $this->NotizModel->addSelect($this->NotizModel->escape(base_url('content/notizdokdownload.php?id=')) . ' || campus.tbl_dms_version.dms_id AS preview'); - - return parent::loadDokumente(); + $checkarray = []; + foreach ($data as $item) + { + if(in_array($item->studiengang_kz, $allowedStgs)) + { + return true; + } + } + + $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL); } -} \ No newline at end of file +} diff --git a/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php b/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php new file mode 100644 index 000000000..5e6cd747c --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizPrestudent.php @@ -0,0 +1,117 @@ + ['admin:r', 'assistenz:r'], + ]); + + //Load Models + $this->load->model('person/Notiz_model', 'NotizModel'); + $this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel'); + $this->load->model('crm/Student_model', 'StudentModel'); + + // Load Libraries + $this->load->library('VariableLib', ['uid' => getAuthUID()]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); + + //Permission checks for Studiengangsarray + $allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []; + + if ($this->router->method == 'addNewNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $prestudent_id = $post_data['id']; + + if(!$prestudent_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs); + } + + if ($this->router->method == 'updateNotiz') + { + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $notiz_id = $post_data['notiz_id']; + + if(!$notiz_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL); + } + + //get prestudent_id + $result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]); + + $data = $this->getDataOrTerminateWithError($result); + $prestudent_id = current($data)->prestudent_id; + + if(!$prestudent_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs); + } + + if ($this->router->method == 'deleteNotiz') + { + $notiz_id = $this->input->post('notiz_id'); + $prestudent_id = $this->input->post('id'); + + if(!$notiz_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL); + } + + if(!$prestudent_id) + { + return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL); + } + $this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs); + } + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "prestudent_id") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } + + private function _checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs) + { + $student_uid = $this->StudentModel->getUID($prestudent_id); + + $result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]); + + $data = $this->getDataOrTerminateWithError($result); + $studiengang_kz = current($data)->studiengang_kz; + + if (!in_array($studiengang_kz, $allowedStgs)) + { + return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL); + } + } + +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizProjekt.php b/application/controllers/api/frontend/v1/notiz/NotizProjekt.php new file mode 100644 index 000000000..9cdde36ae --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizProjekt.php @@ -0,0 +1,32 @@ + ['admin:r', 'assistenz:r'], + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "projekt_kurzbz") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php b/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php new file mode 100644 index 000000000..7a82c658e --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizProjektphase.php @@ -0,0 +1,32 @@ + ['admin:r', 'assistenz:r'], + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "projektphase_id") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php b/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php new file mode 100644 index 000000000..aadb04f40 --- /dev/null +++ b/application/controllers/api/frontend/v1/notiz/NotizProjekttask.php @@ -0,0 +1,32 @@ + ['admin:r', 'assistenz:r'], + ]); + } + + public function isBerechtigt($id, $typeId) + { + if($typeId != "projekttask_id") + { + $this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL); + } + + //TODO define permission + if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid')) + { + $result = $this->p->t('lehre','error_keineSchreibrechte'); + + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + } + $this->terminateWithSuccess("berechtigt in überschreibender Funktion"); + } +} \ No newline at end of file diff --git a/application/controllers/api/frontend/v1/organisation/Studiensemester.php b/application/controllers/api/frontend/v1/organisation/Studiensemester.php index bb56ea71a..3c6b72d2f 100644 --- a/application/controllers/api/frontend/v1/organisation/Studiensemester.php +++ b/application/controllers/api/frontend/v1/organisation/Studiensemester.php @@ -25,7 +25,8 @@ class Studiensemester extends FHCAPI_Controller array( 'getAll' => self::PERM_LOGGED, 'getAktNext' => self::PERM_LOGGED, - 'getStudienjahrByStudiensemester' => self::PERM_LOGGED + 'getStudienjahrByStudiensemester' => self::PERM_LOGGED, + 'getAllStudiensemesterAndAktOrNext' => self::PERM_LOGGED ) ); // Load model StudiensemesterModel @@ -152,4 +153,17 @@ class Studiensemester extends FHCAPI_Controller $this->terminateWithSuccess((getData(success($studienjahrObj)))); } + + public function getAllStudiensemesterAndAktOrNext() { + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + $this->StudiensemesterModel->addOrder("start", "DESC"); + $result = $this->StudiensemesterModel->getAktOrNextSemester(); + $aktuell = getData($result)[0]; + $this->StudiensemesterModel->addSelect('*'); + $result = $this->StudiensemesterModel->load(); + $studiensemester = getData($result); + + $this->terminateWithSuccess(array($studiensemester, $aktuell)); + } } diff --git a/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php b/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php index abf58cf4f..72d5dbccc 100644 --- a/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php +++ b/application/controllers/api/frontend/v1/studstatus/Unterbrechung.php @@ -127,9 +127,9 @@ class Unterbrechung extends FHCAPI_Controller $this->form_validation->set_rules( 'datum_wiedereinstieg', 'Datum Wiedereinstieg', - 'required|callback_isValidDate|callback_isDateInFuture', + 'required|is_valid_date|callback_isDateInFuture', [ - 'isValidDate' => $this->p->t('ui', 'error_invalid_date'), + 'is_valid_date' => $this->p->t('ui', 'error_invalid_date'), 'isDateInFuture' => $this->p->t('ui', 'error_invalid_date') ] ); @@ -209,18 +209,9 @@ class Unterbrechung extends FHCAPI_Controller $this->terminateWithSuccess(getData($result)); } - public function isValidDate($date) - { - try { - new DateTime($date); - } catch (Exception $e) { - return false; - } - return true; - } - public function isDateInFuture($date) { return new DateTime() < new DateTime($date); } } + diff --git a/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php b/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php index 26033908d..437ba42ad 100644 --- a/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php +++ b/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php @@ -36,15 +36,44 @@ class Aufnahmetermine extends FHCAPI_Controller // Load models $this->load->model('crm/Reihungstest_model', 'ReihungstestModel'); $this->load->model('crm/RtPerson_model', 'RtPersonModel'); + $this->load->model('organisation/Studienplan_model', 'StudienplanModel'); + $this->load->model('organisation/Studienordnung_model', 'StudienordnungModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); } public function getAufnahmetermine($person_id) { $result = $this->ReihungstestModel->getReihungstestPerson($person_id); + $arrayRt = $this->getDataOrTerminateWithError($result); - $data = $this->getDataOrTerminateWithError($result); + foreach ($arrayRt as $item) { + //Studienplan + $result = $this->StudienplanModel->loadWhere([ + 'studienplan_id' => $item->studienplan_id + ]); + $data = $this->getDataOrTerminateWithError($result); + $studienordnung_id_ber = current($data)->studienordnung_id; - $this->terminateWithSuccess($data); + //Studienordnung + $result = $this->StudienordnungModel->loadWhere([ + 'studienordnung_id' => $studienordnung_id_ber + ]); + $data = $this->getDataOrTerminateWithError($result); + $studiengang_kz_ber = current($data)->studiengang_kz; + + //Studiengang von studiengang_kz_ber + $result = $this->StudiengangModel->load($studiengang_kz_ber); + $data = $this->getDataOrTerminateWithError($result); + + $studiengangkurzbzlang_ber = current($data)->kurzbzlang; + $typ_ber = current($data)->typ; + + //add to Array + $item->studiengang_kz_ber = $studiengang_kz_ber; + $item->studiengangkurzbzlang_ber = $studiengangkurzbzlang_ber; + $item->studiengangtyp_ber = $typ_ber; + } + $this->terminateWithSuccess($arrayRt); } public function insertAufnahmetermin() @@ -60,7 +89,6 @@ class Aufnahmetermine extends FHCAPI_Controller return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL); } - $rt_id = (isset($formData['rt_id']) && !empty($formData['rt_id'])) ? $formData['rt_id'] : null; $anmeldedatum = (isset($formData['anmeldedatum']) && !empty($formData['anmeldedatum'])) ? $formData['anmeldedatum'] : null; $teilgenommen = (isset($formData['teilgenommen']) && !empty($formData['teilgenommen'])) ? $formData['teilgenommen'] : false; @@ -224,7 +252,11 @@ class Aufnahmetermine extends FHCAPI_Controller ) ); - $data = $this->getDataOrTerminateWithError($result); + //check if existing placementtest + if(!hasData($result)) + $this->terminateWithSuccess([]); + else + $data = getData($result); $studienplan_arr = []; $include_ids = []; @@ -233,12 +265,18 @@ class Aufnahmetermine extends FHCAPI_Controller if($item->studienplan_id != null) $studienplan_arr[] = $item->studienplan_id; } + if(!hasData($studienplan_arr)) + $this->terminateWithSuccess([]); //get Placementtests Person $person_id = $this->_getPersonId($prestudent_id); $resultRt = $this->ReihungstestModel->getReihungstestPerson($person_id); - $dataRt = $this->getDataOrTerminateWithError($resultRt); + //check if existing placementtest + if(!hasData($result)) + $this->terminateWithSuccess([]); + else + $dataRt = getData($resultRt); foreach ($dataRt as $item) { @@ -354,6 +392,7 @@ class Aufnahmetermine extends FHCAPI_Controller $person_id = $this->input->get('person_id'); $punkte = $this->input->get('punkte'); $reihungstest_id = $this->input->get('reihungstest_id'); + $has_excluded_gebiete = $this->input->get('hasExcludedAreas'); if(!$reihungstest_id) { @@ -364,22 +403,27 @@ class Aufnahmetermine extends FHCAPI_Controller $studiengang_kz = $this->input->get('studiengang_kz'); $this->load->model('testtool/Ablauf_model', 'AblaufModel'); - $result = $this->AblaufModel->getAblaufGebieteAndGewichte($studiengang_kz); + $result = $this->AblaufModel->getAblaufGebieteAndGewichte($studiengang_kz, 1); $data = $this->getDataOrTerminateWithError($result); $weightedArray = []; + $basis_gebiet_id_arr = []; + $basis_gebiet_id_toString = ''; foreach ($data as $abl) { $weightedArray[$abl->gebiet_id] = $abl->gewicht; + $basis_gebiet_id_arr[]= $abl->gebiet_id; } + $basis_gebiet_id_toString = implode(', ', $basis_gebiet_id_arr); - $result = $this->ReihungstestModel->getReihungstestErgebnisPerson($person_id, $punkte, $reihungstest_id, $weightedArray); - -/* if (isError($result)) - { - $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); - }*/ - + $result = $this->ReihungstestModel->getReihungstestErgebnisPerson( + $person_id, + $punkte, + $reihungstest_id, + $weightedArray, + $has_excluded_gebiete, + $basis_gebiet_id_toString + ); $this->terminateWithSuccess($result); } diff --git a/application/controllers/api/frontend/v1/stv/Config.php b/application/controllers/api/frontend/v1/stv/Config.php index 17b360f8c..bc1fbebfe 100644 --- a/application/controllers/api/frontend/v1/stv/Config.php +++ b/application/controllers/api/frontend/v1/stv/Config.php @@ -200,7 +200,8 @@ class Config extends FHCAPI_Controller 'type' => 'select', 'values' => $buchungstyp_kurzbz_plus_all, 'value_key' => 'buchungstyp_kurzbz', - 'label_key' => 'beschreibung' + 'label_key' => 'beschreibung', + 'default' => 'all' ], 'samestg' => [ 'type' => 'bool', @@ -226,7 +227,8 @@ class Config extends FHCAPI_Controller 'type' => 'select', 'values' => $buchungstyp_kurzbz_plus_all, 'value_key' => 'buchungstyp_kurzbz', - 'label_key' => 'beschreibung' + 'label_key' => 'beschreibung', + 'default' => 'all' ], 'samestg' => [ 'type' => 'bool', @@ -504,7 +506,7 @@ class Config extends FHCAPI_Controller { $result['combinePeople'] = [ 'title' => $this->p->t('stv', 'tab_combine_people'), - 'component' => './Stv/Studentenverwaltung/Details/CombinePeople.js', + 'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/CombinePeople.js'), 'config' => $config['combinePeople'] ]; } diff --git a/application/controllers/api/frontend/v1/stv/Dokumente.php b/application/controllers/api/frontend/v1/stv/Dokumente.php index 8a69d28ab..b8c7830bd 100644 --- a/application/controllers/api/frontend/v1/stv/Dokumente.php +++ b/application/controllers/api/frontend/v1/stv/Dokumente.php @@ -596,8 +596,8 @@ class Dokumente extends FHCAPI_Controller buildDropdownEntryPrintArray("bescheid", "Bescheid (nur Voransicht)", "xml=abschlusspruefung.rdf.php&xsl_stg_kz=$studiengang_kz&xsl=Bescheid&output=pdf", $uid, 25, null), buildDropdownEntryPrintArray("diplomasupp", "Diploma Supplement (nur Voransicht)", "xml=diplomasupplement.xml.php&xsl_stg_kz=$studiengang_kz&xsl=DiplSupplement&output=pdf", $uid, 26, null), - buildDropdownEntryPrintArray("studienbestaetigung", "Studienbestätigung", "xml=student.rdf.php&xsl=Inskription&output=pdf", $uid, 50, null), - buildDropdownEntryPrintArray("studienbestaetigung_en", "Studienbestätigung Englisch", "xml=student.rdf.php&xsl=InskriptionEng&output=pdf", $uid, 51, null), + buildDropdownEntryPrintArray("studienbestaetigung", "Studienbestätigung", "xml=student.rdf.php&xsl=Inskription&output=pdf&ss=$studiensemester_kurzbz&xsl_stg_kz=$studiengang_kz", $uid, 50, null), + buildDropdownEntryPrintArray("studienbestaetigung_en", "Studienbestätigung Englisch", "xml=student.rdf.php&xsl=InskriptionEng&output=pdf&ss=$studiensemester_kurzbz&xsl_stg_kz=$studiengang_kz", $uid, 51, null), buildDropdownEntryPrintArray("zutrittskarte", "Zutrittskarte", "xsl=ZutrittskarteStud&output=pdf&data=$uid", $uid,200, "zutrittskarte.php"), buildDropdownEntryPrintArray("studienblatt", "Studienblatt", "xml=studienblatt.xml.php&xsl=Studienblatt&output=pdf&ss=$studiensemester_kurzbz", $uid, 60, null), buildDropdownEntryPrintArray("studienblatt_eng", "Studienblatt Englisch", "xml=studienblatt.xml.php&xsl=StudienblattEng&output=pdf&ss=$studiensemester_kurzbz", $uid, 61, null), @@ -686,8 +686,8 @@ class Dokumente extends FHCAPI_Controller buildDropdownEntryPrintArray("accountinfo", "Accountinfoblatt", "xml=accountinfoblatt.xml.php&xsl=AccountInfo&output=pdf", $uidString, 10, null), buildDropdownEntryPrintArray("ausbildungsvertrag", "Ausbildungsvertrag", "xml=ausbildungsvertrag.xml.php&xsl=Ausbildungsver&output=pdf", $uidString, 20, null), buildDropdownEntryPrintArray("ausbildungsvertrag_en", "Ausbildungsvertrag Englisch", "xml=ausbildungsvertrag.xml.php&xsl=AusbVerEng&output=pdf", $uidString, 21, null), - buildDropdownEntryPrintArray("studienbestaetigung", "Studienbestätigung", "xml=student.rdf.php&xsl=Inskription&output=pdf", $uidString, 50, null), - buildDropdownEntryPrintArray("studienbestaetigung_en", "Studienbestätigung Englisch", "xml=student.rdf.php&xsl=InskriptionEng&output=pdf", $uidString, 51, null), + buildDropdownEntryPrintArray("studienbestaetigung", "Studienbestätigung", "xml=student.rdf.php&xsl=Inskription&output=pdf&ss=$studiensemester_kurzbz&xsl_stg_kz=$studiengang_kz", $uidString, 50, null), + buildDropdownEntryPrintArray("studienbestaetigung_en", "Studienbestätigung Englisch", "xml=student.rdf.php&xsl=InskriptionEng&output=pdf&ss=$studiensemester_kurzbz&xsl_stg_kz=$studiengang_kz", $uidString, 51, null), buildDropdownEntryPrintArray("zutrittskarte", "Zutrittskarte", "xsl=ZutrittskarteStud&output=pdf&data=$uidString", $uidString,200, "zutrittskarte.php"), buildDropdownEntryPrintArray("studienblatt", "Studienblatt", "xml=studienblatt.xml.php&xsl=Studienblatt&output=pdf&ss=$studiensemester_kurzbz", $uidString, 60, null), buildDropdownEntryPrintArray("studienblatt_eng", "Studienblatt Englisch", "xml=studienblatt.xml.php&xsl=StudienblattEng&output=pdf&ss=$studiensemester_kurzbz", $uidString, 61, null), @@ -753,6 +753,10 @@ class Dokumente extends FHCAPI_Controller ); $data = $this->getDataOrTerminateWithError($result); + if(!(is_array($data) && count($data) > 0)) + { + return null; + } $student = current($data); return $student->student_uid; diff --git a/application/controllers/api/frontend/v1/stv/Grades.php b/application/controllers/api/frontend/v1/stv/Grades.php index dd8f53a27..128316d2b 100644 --- a/application/controllers/api/frontend/v1/stv/Grades.php +++ b/application/controllers/api/frontend/v1/stv/Grades.php @@ -60,7 +60,8 @@ class Grades extends FHCAPI_Controller { $this->load->model('codex/Note_model', 'NoteModel'); - $this->NoteModel->addOrder('note'); + $this->NoteModel->addOrder('notenwert', 'ASC'); + $this->NoteModel->addOrder('bezeichnung', 'ASC'); $result = $this->NoteModel->load(); diff --git a/application/controllers/api/frontend/v1/stv/Konto.php b/application/controllers/api/frontend/v1/stv/Konto.php index 384452f3e..ecd58671a 100644 --- a/application/controllers/api/frontend/v1/stv/Konto.php +++ b/application/controllers/api/frontend/v1/stv/Konto.php @@ -239,7 +239,7 @@ class Konto extends FHCAPI_Controller $data[$field] = $this->input->post($field); if (defined('FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE') && isset(unserialize(FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE)[$data['buchungstyp_kurzbz']])) { - $data['kostenstelle'] = unserialize(FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE)[$data['buchungstyp_kurzbz']]; + $data['studiengang_kz'] = unserialize(FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE)[$data['buchungstyp_kurzbz']]; } $result = []; diff --git a/application/controllers/api/frontend/v1/stv/Prestudent.php b/application/controllers/api/frontend/v1/stv/Prestudent.php index 7dc607d1a..d8c8d1ff2 100644 --- a/application/controllers/api/frontend/v1/stv/Prestudent.php +++ b/application/controllers/api/frontend/v1/stv/Prestudent.php @@ -43,7 +43,7 @@ class Prestudent extends FHCAPI_Controller // Load language phrases $this->loadPhrases([ - 'ui', 'studierendenantrag', 'lehre' + 'ui', 'studierendenantrag', 'lehre', 'global' ]); } @@ -98,11 +98,9 @@ class Prestudent extends FHCAPI_Controller 'person_id', 'berufstaetigkeit_code', 'ausbildungcode', - 'zgv_code', 'zgvort', 'zgvdatum', 'zgvnation', - 'zgvmas_code', 'zgvmaort', 'zgvmadatum', 'zgvmanation', @@ -110,7 +108,6 @@ class Prestudent extends FHCAPI_Controller 'bismelden', 'anmerkung', 'dual', - 'zgvdoktor_code', 'zgvdoktorort', 'zgvdoktordatum', 'zgvdoktornation', @@ -125,6 +122,57 @@ class Prestudent extends FHCAPI_Controller 'standort_code' ]; + // add zgv code fields only if user has permission + $this->load->library('PermissionLib'); + $prestudentres = $this->PrestudentModel->load($prestudent_id); + if(!hasData($prestudentres)) + { + $this->terminateWithError($this->p->t('ui', 'error_fieldNotFound', ['field' => 'Prestudent ' . $prestudent_id])); + } + $prestudent = (getData($prestudentres))[0]; + $bakkZgvStg = $this->permissionlib->getSTG_isEntitledFor('student/editBakkZgv') ?: array(); + $makkZgvStg = $this->permissionlib->getSTG_isEntitledFor('student/editMakkZgv') ?: array(); + $dokZgvStg = $this->permissionlib->getSTG_isEntitledFor('student/editDokZgv') ?: array(); + + if(in_array($prestudent->studiengang_kz, $bakkZgvStg)) + { + $array_allowed_props_prestudent[] = 'zgv_code'; + } + else if(!is_null($this->input->post('zgv_code'))) + { + $this->terminateWithError( + $this->p->t('global', 'zgv') + . ' - ' . + $this->p->t('ui', 'error_keineBerechtigungStg') + ); + } + + if(in_array($prestudent->studiengang_kz, $makkZgvStg)) + { + $array_allowed_props_prestudent[] = 'zgvmas_code'; + } + else if(!is_null($this->input->post('zgvmas_code'))) + { + $this->terminateWithError( + $this->p->t('lehre', 'zgvMaster') + . ' - ' . + $this->p->t('ui', 'error_keineBerechtigungStg') + ); + } + + if(in_array($prestudent->studiengang_kz, $dokZgvStg)) + { + $array_allowed_props_prestudent[] = 'zgvdoktor_code'; + } + else if(!is_null($this->input->post('zgvdoktor_code'))) + { + $this->terminateWithError( + $this->p->t('lehre', 'zgvDoktor') + . ' - ' . + $this->p->t('ui', 'error_keineBerechtigungStg') + ); + } + // add UDFs $result = $this->udflib->getDefinitionForModel($this->PrestudentModel); diff --git a/application/controllers/api/frontend/v1/stv/Projektarbeit.php b/application/controllers/api/frontend/v1/stv/Projektarbeit.php index db7d99752..8740ef3d6 100644 --- a/application/controllers/api/frontend/v1/stv/Projektarbeit.php +++ b/application/controllers/api/frontend/v1/stv/Projektarbeit.php @@ -280,6 +280,9 @@ class Projektarbeit extends FHCAPI_Controller */ public function getNoten() { + $this->NoteModel->addOrder('notenwert', 'ASC'); + $this->NoteModel->addOrder('bezeichnung', 'ASC'); + $result = $this->NoteModel->load(); if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); diff --git a/application/controllers/api/frontend/v1/stv/Status.php b/application/controllers/api/frontend/v1/stv/Status.php index 36d445fc6..3c0a639cd 100644 --- a/application/controllers/api/frontend/v1/stv/Status.php +++ b/application/controllers/api/frontend/v1/stv/Status.php @@ -636,7 +636,7 @@ class Status extends FHCAPI_Controller $this->load->library('PrestudentLib'); - $this->prestudentlib->setFirstStudent( + $resFirstStudent = $this->prestudentlib->setFirstStudent( $prestudent_id, $lastAufgenommener->studiensemester_kurzbz, $lastAufgenommener->ausbildungssemester, @@ -645,9 +645,8 @@ class Status extends FHCAPI_Controller $this->input->post('statusgrund_id') ); - $this->getDataOrTerminateWithError($result); - - $this->db->trans_commit(); + $this->db->trans_complete(); + $this->getDataOrTerminateWithError($resFirstStudent); return $this->outputJsonSuccess(true); } @@ -1078,6 +1077,24 @@ class Status extends FHCAPI_Controller $this->terminateWithSuccess(true); } + protected function checkForCriticalChangesBis($oldstatus) + { + $changedFields = array(); + $allowedFields = array('anmerkung', 'statusgrund_id'); + $oldstatus_array = get_object_vars($oldstatus); + foreach($oldstatus_array as $key => $oldValue) + { + $newValue = $this->input->post($key); + if( $newValue !== $oldValue ) + { + $changedFields[] = $key; + } + } + $criticalFieldsChanged = array_diff($changedFields, $allowedFields); + $hasCriticalChangesBis = count($criticalFieldsChanged) > 0 ? true : false; + return $hasCriticalChangesBis; + } + /** * Updates a status entry * @@ -1102,6 +1119,7 @@ class Status extends FHCAPI_Controller $oldstatus = current($oldstatus); + $hasCriticalChangesBis = $this->checkForCriticalChangesBis($oldstatus); $isBerechtigtNoStudstatusCheck = $this->permissionlib->isBerechtigt('student/keine_studstatuspruefung'); $isBerechtigtBasisPrestudentstatus = $this->permissionlib->isBerechtigt('basis/prestudentstatus'); @@ -1112,7 +1130,6 @@ class Status extends FHCAPI_Controller $ausbildungssemester = $this->input->post('ausbildungssemester') ?: $oldstatus->ausbildungssemester; $datum = $this->input->post('datum') ?: $oldstatus->datum; - //Form Validation $this->load->library('form_validation'); @@ -1135,9 +1152,15 @@ class Status extends FHCAPI_Controller $this->p->t('global', 'datum'), [ 'is_valid_date', - ['meldestichtag_not_exceeded', function ($value) use ($isBerechtigtNoStudstatusCheck) { + ['meldestichtag_not_exceeded', function ($value) use ($isBerechtigtNoStudstatusCheck, $hasCriticalChangesBis){ if ($isBerechtigtNoStudstatusCheck) - return true; // Skip if access right says so + { + return true; // Skip if access right says so*/ + } + if (!$hasCriticalChangesBis) { + return true; // Skip if no critical changes were made + } + if (!$value) return true; // Error will be handled by the required statement above diff --git a/application/controllers/api/frontend/v1/stv/Student.php b/application/controllers/api/frontend/v1/stv/Student.php index ad6883f94..7694807e7 100644 --- a/application/controllers/api/frontend/v1/stv/Student.php +++ b/application/controllers/api/frontend/v1/stv/Student.php @@ -108,6 +108,10 @@ class Student extends FHCAPI_Controller $this->PrestudentModel->addSelect('p.matr_nr'); $this->PrestudentModel->addSelect('p.anrede'); $this->PrestudentModel->addSelect('p.zugangscode'); + if($this->permissionlib->isBerechtigt('student/bpk')) + { + $this->PrestudentModel->addSelect('p.bpk'); + } if (defined('ACTIVE_ADDONS') && strpos(ACTIVE_ADDONS, 'bewerbung') !== false) { $this->PrestudentModel->addSelect( @@ -136,14 +140,9 @@ class Student extends FHCAPI_Controller ); } $this->PrestudentModel->addSelect( - "( - SELECT status_kurzbz - FROM public.tbl_prestudentstatus pss - WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id - AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . " - ORDER BY GREATEST(pss.datum, '0001-01-01') DESC - LIMIT 1 - ) AS statusofsemester" + "public.get_rolle_prestudent(public.tbl_prestudent.prestudent_id, " + . $this->PrestudentModel->escape($studiensemester_kurzbz) + . ") AS statusofsemester" ); $this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT'); @@ -321,6 +320,10 @@ class Student extends FHCAPI_Controller foreach ($array_allowed_props_benutzer as $prop) { $val = $this->input->post($prop); if ($val !== null) { + if($prop === 'alias' && $val === '') + { + $val = null; + } $update_benutzer[$prop] = $val; } } @@ -543,6 +546,7 @@ class Student extends FHCAPI_Controller $this->_validate(); + // TODO(chris): This should be in a library $this->load->model('crm/Student_model', 'StudentModel'); $this->load->model('crm/Prestudent_model', 'PrestudentModel'); $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); @@ -794,8 +798,8 @@ class Student extends FHCAPI_Controller $this->form_validation->set_rules('geschlecht', 'Geschlecht', 'callback_requiredIfNotPersonId', [ 'requiredIfNotPersonId' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'geschlecht')]) ]); - $this->form_validation->set_rules('gebdatum', 'Geburtsdatum', ['isValidDate', function($value) { return isValidDate($value); }], [ - 'isValidDate' => $this->p->t('ui', 'error_invalid_date') + $this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'is_valid_date', [ + 'is_valid_date' => $this->p->t('ui', 'error_invalid_date') ]); //$this->form_validation->set_rules('address[checked]', 'Address', 'required'); $this->form_validation->set_rules('address[plz]', 'PLZ', 'callback_requiredIfAddressFunc', [ diff --git a/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index 9dbea65f2..55f4b8976 100644 --- a/application/controllers/api/frontend/v1/stv/Students.php +++ b/application/controllers/api/frontend/v1/stv/Students.php @@ -611,7 +611,7 @@ class Students extends FHCAPI_Controller if (!$verband && !$gruppe && $orgform_kurzbz !== null) { $this->PrestudentModel->db->where( "( - SELECT orgform_kurzbz + SELECT orgform_kurzbz FROM public.tbl_prestudentstatus WHERE prestudent_id=tbl_prestudent.prestudent_id AND studiensemester_kurzbz=" . $this->PrestudentModel->escape($studiensemester_kurzbz) . " @@ -801,14 +801,9 @@ class Students extends FHCAPI_Controller //add status per semester $this->PrestudentModel->addSelect( - "( - SELECT status_kurzbz - FROM public.tbl_prestudentstatus pss - WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id - AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . " - ORDER BY GREATEST(pss.datum, '0001-01-01') DESC - LIMIT 1 - ) AS statusofsemester" + "public.get_rolle_prestudent(public.tbl_prestudent.prestudent_id, " + . $this->PrestudentModel->escape($studiensemester_kurzbz) + . ") AS statusofsemester" ); $this->addSelectPrioRel(); @@ -855,6 +850,41 @@ class Students extends FHCAPI_Controller { $stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL'; + $this->load->config('stv'); + $tags = $this->config->item('stv_prestudent_tags'); + + $whereTags = ''; + if (is_array($tags) && !isEmptyArray($tags)) { + $tags = array_keys($tags); + + foreach ($tags as $key => $tag) { + $tags[$key] = $this->db->escape($tag); + } + $whereTags = " AND nt.typ_kurzbz IN (" . implode(",", $tags) . ")"; + } + $subQueryTag = " + ( + SELECT + tag.prestudent_id, + COALESCE(json_agg(tag ORDER BY tag.done), '[]'::json) AS tags + FROM ( + SELECT DISTINCT ON (n.notiz_id) + n.notiz_id AS id, + nt.typ_kurzbz, + array_to_json(nt.bezeichnung_mehrsprachig)->>0 AS beschreibung, + n.text AS notiz, + nt.style, + n.erledigt AS done, + nz.prestudent_id + 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 + GROUP BY tag.prestudent_id + ) AS tag_data_agg + "; $this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT'); $this->PrestudentModel->addJoin('public.tbl_person p', 'person_id'); @@ -877,8 +907,11 @@ class Students extends FHCAPI_Controller AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ') AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')', 'LEFT'); + $this->PrestudentModel->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT'); + $this->PrestudentModel->addSelect("b.uid"); + $this->PrestudentModel->addSelect('tag_data_agg.tags'); $this->PrestudentModel->addSelect('titelpre'); $this->PrestudentModel->addSelect('nachname'); $this->PrestudentModel->addSelect('vorname'); @@ -897,14 +930,9 @@ class Students extends FHCAPI_Controller //add status per semester $this->PrestudentModel->addSelect( - "( - SELECT status_kurzbz - FROM public.tbl_prestudentstatus pss - WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id - AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . " - ORDER BY GREATEST(pss.datum, '0001-01-01') DESC - LIMIT 1 - ) AS statusofsemester" + "public.get_rolle_prestudent(public.tbl_prestudent.prestudent_id, " + . $this->PrestudentModel->escape($studiensemester_kurzbz) + . ") AS statusofsemester" ); $this->PrestudentModel->addSelect('UPPER(stg.typ || stg.kurzbz) AS studiengang'); @@ -941,6 +969,7 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect('mentor'); $this->PrestudentModel->addSelect('b.aktiv AS bnaktiv'); + $this->PrestudentModel->addSelect('unruly'); $this->PrestudentModel->db->where_in('tbl_prestudent.studiengang_kz', $this->allowedStgs); diff --git a/application/controllers/api/frontend/v1/stv/Tags.php b/application/controllers/api/frontend/v1/stv/Tags.php new file mode 100644 index 000000000..3004a1f3b --- /dev/null +++ b/application/controllers/api/frontend/v1/stv/Tags.php @@ -0,0 +1,48 @@ + self::BERECHTIGUNG_KURZBZ, + 'getTags' => self::BERECHTIGUNG_KURZBZ, + 'addTag' => self::BERECHTIGUNG_KURZBZ, + 'updateTag' => self::BERECHTIGUNG_KURZBZ, + 'doneTag' => self::BERECHTIGUNG_KURZBZ, + 'deleteTag' => self::BERECHTIGUNG_KURZBZ + ]); + + $this->config->load('stv'); + } + + public function getTag($readonly_tags = null) + { + parent::getTag($this->config->item('stv_prestudent_tags')); + } + public function getTags($tags = null) + { + parent::getTags($this->config->item('stv_prestudent_tags')); + } + public function addTag($withZuordnung = true, $updatable_tags = null) + { + parent::addTag(true, $this->config->item('stv_prestudent_tags')); + } + public function updateTag($updatable_tags = null) + { + parent::updateTag($this->config->item('stv_prestudent_tags')); + } + public function deleteTag($withZuordnung = true, $updatable_tags = null) + { + parent::deleteTag(true, $this->config->item('stv_prestudent_tags')); + } + public function doneTag($updatable_tags = null) + { + parent::doneTag($this->config->item('stv_prestudent_tags')); + } +} diff --git a/application/controllers/api/frontend/v1/stv/Verband.php b/application/controllers/api/frontend/v1/stv/Verband.php index eb25a548b..32ef30a45 100644 --- a/application/controllers/api/frontend/v1/stv/Verband.php +++ b/application/controllers/api/frontend/v1/stv/Verband.php @@ -215,6 +215,7 @@ class Verband extends FHCAPI_Controller $this->StudienordnungModel->addDistinct(); $this->StudienordnungModel->addSelect("CONCAT(studiengang_kz, '/', p.orgform_kurzbz) AS link"); $this->StudienordnungModel->addSelect("p.orgform_kurzbz AS name"); + $this->StudienordnungModel->addSelect("studiengang_kz AS stg_kz"); $this->StudienordnungModel->addJoin('lehre.tbl_studienplan p', 'studienordnung_id'); diff --git a/application/controllers/api/frontend/v1/stv/Vertrag.php b/application/controllers/api/frontend/v1/stv/Vertrag.php index f94fe795e..c2b0f713c 100644 --- a/application/controllers/api/frontend/v1/stv/Vertrag.php +++ b/application/controllers/api/frontend/v1/stv/Vertrag.php @@ -76,9 +76,7 @@ class Vertrag extends FHCAPI_Controller if (isError($allOe)) $this->terminateWithError(getError($allOe), self::ERROR_TYPE_GENERAL); - $allOe = hasData($allOe) ? getData($allOe) : []; - - $this->addMeta('oe', $allOe); + $allOe = hasData($allOe) ? array_column(getData($allOe), 'oe_kurzbz') : []; // * then check if the user has permissions to cancel the corresponding lv-organisational units if (!$this->permissionlib->isBerechtigtMultipleOe('admin', $allOe, 'suid') && diff --git a/application/controllers/api/frontend/v1/vertraege/Config.php b/application/controllers/api/frontend/v1/vertraege/Config.php new file mode 100644 index 000000000..a4ebd8c48 --- /dev/null +++ b/application/controllers/api/frontend/v1/vertraege/Config.php @@ -0,0 +1,62 @@ +. + */ + +if (!defined('BASEPATH')) exit('No direct script access allowed'); + +use CI3_Events as Events; + +/** + * This controller operates between (interface) the JS (GUI) and the back-end + * Provides data to the ajax get calls about the VV Config + * This controller works with JSON calls on the HTTP GET or POST and the output is always JSON + */ +class Config extends FHCAPI_Controller +{ + public function __construct() + { + parent::__construct([ + 'printDocument' => ['vertrag/mitarbeiter:r'], + ]); + } + + public function printDocument() + { + $params = []; + $menu = []; + + Events::trigger( + 'multiActionPrintHonorarvertrag', + // passing $menu per reference + function & () use (&$menu) { + return $menu; + }, + $params + ); + + if (is_array($menu) && isset($menu[0])) + { + $this->terminateWithSuccess($menu[0]); + } + else + { + // $this->terminateWithError('Error with Event 'multiActionPrintHonorarvertrag'); + $this->terminateWithSuccess(); + + } + } +} diff --git a/application/controllers/api/frontend/v1/vertraege/Vertraege.php b/application/controllers/api/frontend/v1/vertraege/Vertraege.php index bb14bc511..c0683e999 100644 --- a/application/controllers/api/frontend/v1/vertraege/Vertraege.php +++ b/application/controllers/api/frontend/v1/vertraege/Vertraege.php @@ -26,9 +26,6 @@ class Vertraege extends FHCAPI_Controller 'deleteLehrauftrag' =>['vertrag/mitarbeiter:w'], 'deleteBetreuung' =>['vertrag/mitarbeiter:w'], 'getMitarbeiter' => ['vertrag/mitarbeiter:r'], - 'getHeader' => ['vertrag/mitarbeiter:r'], - 'getPersonAbteilung' => ['vertrag/mitarbeiter:r'], - 'getLeitungOrg' => ['vertrag/mitarbeiter:r'], ]); //Load Models and Libraries @@ -241,7 +238,7 @@ class Vertraege extends FHCAPI_Controller } } $this->db->trans_complete(); - $this->terminateWithSuccess(true); + $this->terminateWithSuccess($vertrag_id); } public function updateContract() @@ -358,7 +355,7 @@ class Vertraege extends FHCAPI_Controller } $this->db->trans_complete(); - $this->terminateWithSuccess(true); + $this->terminateWithSuccess($vertrag_id); } public function loadContract($vertrag_id) @@ -684,37 +681,4 @@ class Vertraege extends FHCAPI_Controller } return $this->terminateWithSuccess(getData($result)); } - - public function getPersonAbteilung($mitarbeiter_uid) - { - $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); - - $result = $this->Mitarbeitermodel->getPersonAbteilung($mitarbeiter_uid); - - $data = $this->getDataOrTerminateWithError($result); - - $this->terminateWithSuccess(current($data)); - } - - public function getLeitungOrg($oekurzbz) - { - $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); - - $result = $this->Mitarbeitermodel->getLeitungOrg($oekurzbz); - - $data = $this->getDataOrTerminateWithError($result); - - $this->terminateWithSuccess(current($data)); - } - - public function getHeader($person_id) - { - $this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel'); - - $result = $this->Mitarbeitermodel->getHeader($person_id); - - $data = $this->getDataOrTerminateWithError($result); - - $this->terminateWithSuccess(current($data)); - } } diff --git a/application/controllers/dashboard/Widget.php b/application/controllers/dashboard/Widget.php index 0da6fe8da..9966ddc12 100644 --- a/application/controllers/dashboard/Widget.php +++ b/application/controllers/dashboard/Widget.php @@ -33,19 +33,26 @@ class Widget extends Auth_Controller return $this->outputJsonSuccess([ "widget_id" => 0, "widget_kurzbz" => "notfound", - "arguments" => json_encode([ + "arguments" => [ "className" => 'alert-danger', "title" => 'Widget Not Found', "msg" => 'The widget with the id ' . $widget_id . ' could not be found' - ]), - "setup" => json_encode([ + ], + "setup" => [ "name" => 'Widget Not Found', - "file" => 'DashboardWidget/Default.js', + "file" => absoluteJsImportUrl('public/js/components/DashboardWidget/Default.js'), "width" => 1, "height" => 1 - ]) + ] ]); - return $this->outputJsonSuccess(current(getData($widget))); + + $widget = current(getData($widget)); + $widget->arguments = json_decode($widget->arguments); + $tmpsetup = json_decode($widget->setup); + $tmpsetup->file = absoluteJsImportUrl($tmpsetup->file); + $widget->setup = $tmpsetup; + + return $this->outputJsonSuccess($widget); } public function getAll() @@ -56,7 +63,16 @@ class Widget extends Auth_Controller if (isError($result)) return $this->outputJsonError(getError($result)); - $this->outputJsonSuccess(getData($result) ?: []); + $tmpwidgets = getData($result) ?: []; + $widgets = array_map(function($widget) { + $widget->arguments = json_decode($widget->arguments); + $tmpsetup = json_decode($widget->setup); + $tmpsetup->file = absoluteJsImportUrl($tmpsetup->file); + $widget->setup = $tmpsetup; + return $widget; + }, $tmpwidgets); + + $this->outputJsonSuccess($widgets); } public function getWidgetsForDashboard() @@ -71,7 +87,16 @@ class Widget extends Auth_Controller ]); } - $this->outputJsonSuccess(getData($result) ?: []); + $tmpwidgets = getData($result) ?: []; + $widgets = array_map(function($widget) { + $widget->arguments = json_decode($widget->arguments); + $tmpsetup = json_decode($widget->setup); + $tmpsetup->file = absoluteJsImportUrl($tmpsetup->file); + $widget->setup = $tmpsetup; + return $widget; + }, $tmpwidgets); + + $this->outputJsonSuccess($widgets); } public function setAllowed() diff --git a/application/controllers/jobs/AbgabetoolJob.php b/application/controllers/jobs/AbgabetoolJob.php new file mode 100644 index 000000000..b81053032 --- /dev/null +++ b/application/controllers/jobs/AbgabetoolJob.php @@ -0,0 +1,913 @@ +_ci =& get_instance(); + + $this->_ci->load->helper('hlp_sancho_helper'); + + $this->_ci->load->model('education/Projektarbeit_model', 'ProjektarbeitModel'); + $this->_ci->load->model('education/Projektbetreuer_model', 'ProjektbetreuerModel'); + $this->_ci->load->model('education/Paabgabe_model', 'PaabgabeModel'); + $this->_ci->load->model('crm/Student_model', 'StudentModel'); + $this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->_ci->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel'); + + $this->_ci->load->library('SignatureLib'); + + $this->_ci->load->config('abgabe'); + $this->loadPhrases([ + 'abgabetool' + ]); + + + } + + // basically the notifyBetreuerMail function but email goes to assistenz + // and new abgaben are further evaluated for missing signature status + public function notifyAssistenzAboutMissingSignatureUploads() { + $this->_ci->logInfo('Start job FHC-Core->notifyAssistenzAboutMissingSignatureUploads'); + + $interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL'); + $relevantTypes = $this->_ci->config->item('RELEVANT_PAABGABETYPEN_SAMMELMAIL_ASSISTENZ'); + + $result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSinceByAbgabedatum($interval, $relevantTypes); + $retval = getData($result); + + // retval are paabgaben joined with projektarbeit and betreuer + if(count($retval) == 0) { + $this->logInfo("Keine Emails über neue Paabgaben an Assistenzen versandt"); + return; + } + + // group changed/new abgaben for projektarbeiten + $projektarbeiten = []; + foreach($retval as $abgabeWithNewUpload) { + // Check if the current item has a 'projektarbeit_id' field. + // Replace 'projektarbeit_id' with the actual key name if it's different. + if (isset($abgabeWithNewUpload->projektarbeit_id)) { + $projektarbeitId = $abgabeWithNewUpload->projektarbeit_id; + + // If the 'projektarbeit_id' is not yet a key in $projektarbeiten, + // initialize it as an empty array. + if (!isset($projektarbeiten[$projektarbeitId])) { + $projektarbeiten[$projektarbeitId] = []; + } + + // check signature for that abgabe, main point of this job + $this->checkAbgabeSignatur($abgabeWithNewUpload, $abgabeWithNewUpload->student_uid); + + // Add the current row to the array associated with its 'projektarbeit_id'. + $projektarbeiten[$projektarbeitId][] = $abgabeWithNewUpload; + } + } + + // for each projektarbeit fetch their assistenz and same them in their own dictionary to avoid too many mails + $assistenzMap = []; + // for each projektarbeit fetch their betreuer and save them in their own dictionary to avoid too many mails + $projektarbeitBetreuerMap = []; + forEach($projektarbeiten as $projektarbeit_id => $abgaben) { + + $assistenzResult = $this->_ci->OrganisationseinheitModel->getAssistenzForOE($abgaben[0]->stg_oe_kurzbz); + + forEach($assistenzResult->retval as $assistenzRow) { + if (!isset($assistenzMap[$assistenzRow->person_id])) { + $assistenzMap[$assistenzRow->person_id] = []; + } + + // Add the current $assistenzRow to the $assistenzMap as an array associated with its projektarbeit_id. + $assistenzMap[$assistenzRow->person_id][] = [$projektarbeit_id, $assistenzRow]; + } + + $betreuerResult = $this->_ci->ProjektbetreuerModel->getAllBetreuerOfProjektarbeit($projektarbeit_id); + + forEach($betreuerResult->retval as $betreuerRow) { + if (!isset($projektarbeitBetreuerMap[$projektarbeit_id])) { + $projektarbeitBetreuerMap[$projektarbeit_id] = []; + } + + // Add the current betreuerRow to the betreuerMap as an array associated with its projektarbeit_id. + $projektarbeitBetreuerMap[$projektarbeit_id][] = $betreuerRow; + } + + } + + $count = 0; + foreach($assistenzMap as $assistenz_person_id => $tupelArr) { + + $abgabenString = '
'; + $hasIssues = false; // Track if this assistant actually needs an email + + foreach($tupelArr as $tupel) { + $projektarbeit_id = $tupel[0]; + $assistenzRow = $tupel[1]; + + $betreuerArray = $projektarbeitBetreuerMap[$projektarbeit_id] ?? []; + $allAbgaben = $projektarbeiten[$projektarbeit_id]; + + // only keep abgaben that are not correctly signed + $issueAbgaben = array_filter($allAbgaben, function($abgabe) { + // We only care about cases where it's explicitly NOT true (false, error, or null) + return $abgabe->signatur !== true; + }); + + // if this specific project has no signature issues, skip to the next project + if(empty($issueAbgaben)) { + continue; + } + + // If we reached here, we have at least one issue to report + $hasIssues = true; + + // Format the Student Name (using the first available abgabe object) + $s = reset($issueAbgaben); + $nameParts = array_filter([$s->titelpre, $s->vorname, $s->nachname, $s->titelpost]); + $studentFullName = implode(' ', $nameParts); + + // Format the Supervisors string + $betreuerStrings = []; + foreach($betreuerArray as $b) { + $bNameParts = array_filter([$b->titelpre, $b->vorname, $b->nachname, $b->titelpost]); + $bFullName = implode(' ', $bNameParts); + $betreuerStrings[] = "{$bFullName} ({$b->betreuerart_kurzbz})"; + } + $allBetreuerFormatted = implode(', ', $betreuerStrings); + + $projektarbeit_titel = $s->titel ?? 'Kein Titel vergeben'; + + // Project Header Section + $abgabenString .= " +
+ Projekt: {$projektarbeit_titel}
+
+ Studierende/r: {$studentFullName} +
+
+ Betreuer: {$allBetreuerFormatted} +
+ + ID: {$projektarbeit_id} | Stg: {$s->stgtyp}{$s->stgkz} ({$s->studiensemester_kurzbz}) + +
"; + + // Start Table + $abgabenString .= ' + + + + + + + + + '; + + $printed = []; // lazy hack to avoid duplicate rows + foreach ($issueAbgaben as $abgabe) { + // if we had this paabgabe already (erstbetreuer/zweitbetreuer fetch achieves duplicates + if(in_array($abgabe->paabgabe_id, $printed)) { + continue; // skip this forEach iteration + } + + $printed[] = $abgabe->paabgabe_id; + + $abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y'); + + // label and color + if ($abgabe->signatur === false) { + $sigLabel = "FEHLENDE SIGNATUR"; + $sigBg = "#dc3545"; + } elseif ($abgabe->signatur === 'error') { + $sigLabel = "PRÜFUNG FEHLGESCHLAGEN"; + $sigBg = "#fd7e14"; + } else { + $sigLabel = "DATEI NICHT GEFUNDEN"; + $sigBg = "#6c757d"; + } + + $abgabenString .= " + + + + + "; + } + + $abgabenString .= '
DatumAbgabe/BezeichnungStatus
{$abgabedatumFormatted} + {$abgabe->bezeichnung} + + + {$sigLabel} + +
'; + } + + $abgabenString .= '
'; + + // only send the email if at least one project had an issue + if ($hasIssues) { + $assistenzRow = $tupelArr[0][1]; + $anrede = $assistenzRow->anrede; + $anredeFillString = $assistenzRow->anrede == "Herr" ? "r" : ""; + $fullFormattedNameString = $assistenzRow->first; + + $path = $this->_ci->config->item('URL_ASSISTENZ'); + $url = CIS_ROOT . $path; + + $body_fields = array( + 'anrede' => $anrede, + 'anredeFillString' => $anredeFillString, + 'fullFormattedNameString' => $fullFormattedNameString, + 'abgabenString' => $abgabenString, + 'linkAbgabetool' => $url + ); + + $email = $assistenzRow->uid . "@" . DOMAIN; + + sendSanchoMail( + 'PAANoSigAssSM', + $body_fields, + $email, + $this->p->t('abgabetool', 'c4missingSignatureNotification') + ); + + $count++; + } + } + + $this->_ci->logInfo($count . " Emails bezüglich fehlender Signaturen erfolgreich versandt"); + $this->_ci->logInfo('End job FHC-Core->notifyAssistenzAboutMissingSignatureUploads'); + } + + /** + * helper function to check the signature status of uploaded files for zwischenabgabe & endupload + */ + private function checkAbgabeSignatur($abgabe, $student_uid) { + $paabgabetypenToCheck = $this->config->item('SIGNATUR_CHECK_PAABGABETYPEN'); + + if(!in_array($abgabe->paabgabetyp_kurzbz, $paabgabetypenToCheck)) { + return; + } + + if (!defined('SIGNATUR_URL')) { + $abgabe->signatur = 'error'; + return; + } + + $path = PAABGABE_PATH.$abgabe->paabgabe_id.'_'.$student_uid.'.pdf'; + + $signaturVorhanden = null; // if frontend receives null -> indicates no file found at path + if(file_exists($path)) { + + // Check if the document is signed + $signList = SignatureLib::list($path); + if (is_array($signList) && count($signList) > 0) + { + // The document is signed + $signaturVorhanden = true; + } + elseif ($signList === null) + { + // frontend knows to handle it this way for signatures + $signaturVorhanden = 'error'; + } + else + { + $signaturVorhanden = false; + } + + $abgabe->signatur = $signaturVorhanden; + } + } + + public function notifyAssistenzAboutChangedAbgaben() { + + $this->_ci->logInfo('Start job FHC-Core->notifyAssistenzAboutChangedAbgaben'); + + $interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL'); + $relevantTypes = $this->_ci->config->item('RELEVANT_PAABGABETYPEN_SAMMELMAIL_ASSISTENZ'); + // get all new or changed termine in interval + $result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSince($interval, $relevantTypes); + + $retval = getData($result); + + if(count($retval) == 0) { + $this->_ci->logInfo("Keine Emails an Assistenzen über neue oder veränderte Termine versandt"); + return; + } + + // group changed/new abgaben for projektarbeiten + $projektarbeiten = []; + foreach($retval as $newOrChangedAbgabe) { + // Check if the current item has a 'projektarbeit_id' field. + // Replace 'projektarbeit_id' with the actual key name if it's different. + if (isset($newOrChangedAbgabe->projektarbeit_id)) { + $projektarbeitId = $newOrChangedAbgabe->projektarbeit_id; + + // If the 'projektarbeit_id' is not yet a key in $projektarbeiten, + // initialize it as an empty array. + if (!isset($projektarbeiten[$projektarbeitId])) { + $projektarbeiten[$projektarbeitId] = []; + } + + // Add the current row to the array associated with its 'projektarbeit_id'. + $projektarbeiten[$projektarbeitId][] = $newOrChangedAbgabe; + } + } + + // for each projektarbeit fetch their assistenz and same them in their own dictionary to avoid too many mails + $assistenzMap = []; + // for each projektarbeit fetch their betreuer and save them in their own dictionary to avoid too many mails + $projektarbeitBetreuerMap = []; + forEach($projektarbeiten as $projektarbeit_id => $abgaben) { + + $assistenzResult = $this->_ci->OrganisationseinheitModel->getAssistenzForOE($abgaben[0]->stg_oe_kurzbz); + + forEach($assistenzResult->retval as $assistenzRow) { + if (!isset($assistenzMap[$assistenzRow->person_id])) { + $assistenzMap[$assistenzRow->person_id] = []; + } + + // Add the current $assistenzRow to the $assistenzMap as an array associated with its projektarbeit_id. + $assistenzMap[$assistenzRow->person_id][] = [$projektarbeit_id, $assistenzRow]; + } + + $betreuerResult = $this->_ci->ProjektbetreuerModel->getAllBetreuerOfProjektarbeit($projektarbeit_id); + + forEach($betreuerResult->retval as $betreuerRow) { + if (!isset($projektarbeitBetreuerMap[$projektarbeit_id])) { + $projektarbeitBetreuerMap[$projektarbeit_id] = []; + } + + // Add the current betreuerRow to the betreuerMap as an array associated with its projektarbeit_id. + $projektarbeitBetreuerMap[$projektarbeit_id][] = $betreuerRow; + } + } + + $count = 0; + foreach($assistenzMap as $assistenz_person_id => $tupelArr) { + + $abgabenString = '
'; + + foreach($tupelArr as $tupel) { + $projektarbeit_id = $tupel[0]; + $assistenzRow = $tupel[1]; + + $betreuerArray = $projektarbeitBetreuerMap[$projektarbeit_id] ?? []; + $changedAbgaben = $projektarbeiten[$projektarbeit_id]; + + $relevantAbgaben = array_values(array_filter($changedAbgaben, function($abgabetermin) use ($assistenzRow) { + if($abgabetermin->updatevon == null && $abgabetermin->insertvon != $assistenzRow->uid) { + return $abgabetermin; + } else if($abgabetermin->updatevon != null && $abgabetermin->updatevon != $assistenzRow->uid) { + return $abgabetermin; + } + })); + + if(count($relevantAbgaben) == 0) { + continue; + } + + // Format the Student Name + $s = $relevantAbgaben[0]; + $nameParts = []; + if (!empty($s->titelpre)) $nameParts[] = $s->titelpre; + $nameParts[] = $s->vorname; + $nameParts[] = $s->nachname; + if (!empty($s->titelpost)) $nameParts[] = $s->titelpost; + $studentFullName = implode(' ', $nameParts); + + // Format the Supervisors string + $betreuerStrings = []; + foreach($betreuerArray as $b) { + $bNameParts = []; + if (!empty($b->titelpre)) $bNameParts[] = $b->titelpre; + $bNameParts[] = $b->vorname; + $bNameParts[] = $b->nachname; + if (!empty($b->titelpost)) $bNameParts[] = $b->titelpost; + + $bFullName = implode(' ', $bNameParts); + $betreuerStrings[] = "{$bFullName} ({$b->betreuerart_kurzbz})"; + } + $allBetreuerFormatted = implode(', ', $betreuerStrings); + + $projektarbeit_titel = $s->titel ?? 'Kein Titel vergeben'; + + // Project Header Section + $abgabenString .= " +
+ Projekt: {$projektarbeit_titel}
+
+ Studierende/r: {$studentFullName} +
+
+ Betreuer: {$allBetreuerFormatted} +
+ + ID: {$projektarbeit_id} | Stg: {$s->stgtyp}{$s->stgkz} ({$s->studiensemester_kurzbz}) + +
"; + + // Start Table + $abgabenString .= ' + + + + + + + + '; + + foreach ($relevantAbgaben as $abgabe) { + $dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y'); + $abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y'); + $kurzbzLine = !empty($abgabe->kurzbz) ? "
{$abgabe->kurzbz}" : ""; + + $abgabenString .= " + + + + "; + } + + $abgabenString .= '
ZieldatumBezeichnung
{$dateEmailFormatted} + {$abgabe->bezeichnung}{$kurzbzLine} +
'; + } + + $abgabenString .= '
'; + + // done with building the change list, now send it + $assistenzRow = $tupelArr[0][1]; + $anrede = $assistenzRow->anrede; + $anredeFillString = $assistenzRow->anrede == "Herr" ? "r" : ""; + $fullFormattedNameString = $assistenzRow->first; + + + + $path = $this->_ci->config->item('URL_ASSISTENZ'); + $url = CIS_ROOT.$path; + + $body_fields = array( + 'anrede' => $anrede, + 'anredeFillString' => $anredeFillString, + 'fullFormattedNameString' => $fullFormattedNameString, + 'abgabenString' => $abgabenString, + 'linkAbgabetool' => $url + ); + + $email = $assistenzRow->uid."@".DOMAIN; + + // send email with bundled info + sendSanchoMail( + 'PAAChangesAssSM', + $body_fields, + $email, + $this->p->t('abgabetool', 'changedAbgabeterminev2') + ); + + $count++; + } + + $this->_ci->logInfo($count . " Emails erfolgreich versandt"); + $this->_ci->logInfo('End job FHC-Core->notifyAssistenzAboutChangedAbgaben'); + } + + public function notifyBetreuerAboutChangedAbgaben() { + + $this->_ci->logInfo('Start job FHC-Core->notifyBetreuerAboutChangedAbgaben'); + + $interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL'); + + $relevantTypes = $this->_ci->config->item('RELEVANT_PAABGABETYPEN_SAMMELMAIL_BETREUER'); + + // get all new or changed termine in interval + $result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSince($interval, $relevantTypes); + $retval = getData($result); + if(!$retval) { + $this->_ci->logInfo("Keine Emails an Betreuer über neue oder veränderte Termine versandt"); + return; + } + + // group changed/new abgaben for projektarbeiten + $projektarbeiten = []; + foreach($retval as $newOrChangedAbgabe) { + // Check if the current item has a 'projektarbeit_id' field. + // Replace 'projektarbeit_id' with the actual key name if it's different. + if (isset($newOrChangedAbgabe->projektarbeit_id)) { + $projektarbeitId = $newOrChangedAbgabe->projektarbeit_id; + + // check if the updatevon field is NOT the same as the student the projektarbeit is assigned to + // since uploading a file to a paabgabe is also putting updateamum & updatevon + // we have our own "student has uploaded a file" emailjob anyways + if($newOrChangedAbgabe->student_uid === $newOrChangedAbgabe->updatevon) { + continue; + } + + // If the 'projektarbeit_id' is not yet a key in $projektarbeiten, + // initialize it as an empty array. + if (!isset($projektarbeiten[$projektarbeitId])) { + $projektarbeiten[$projektarbeitId] = []; + } + + // Add the current row to the array associated with its 'projektarbeit_id'. + $projektarbeiten[$projektarbeitId][] = $newOrChangedAbgabe; + } + } + + if(count($projektarbeiten) == 0) { + $this->_ci->logInfo("Keine Emails an Betreuer über neue oder veränderte Termine versandt"); + return; + } + + // for each projektarbeit fetch their betreuer and save them in their own dictionary to avoid too many mails + $betreuerMap = []; + forEach($projektarbeiten as $projektarbeit_id => $abgaben) { + $betreuerResult = $this->_ci->ProjektbetreuerModel->getAllBetreuerOfProjektarbeit($projektarbeit_id); + + forEach($betreuerResult->retval as $betreuerRow) { + if (!isset($betreuerMap[$betreuerRow->person_id])) { + $betreuerMap[$betreuerRow->person_id] = []; + } + + // Add the current betreuerRow to the betreuerMap as an array associated with its projektarbeit_id. + $betreuerMap[$betreuerRow->person_id][] = [$projektarbeit_id, $betreuerRow]; + } + } + + $count = 0; + // now iterate over the betreuerMap and build 1 email about all projektarbeiten and their new/changed termine + // $tupel = [$projektarbeit_id, $betreuerRow], each betreuer has 0..n [projektarbeit_id, changedAbgaben] tupel + forEach($betreuerMap as $betreuer_person_id => $tupelArr) { + + // start the container + $abgabenString = '
'; + + $result = $this->_ci->ProjektarbeitModel->getProjektbetreuerAnrede($betreuer_person_id); + $data = getData($result)[0]; + + $anrede = $data->anrede; + $anredeFillString = $data->anrede == "Herr" ? "r" : ""; + $fullFormattedNameString = $data->first; + + $relevantCounter = 0; // workaround to check if a betreuer needs to have any notification about relevant + // abgaben at all to avoid sending empty emails since we filter on certain conditions + forEach($tupelArr as $tupel) { + $projektarbeit_id = $tupel[0]; + $betreuerRow = $tupel[1]; + + $changedAbgaben = $projektarbeiten[$projektarbeit_id]; + + $relevantAbgaben = array_values(array_filter($changedAbgaben, function($abgabetermin) use ($betreuerRow) { + if($abgabetermin->updatevon == null && $abgabetermin->insertvon != $betreuerRow->uid) { + return $abgabetermin; + } else if($abgabetermin->updatevon != null && $abgabetermin->updatevon != $betreuerRow->uid) { + return $abgabetermin; + } + })); + + if(count($relevantAbgaben) == 0) { + continue; + } + + $relevantCounter++; + + // format the Student Name + $s = $relevantAbgaben[0]; + $nameParts = []; + if (!empty($s->titelpre)) $nameParts[] = $s->titelpre; + $nameParts[] = $s->vorname; + $nameParts[] = $s->nachname; + if (!empty($s->titelpost)) $nameParts[] = $s->titelpost; + $studentFullName = implode(' ', $nameParts); + + $projektarbeit_titel = $s->titel ?? 'Kein Titel vergeben'; + + // project header section + $abgabenString .= " +
+ Projekt: {$projektarbeit_titel}
+
+ Studierende/r: {$studentFullName} +
+ + ID: {$projektarbeit_id} | Rolle: {$betreuerRow->betreuerart_kurzbz} | + Stg: {$s->stgtyp}{$s->stgkz} ({$s->studiensemester_kurzbz}) + +
"; + + // start table + $abgabenString .= ' + + + + + + + + '; + + foreach ($relevantAbgaben as $abgabe) { + $dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y'); + $abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y'); + $kurzbzLine = !empty($abgabe->kurzbz) ? "
{$abgabe->kurzbz}" : ""; + + $abgabenString .= " + + + + "; + } + + $abgabenString .= '
ZieldatumBezeichnung
{$dateEmailFormatted} + {$abgabe->bezeichnung}{$kurzbzLine} +
'; + } + + // close container + $abgabenString .= '
'; + + // done with building the change list, now send it + $betreuerRow = $tupelArr[0][1]; + + if($relevantCounter == 0) { + $this->_ci->logInfo('No Relevant Abgaben to notify Betreuer PersonID: "'.$betreuerRow->person_id.'".'); + continue; + } + + $path = $this->_ci->config->item('URL_MITARBEITER'); + $url = CIS_ROOT.$path; + + $body_fields = array( + 'anrede' => $anrede, + 'anredeFillString' => $anredeFillString, + 'fullFormattedNameString' => $fullFormattedNameString, + 'abgabenString' => $abgabenString, + 'linkAbgabetool' => $url + ); + + $email = $betreuerRow->uid ? $betreuerRow->uid."@".DOMAIN : $betreuerRow->private_email; + + if(!$email) { + $this->_ci->logInfo('Could not send Email for Betreuer PersonID: "'.$data->person_id.'".'); + continue; + } + + // send email with bundled info + sendSanchoMail( + 'PAAChangesBetSM', + $body_fields, + $email, + $this->p->t('abgabetool', 'changedAbgabeterminev2') + ); + + $count++; + } + + $this->_ci->logInfo($count . " Emails erfolgreich versandt"); + $this->_ci->logInfo('End job FHC-Core->notifyBetreuerAboutChangedAbgaben'); + } + + public function notifyBetreuerMail() { + // send all new projektarbeit abgabe UPLOADS since the last job run to the related betreuer + // this job gathers all new or changed file uploads via field 'abgabedatum', enduploads still + // send an email directly after happening since they are kind of important + + $this->_ci->logInfo('Start job FHC-Core->notifyBetreuerMail'); + + // dont filter for relevant types since this mail should gather all UPLOAD info + + $interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL'); + + $result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSinceByAbgabedatum($interval); + $retval = getData($result); + + // retval are paabgaben joined with projektarbeit and betreuer + if(count($retval) == 0) { + $this->logInfo("Keine Emails über neue Paabgaben an Betreuer versandt"); + return; + } + + // group contents per betreuer person_id + $betreuer_uids = []; + forEach($retval as $paabgabe) { + if(!isset($betreuer_uids[$paabgabe->person_id])) { + $betreuer_uids[$paabgabe->person_id] = []; + } + + $betreuer_uids[$paabgabe->person_id][] = $paabgabe; + } + + $count = 0; + forEach ($betreuer_uids as $person_id => $abgaben) { + // $person_id is from betreuer + + $result = $this->_ci->ProjektarbeitModel->getProjektbetreuerAnrede($person_id); + $data = getData($result)[0]; + + $anrede = $data->anrede; + $anredeFillString = $data->anrede == "Herr" ? "r" : ""; + $fullFormattedNameString = $data->first; + + // sorting $abgaben array by datum + usort($abgaben, function ($a, $b) { + return strtotime($a->datum) <=> strtotime($b->datum); + }); + + $projektarbeit_titel = $abgaben[0]->titel; + + // initialize the table and headers + $abgabenString = ' + + + + + + + + + + '; + + foreach ($abgaben as $abgabe) { + // format the student name + $nameParts = []; + if (!empty($abgabe->titelpre)) $nameParts[] = $abgabe->titelpre; + $nameParts[] = $abgabe->vorname; + $nameParts[] = $abgabe->nachname; + if (!empty($abgabe->titelpost)) $nameParts[] = $abgabe->titelpost; + $studentFullName = implode(' ', $nameParts); + + // format dates inline + $dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y'); + $abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y'); + + // handle the optional Kurzbezeichnung + $kurzbzLine = !empty($abgabe->kurzbz) ? "
{$abgabe->kurzbz}" : ""; + + $abgabenString .= " + + + + + + "; + } + + $abgabenString .= '
ZieldatumStudierende/rBezeichnungAbgabedatum
{$dateEmailFormatted}{$studentFullName} + {$abgabe->bezeichnung}{$kurzbzLine} + {$abgabedatumFormatted}
'; + + $path = $this->_ci->config->item('URL_MITARBEITER'); + $url = CIS_ROOT.$path; + + $body_fields = array( + 'anrede' => $anrede, + 'anredeFillString' => $anredeFillString, + 'fullFormattedNameString' => $fullFormattedNameString, + 'paTitel' => $projektarbeit_titel, + 'abgabenString' => $abgabenString, + 'linkAbgabetool' => $url + ); + + $result = $this->_ci->ProjektbetreuerModel->getBetreuerOfProjektarbeit($abgaben[0]->projektarbeit_id, $abgaben[0]->betreuerart_kurzbz); + $data = getData($result)[0]; + + $email = $data->uid ? $data->uid."@".DOMAIN : $data->private_email; + + // in rare cases there are betreuer (often zweitbetreuer) without uid and without private email + if(!$email) { + $this->_ci->logInfo('Could not send Email for Betreuer PersonID: "'.$data->person_id.'".'); + continue; + } + + // send email with bundled info + sendSanchoMail( + 'PaabgabeUpdatesBetSM', + $body_fields, + $email, + $this->p->t('abgabetool', 'changedAbgabeterminev2') + ); + + $count++; + } + + $this->_ci->logInfo($count . " Emails erfolgreich versandt"); + $this->_ci->logInfo('End job FHC-Core->notifyBetreuerMail'); + } + + public function notifyStudentMail() + { + // send all new projektarbeit abgabe since the last job run to the related student + + $this->_ci->logInfo('Start job FHC-Core->notifyStudentMail'); + + $interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL'); + + $relevantTypes = $this->_ci->config->item('RELEVANT_PAABGABETYPEN_SAMMELMAIL_STUDENT'); + + $result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSince($interval, $relevantTypes); + $retval = getData($result); + + if(count($retval) == 0) { + $this->_ci->logInfo("Keine Emails an Studenten versandt"); + return; + } + + // group results per projektarbeit/student_uid + $student_uids = []; + forEach($retval as $paabgabe) { + if(!isset($student_uids[$paabgabe->student_uid])) { + $student_uids[$paabgabe->student_uid] = []; + } + + $student_uids[$paabgabe->student_uid][] = $paabgabe; + } + + $count = 0; + foreach ($student_uids as $uid => $abgaben) { + // $uid is the student's UID + $result = $this->_ci->StudentModel->getEmailAnredeForStudentUID($uid); + $data = getData($result)[0]; + + // $abgabe is the array of paabgabe objects + $anredeFillString = $data->anrede=="Herr"?"r":""; + $fullFormattedNameString = trim($data->titelpre." ".$data->vorname." ".$data->vornamen." ".$data->nachname." ".$data->titelpost); + + // https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.spaceship-op + // php has spaceships 🚀🚀🚀🚀🚀 + usort($abgaben, function($a, $b) { + return strtotime($a->datum) <=> strtotime($b->datum); + }); + + $projektarbeit_titel = $abgaben[0]->titel; + + // initialize the table and headers + $abgabenString = ' + + + + + + + + '; + + foreach ($abgaben as $abgabe) { + $dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y'); + + // handle the optional Kurzbezeichnung + $kurzbzLine = !empty($abgabe->kurzbz) ? "
{$abgabe->kurzbz}" : ""; + + $abgabenString .= " + + + + "; + } + + $abgabenString .= '
ZieldatumBezeichnung / Hinweis
+ {$dateEmailFormatted} + + {$abgabe->bezeichnung}{$kurzbzLine} +
'; + + $route = $this->_ci->config->item('URL_STUDENTS'); + $url = CIS_ROOT.$route; + + $body_fields = array( + 'anrede' => $data->anrede, + 'anredeFillString' => $anredeFillString, + 'fullFormattedNameString' => $fullFormattedNameString, + 'paTitel' => $projektarbeit_titel, + 'abgabenString' => $abgabenString, + 'linkAbgabetool' => $url + ); + + // send email with bundled info + sendSanchoMail( + 'PaabgabeUpdatesSammelmail', + $body_fields, + $uid.'@'.DOMAIN, + $this->p->t('abgabetool', 'changedAbgabeterminev2') + ); + + $count++; + + } + + $this->_ci->logInfo($count . " Emails erfolgreich versandt"); + $this->_ci->logInfo('End job FHC-Core->notifyStudentMail'); + } +} \ No newline at end of file diff --git a/application/controllers/jobs/AntragJob.php b/application/controllers/jobs/AntragJob.php index debcfe391..8dc4870ea 100644 --- a/application/controllers/jobs/AntragJob.php +++ b/application/controllers/jobs/AntragJob.php @@ -200,13 +200,14 @@ class AntragJob extends JOB_Controller } /** - * Send reminder to Assistant for Wiedereinstieg Unterbrecher + * Send reminder to Assistant and to Student for Wiedereinstieg Unterbrecher * */ public function sendReminderWiedereinstieg() { $now = new DateTime(); $modifier = $this->config->item('unterbrechung_job_remind_wiedereinstieg_date_modifier'); + if (!$modifier) return $this->logError('Konnte Job nicht starten: Config "unterbrechung_job_remind_wiedereinstieg_date_modifiers" nicht gesetzt'); @@ -230,6 +231,7 @@ class AntragJob extends JOB_Controller $antraege = getData($result) ?: []; $count = 0; + $countReminderStudent = 0; foreach ($antraege as $antrag) { $res = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id); @@ -257,10 +259,92 @@ class AntragJob extends JOB_Controller $data['UID'] = $student->student_uid; } - // NOTE(chris): Sancho mail - if(sendSanchoMail('Sancho_Mail_Antrag_U_Reminder', $data, $antrag->email, 'Reminder: Unterbrechung Wiedereinstieg')) + //Data für Email Student + $result = $this->PrestudentModel->load($antrag->prestudent_id); + $dataPrestudent = current(getData($result)); + $person_id = $dataPrestudent->person_id; + + $this->KontaktModel->addSelect('kontakt'); + + $result = $this->KontaktModel->loadWhere([ + 'person_id'=> $person_id, + 'zustellung' => true, + 'kontakttyp' => 'email' + ]); + + $email_student_privat = null; + $dataKontakt = getData($result); + if ($dataKontakt) { + $stud_private_zustell_emails = array_map(function($kontakt) { + return $kontakt->kontakt; + }, $dataKontakt); + $email_student_privat = implode(', ', $stud_private_zustell_emails); + } + + $email_student_FH = $this->StudentModel->getEmailFH($this->StudentModel->getUID($antrag->prestudent_id)); + + //studiensemester + $result = $this->StudiensemesterModel->getByDate($datum->format('Y-m-d')); + if (hasData($result)) { + $dataSem = current(getData($result)); + } + + $studiensemester = $dataSem->studiensemester_kurzbz; + $studsemShort = substr($studiensemester, 0, 2); + + if($studsemShort == "SS") + { + $data['studSemShort_Eng'] = "summer semester"; + $data['meldenBis'] = "15.1."; + $data['meldenBis_Eng'] = "January 15"; + } + elseif ($studsemShort == "WS") { + $data['studSemShort_Eng'] = "winter semester"; + $data['meldenBis'] = "1.8."; + $data['meldenBis_Eng'] = "August 1"; + } + else + { + $studsemShort = "SS/WS"; + $data['studSemShort_Eng'] = "summer/winter semester"; + $data['meldenBis'] = "15.1. (bei Einstieg ins SS) / 1.8. (bei Einstieg ins WS)"; + $data['meldenBis_Eng'] = "January 15 (for sommer semester enrollment) / August 1 (for winter semester enrollment)"; + } + + $data['studSemShort'] = $studsemShort; + + // NOTE(chris): Sancho mail Assistant + $sancho_assistant_sent = sendSanchoMail('Sancho_Mail_Antrag_U_Reminder', $data, $antrag->email, 'Reminder: Unterbrechung Wiedereinstieg'); + if($sancho_assistant_sent) { $count++; + } + else + { + $this->logError('Error: failed to send Assistant Reminder studierendenantrag_id: ' . $antrag->studierendenantrag_id); + } + //Mail to Student + $sancho_student_sent = sendSanchoMail( + 'Sancho_Mail_Antrag_U_Remind_Stud', + $data, + $email_student_FH, + 'Reminder: Unterbrechung Wiedereinstieg', + '', + '', + '', + $email_student_privat); + + if($sancho_student_sent) + { + $countReminderStudent++; + } + else + { + $this->logError('Error: failed to send Student Reminder studierendenantrag_id: ' . $antrag->studierendenantrag_id); + } + + if($sancho_assistant_sent && $sancho_student_sent) + { $this->StudierendenantragstatusModel->insert([ 'studierendenantrag_id' => $antrag->studierendenantrag_id, 'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_REMINDERSENT, @@ -268,7 +352,7 @@ class AntragJob extends JOB_Controller ]); } } - $this->logInfo($count . ' Reminder gesendet - Ende Job sendReminderWiedereinstieg'); + $this->logInfo($count . ' Reminder an Assistenz und ' . $countReminderStudent . ' Reminder an Student gesendet - Ende Job sendReminderWiedereinstieg'); } /** diff --git a/application/core/CI3_Events.php b/application/core/CI3_Events.php index 37f6c3f21..ad4aea729 100644 --- a/application/core/CI3_Events.php +++ b/application/core/CI3_Events.php @@ -35,7 +35,7 @@ class CI3_Events }); self::$eventsSorted[$event] = true; } - + foreach (self::$events[$event] as $conf) { $conf[1](...$args); } diff --git a/application/core/FHCAPI_Controller.php b/application/core/FHCAPI_Controller.php index dad56334d..e81506d4b 100644 --- a/application/core/FHCAPI_Controller.php +++ b/application/core/FHCAPI_Controller.php @@ -266,7 +266,7 @@ class FHCAPI_Controller extends Auth_Controller } // --------------------------------------------------------------- - // Security + // Security Begin // --------------------------------------------------------------- /** @@ -287,4 +287,31 @@ class FHCAPI_Controller extends Auth_Controller 'required_permissions' => $this->_rpsToString($requiredPermissions, $this->router->method) ], self::ERROR_TYPE_AUTH); } + + // --------------------------------------------------------------- + // Security End + // --------------------------------------------------------------- + + /** + * Checks the client's total request size (Content-Length) against the minimum + * effective PHP limit (min of upload_max_filesize, post_max_size, memory_limit). + * This preempts failures that result in vague "missing parameters" errors on large files. + * + * @return void + */ + protected function checkUploadSize() { + // this number represents bytes + $content_length_bytes = (int)$this->input->server('CONTENT_LENGTH'); + $content_length = $content_length_bytes / 1000000; + + //get max serverside size upload -> this comes in megabytes + $max_upload = (int)(ini_get('upload_max_filesize')); + $max_post = (int)(ini_get('post_max_size')); + $memory_limit = (int)(ini_get('memory_limit')); + $max_upload_mb = min($max_upload, $max_post, $memory_limit); // smallest of 3 config values + + if($content_length >= $max_upload_mb) { + $this->terminateWithError($this->p->t('global', 'filesizeExceeded'), 'general'); + } + } } diff --git a/application/core/Notiz_Controller.php b/application/core/Notiz_Controller.php index cfc54d5f5..923970923 100644 --- a/application/core/Notiz_Controller.php +++ b/application/core/Notiz_Controller.php @@ -8,7 +8,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller { const DEFAULT_PERMISSION_R = 'admin:r'; const DEFAULT_PERMISSION_RW = 'admin:rw'; - //public function __construct($zuordnung = 'person/Notizzuordnung_model') + public function __construct($permissions) { $default_permissions = [ @@ -97,13 +97,13 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess(getData($result) ?: []); + $this->terminateWithSuccess(getData($result) ?: []); } //Override function protected function isBerechtigt($id, $typeId){ - return $this->terminateWithError("in abstract function: define right in extension", self::ERROR_TYPE_GENERAL); + $this->terminateWithError("in abstract function: define right in extension", self::ERROR_TYPE_GENERAL); } public function loadNotiz() @@ -112,7 +112,6 @@ abstract class Notiz_Controller extends FHCAPI_Controller $notiz_id = $this->input->post('notiz_id'); - //$this->load->model('person/Notiz_model', 'NotizModel'); $this->NotizModel->addJoin('public.tbl_notiz_dokument', 'notiz_id', 'LEFT'); $this->NotizModel->addSelect('*'); $this->NotizModel->addSelect("TO_CHAR(CASE WHEN public.tbl_notiz.updateamum >= public.tbl_notiz.insertamum @@ -143,14 +142,9 @@ abstract class Notiz_Controller extends FHCAPI_Controller $uid = getAuthUID(); - if (isset($_POST['data'])) - { - $data = json_decode($_POST['data']); - unset($_POST['data']); - foreach ($data as $k => $v) { - $_POST[$k] = $v; - } - } + $json = $this->input->post('data'); + $post_data = json_decode($json, true); + $this->form_validation->set_data($post_data); //Form Validation $this->form_validation->set_rules('titel', 'Titel', 'required', [ @@ -166,26 +160,25 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->terminateWithValidationErrors($this->form_validation->error_array()); } - $titel = $this->input->post('titel'); - $text = $this->input->post('text'); - $erledigt = $this->input->post('erledigt'); - $verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid; - $bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : null; - $type = $this->input->post('typeId'); - $start = $this->input->post('start'); - $ende = $this->input->post('ende'); + $titel = $post_data['titel']; + $text = $post_data['text']; + $erledigt = $post_data['erledigt']; + $bearbeiter_uid = isset($post_data['bearbeiter']) ? $post_data['bearbeiter'] : null; + $type = $post_data['typeId']; + $start = isset($post_data['start']) ? $post_data['start'] : null; + $ende = isset($post_data['ende']) ? $post_data['ende'] : null; // Start DB transaction $this->db->trans_start(); //Save note - $result = $this->NotizModel->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $verfasser_uid, - "insertvon" => $verfasser_uid, 'start' => $start, 'ende' => $ende, 'bearbeiter_uid' => $bearbeiter_uid)); + $result = $this->NotizModel->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $uid, + "insertvon" => $uid, 'start' => $start, 'ende' => $ende, 'bearbeiter_uid' => $bearbeiter_uid)); if (isError($result)) { $this->db->trans_rollback(); - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } $notiz_id = $result->retval; @@ -220,7 +213,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->db->trans_rollback(); - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } $dms_id_arr[] = $result->retval['dms_id']; } @@ -235,34 +228,28 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->db->trans_rollback(); - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } } } $this->db->trans_commit(); - return $this->terminateWithSuccess($result); + $this->terminateWithSuccess($result); } public function updateNotiz() { + $this->load->library('form_validation'); $this->load->library('DmsLib'); - if (isset($_POST['data'])) - { - $data = json_decode($_POST['data']); - unset($_POST['data']); - foreach ($data as $k => $v) { - $_POST[$k] = $v; - } - } + $json = $this->input->post('data'); + $post_data = json_decode($json, true); - $notiz_id = $this->input->post('notiz_id'); + $this->form_validation->set_data($post_data); - if(!$notiz_id) - { - $this->terminateWithError($this->p->t('ui','error_missingId',['id'=>'Notiz_id']), self::ERROR_TYPE_GENERAL); - } + $this->form_validation->set_rules('notiz_id', 'Notiz ID', 'required', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'notiz_id']) + ]); //Form Validation $this->form_validation->set_rules('titel', 'Titel', 'required', [ @@ -280,25 +267,23 @@ abstract class Notiz_Controller extends FHCAPI_Controller //update Notiz $uid = getAuthUID(); - $titel = $this->input->post('titel'); - $text = $this->input->post('text'); - $verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid; - $bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : $uid; - $erledigt = $this->input->post('erledigt'); - $start = $this->input->post('start'); - $ende = $this->input->post('ende'); + $titel = $post_data['titel']; + $text = $post_data['text']; + $bearbeiter_uid = isset($post_data['bearbeiter']) ? $post_data['bearbeiter'] : $post_data['bearbeiter_uid']; + $erledigt = $post_data['erledigt']; + $start = $post_data['start']; + $ende = $post_data['ende']; $result = $this->NotizModel->update( [ - 'notiz_id' => $notiz_id + 'notiz_id' => $post_data['notiz_id'], ], [ 'titel' => $titel, 'updatevon' => $uid, 'updateamum' => date('c'), 'text' => $text, - 'verfasser_uid' => $verfasser_uid, - 'bearbeiter_uid' => $bearbeiter_uid, + 'bearbeiter_uid' => isEmptyString($bearbeiter_uid) ? null : $bearbeiter_uid, 'start' => $start, 'ende' => $ende, 'erledigt' => $erledigt @@ -306,7 +291,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller ); if (isError($result)) { - return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); + $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); } //update(1) loading all dms-entries with this notiz_id @@ -314,7 +299,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->load->model('person/Notizdokument_model', 'NotizdokumentModel'); $this->NotizdokumentModel->addJoin('campus.tbl_dms_version', 'dms_id'); - $result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $notiz_id)); + $result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $post_data['notiz_id'])); $result = $this->getDataOrTerminateWithError($result); foreach ($result as $doc) { $dms_id_arr[$doc->dms_id] = array( @@ -351,7 +336,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $result = $this->getDataOrTerminateWithError($result); $dms_id = $result['dms_id']; - $result = $this->NotizdokumentModel->insert(array('notiz_id' => $notiz_id, 'dms_id' => $dms_id)); + $result = $this->NotizdokumentModel->insert(array('notiz_id' => $post_data['notiz_id'], 'dms_id' => $dms_id)); $this->getDataOrTerminateWithError($result); } @@ -365,7 +350,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller $this->getDataOrTerminateWithError($result); } - return $this->terminateWithSuccess($result); + $this->terminateWithSuccess($result); } public function deleteNotiz() @@ -416,15 +401,15 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->db->trans_rollback(); - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } if(!hasData($result)) { - return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); } $this->db->trans_complete(); - return $this->terminateWithSuccess(getData($result)); + $this->terminateWithSuccess(getData($result)); } public function loadDokumente() @@ -440,14 +425,14 @@ abstract class Notiz_Controller extends FHCAPI_Controller array('public.tbl_notiz.notiz_id' => $notiz_id) ); if (isError($result)) { - return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); + $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } if(!hasData($result)) { - return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); + $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess(getData($result)); + $this->terminateWithSuccess(getData($result)); } public function getMitarbeiter($searchString) @@ -457,7 +442,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller if (isError($result)) { $this->terminateWithError($result, self::ERROR_TYPE_GENERAL); } - return $this->terminateWithSuccess($result); + $this->terminateWithSuccess($result); } public function getCountNotes($person_id) @@ -476,4 +461,4 @@ abstract class Notiz_Controller extends FHCAPI_Controller return $this->terminateWithSuccess($anzahl->anzahl ?: 0); } -} \ No newline at end of file +} diff --git a/application/helpers/hlp_common_helper.php b/application/helpers/hlp_common_helper.php index b13d9d44d..06cfa1cfd 100644 --- a/application/helpers/hlp_common_helper.php +++ b/application/helpers/hlp_common_helper.php @@ -91,7 +91,7 @@ function var_dump_to_error_log($parameter) var_dump($parameter); // KEEP IT!!! $ob_get_contents = ob_get_contents(); ob_end_clean(); - error_log(str_replace("\n", '', $ob_get_contents)); // KEEP IT!!! + error_log(str_replace("\n", '', $ob_get_contents) . ', referer: ' . "http".(!empty($_SERVER['HTTPS'])?"s":"")."://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']); // KEEP IT!!! } /** @@ -408,22 +408,6 @@ function findResource($path, $resource, $subdir = false, $extraDir = null) return null; } -/** - * check if String can be converted to a date - */ -function isValidDate($dateString) -{ - try - { - return (new DateTime($dateString)) !== false; - } - catch(Exception $e) - { - return false; - } -} - - // ------------------------------------------------------------------------ // PHP functions that don't exist in older versions // ------------------------------------------------------------------------ @@ -446,7 +430,8 @@ if (!function_exists('array_is_list')) { // ------------------------------------------------------------------------ /** - * check if string can be converted to a date + * Check if the provided parameter is a string containing a valid date + * NOTE: the name is in the "snake case" format because othewise the CI form validation _cannot_ use it */ function is_valid_date($dateString) { diff --git a/application/helpers/hlp_header_helper.php b/application/helpers/hlp_header_helper.php index 309bdedbd..27dfba5a1 100644 --- a/application/helpers/hlp_header_helper.php +++ b/application/helpers/hlp_header_helper.php @@ -185,7 +185,15 @@ function generateJSModulesInclude($JSModules) for ($tmpJSsCounter = 0; $tmpJSsCounter < count($tmpJSs); $tmpJSsCounter++) { - $toPrint = sprintf($jsInclude, base_url($tmpJSs[$tmpJSsCounter].$cachetoken)).PHP_EOL; + if($ci->config->item('use_fhcomplete_build_version_in_path')) + { + $relurl = preg_replace('#public/#', 'public/' . $ci->config->item('fhcomplete_build_version') . '/', $tmpJSs[$tmpJSsCounter]); + $toPrint = sprintf($jsInclude, base_url($relurl)).PHP_EOL; + } + else + { + $toPrint = sprintf($jsInclude, base_url($tmpJSs[$tmpJSsCounter].$cachetoken)).PHP_EOL; + } if ($tmpJSsCounter > 0) $toPrint = "\t\t".$toPrint; @@ -250,6 +258,210 @@ function generateSkipLink($skipID) function absoluteJsImportUrl($relurl) { $ci =& get_instance(); - $url = base_url($relurl) . '?'. $ci->config->item('fhcomplete_build_version'); + $ci->load->config('javascript'); + if($ci->config->item('use_fhcomplete_build_version_in_path')) + { + $url = base_url(preg_replace('#^public/#', 'public/' . $ci->config->item('fhcomplete_build_version') . '/', $relurl)); + } + else + { + $url = base_url($relurl) . '?'. $ci->config->item('fhcomplete_build_version'); + } return $url; -} \ No newline at end of file +} + +/* + * Manipulate CI views includes Array to load + * - public/js/FhcApps.js via customJSs and + * - app customisation js and/or css from extensions via customJSModules + * if customJSModules contains at least one vuejs app and customisation files + * exist in extensions + */ +class ExtendableAppsHelper +{ + private static $instance = null; + + protected $extensions; + + protected $customCSSs; + protected $customJSs; + protected $customJSModules; + + protected $initialised; + protected $appscount; + + protected $extCustomCSSs; + protected $extCustomJSs; + protected $extCustomJSModules; + + private function __construct() + { + $this->extensions = array(); + $this->customCSSs = null; + $this->customJSs = null; + $this->customJSModules = null; + + $this->initialised = false; + $this->appscount = 0; + + $this->extCustomCSSs = null; + $this->extCustomJSs = null; + $this->extCustomJSModules = null; + } + + public static function getInstance() + { + if(self::$instance === null) + { + self::$instance = new ExtendableAppsHelper(); + } + return self::$instance; + } + + public function init($customCSSs, $customJSs, $customJSModules) + { + if($this->initialised) + { + return; + } + + $this->customCSSs = $customCSSs; + $this->customJSs = $customJSs; + $this->customJSModules = $customJSModules; + $this->initialised = true; + + if(!isset($this->customJSModules)) + { + return; + } + + if(!is_array($this->customJSModules)) + { + $this->customJSModules = array($this->customJSModules); + } + + if(count($this->customJSModules) < 1) + { + return; + } + + $this->buildExtensionsList(); + $this->prepareExtendedArrays(); + } + + public function getCustomCSSs() + { + if(is_null($this->extCustomCSSs)) + { + return $this->customCSSs; + } + return $this->extCustomCSSs; + } + + public function getCustomJSs() + { + if(is_null($this->extCustomJSs)) + { + return $this->customJSs; + } + return $this->extCustomJSs; + } + + public function getCustomJSModules() + { + if(is_null($this->extCustomJSModules)) + { + return $this->customJSModules; + } + return $this->extCustomJSModules; + } + + protected function buildExtensionsList() + { + $this->extensions = array(); + $fsiterator = new FilesystemIterator(FHCPATH . 'application/extensions'); + foreach ($fsiterator as $fsitem) + { + if(preg_match('/^FHC-Core-/', $fsitem->getBasename())) + { + $this->extensions[] = $fsitem->getBasename(); + } + } + } + + protected function prepareExtendedArrays() + { + $this->appscount = 0; + $this->initExtCustomCSSs(); + $this->extCustomJSModules = array(); + foreach($this->customJSModules as $item) + { + $matches = array(); + if(preg_match('#^public/(extensions/FHC-Core-.+)?js/apps/(.*)\.js$#', $item, $matches)) + { + $this->appscount++; + + $fhcextension = $matches[1]; + $app = $matches[2]; + + $extend_js_suffix = 'js/extend_app/' . $fhcextension . $app . '.js'; + $extend_css_suffix = 'css/extend_app/' . $fhcextension . $app . '.css'; + + foreach($this->extensions as $extension) + { + $extend_js = 'public/extensions/' . $extension . '/' . $extend_js_suffix; + $extend_css = 'public/extensions/' . $extension . '/' . $extend_css_suffix; + + if(is_readable(FHCPATH . $extend_js)) + { + array_push($this->extCustomJSModules, $extend_js); + } + + if(is_readable(FHCPATH . $extend_css)) + { + array_push($this->extCustomCSSs, $extend_css); + } + } + } + array_push($this->extCustomJSModules, $item); + } + + if($this->appscount > 0) + { + $this->addFhcAppsJs(); + } + } + + protected function initExtCustomCSSs() + { + if(!isset($this->customCSSs)) + { + $this->extCustomCSSs = array(); + } + elseif(!is_array($this->customCSSs)) + { + $this->extCustomCSSs = array($this->customCSSs); + } + else + { + $this->extCustomCSSs = $this->customCSSs; + } + } + + protected function addFhcAppsJs() + { + if(!isset($this->customJSs)) + { + $this->extCustomJSs = array(); + } + elseif(!is_array($this->customJSs)) + { + $this->extCustomJSs = array($this->customJSs); + } + else + { + $this->extCustomJSs = $this->customJSs; + } + array_push($this->extCustomJSs, 'public/js/FhcApps.js'); + } +} diff --git a/application/libraries/DocsboxLib.php b/application/libraries/DocsboxLib.php index f9167c379..184855ad8 100644 --- a/application/libraries/DocsboxLib.php +++ b/application/libraries/DocsboxLib.php @@ -180,7 +180,8 @@ class DocsboxLib } // Just started or still working on it elseif ($getStatusResponse->body->status == self::STATUS_WORKING - || $getStatusResponse->body->status == self::STATUS_STARTED) + || $getStatusResponse->body->status == self::STATUS_STARTED + || $getStatusResponse->body->status == self::STATUS_QUEUED) { // go on! } diff --git a/application/libraries/PrestudentLib.php b/application/libraries/PrestudentLib.php index 28879fb47..b1f2dc900 100644 --- a/application/libraries/PrestudentLib.php +++ b/application/libraries/PrestudentLib.php @@ -68,7 +68,8 @@ class PrestudentLib $this->_ci->PrestudentModel->addOrder('zgv_code', 'DESC'); $this->_ci->PrestudentModel->addLimit(1); $result = $this->_ci->PrestudentModel->loadWhere([ - 'person_id' => $person_id + 'person_id' => $person_id, + 'zgv_code IS NOT NULL' => null ]); if (isError($result)) return $result; @@ -686,9 +687,6 @@ class PrestudentLib $now = date('c'); $today = date('Y-m-d'); - $jahr = mb_substr($studiensemester_kurzbz, 4, 2); - - // Genererate Personenkennzeichen $personenkennzeichen = $this->_ci->StudentModel->generateMatrikelnummer2( $student_data->studiengang_kz, @@ -698,8 +696,9 @@ class PrestudentLib if (isError($personenkennzeichen)) return $personenkennzeichen; $personenkennzeichen = getData($personenkennzeichen); - - + + $jahr = mb_substr($personenkennzeichen, 0, 2); + // Generate UID $uid = $this->_ci->StudentModel->generateUID( $student_data->kurzbz, @@ -724,7 +723,7 @@ class PrestudentLib // Generate Alias - $alias = ''; + $alias = null; if (!defined('GENERATE_ALIAS_STUDENT') || GENERATE_ALIAS_STUDENT === true ) { diff --git a/application/models/accounting/Vertrag_model.php b/application/models/accounting/Vertrag_model.php index 4c036369b..97b5c72b6 100644 --- a/application/models/accounting/Vertrag_model.php +++ b/application/models/accounting/Vertrag_model.php @@ -490,6 +490,175 @@ class Vertrag_model extends DB_Model return $bezeichnung; } + /** + * Loads all Contracts of a Person + * @param $person_id + * @return array of objects + */ + public function loadContractsOfPerson($person_id) + { + $query = " + SELECT + *, + tbl_vertrag.bezeichnung as bezeichnung, + tbl_vertragstyp.bezeichnung as vertragstyp_bezeichnung, + tbl_vertrag.vertragsdatum, + (SELECT bezeichnung FROM lehre.tbl_vertragsstatus + JOIN lehre.tbl_vertrag_vertragsstatus USING(vertragsstatus_kurzbz) + WHERE vertrag_id=tbl_vertrag.vertrag_id ORDER BY datum desc limit 1) as status, anmerkung, + CASE + WHEN EXISTS ( + SELECT 1 + FROM lehre.tbl_vertrag_vertragsstatus + WHERE vertrag_id = tbl_vertrag.vertrag_id + AND vertragsstatus_kurzbz = 'abgerechnet' + ) THEN true + ELSE false + END AS isAbgerechnet + FROM + lehre.tbl_vertrag + LEFT JOIN lehre.tbl_vertragstyp USING(vertragstyp_kurzbz) + WHERE person_id= ?"; + + + return $this->execQuery($query, array($person_id)); + } + + /** + * Loads all Contracts of a Person that are not assigned yet + * @param $person_id + * @return array of objects + */ + public function loadContractsOfPersonNotAssigned($person_id) + { + $query = " +SELECT + 'Lehrauftrag' as type, + lehreinheit_id, + mitarbeiter_uid, + null as pruefung_id, + null as projektarbeit_id, + (tbl_lehreinheitmitarbeiter.semesterstunden*tbl_lehreinheitmitarbeiter.stundensatz) as betrag1, + tbl_lehreinheit.studiensemester_kurzbz, + null as betreuerart_kurzbz, + ( SELECT + upper(tbl_studiengang.typ || tbl_studiengang.kurzbz) || tbl_lehrveranstaltung.semester || '-' || tbl_lehrveranstaltung.kurzbz || '-' || tbl_lehreinheit.lehrform_kurzbz + FROM + lehre.tbl_lehrveranstaltung + JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE + lehrveranstaltung_id=tbl_lehreinheit.lehrveranstaltung_id) + as bezeichnung + FROM + lehre.tbl_lehreinheitmitarbeiter + JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + WHERE + mitarbeiter_uid IN (SELECT uid FROM public.tbl_benutzer WHERE person_id=?) + AND vertrag_id IS NULL + UNION + SELECT + 'Betreuung' as type, + tbl_projektarbeit.lehreinheit_id as lehreinheit_id, + null as mitarbeiter_uid, + null::integer as pruefung_id, + projektarbeit_id, + (tbl_projektbetreuer.stunden*tbl_projektbetreuer.stundensatz) as betrag1, + tbl_lehreinheit.studiensemester_kurzbz, + tbl_projektbetreuer.betreuerart_kurzbz, + (SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid) + as bezeichnung + FROM + lehre.tbl_projektbetreuer + JOIN lehre.tbl_projektarbeit USING(projektarbeit_id) + JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + WHERE + tbl_projektbetreuer.person_id=? + AND vertrag_id IS NULL + "; + + return $this->execQuery($query, array($person_id, $person_id)); + } + + /** + * Loads all Contracts of a Person that are assigned yet + * @param $person_id, $vertrag_id + * @return array of objects + */ + + public function loadContractsOfPersonAssigned($person_id, $vertrag_id) + { + $query = " + SELECT + 'Lehrauftrag' as type, + lehreinheit_id, + mitarbeiter_uid, + null as pruefung_id, + null as projektarbeit_id, + (tbl_lehreinheitmitarbeiter.semesterstunden * tbl_lehreinheitmitarbeiter.stundensatz) as betrag, + tbl_lehreinheit.studiensemester_kurzbz, + null as betreuerart_kurzbz, + ( SELECT + upper(tbl_studiengang.typ || tbl_studiengang.kurzbz) || tbl_lehrveranstaltung.semester || '-' || tbl_lehrveranstaltung.kurzbz || '-' || tbl_lehreinheit.lehrform_kurzbz + FROM + lehre.tbl_lehrveranstaltung + JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE + lehrveranstaltung_id=tbl_lehreinheit.lehrveranstaltung_id) + as bezeichnung, vertrag_id + FROM + lehre.tbl_lehreinheitmitarbeiter + JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + WHERE + mitarbeiter_uid IN (SELECT uid FROM public.tbl_benutzer WHERE person_id=?) + AND vertrag_id = ? + UNION + SELECT + 'Betreuung' as type, + tbl_projektarbeit.lehreinheit_id as lehreinheit_id, + null as mitarbeiter_uid, + null::integer as pruefung_id, + projektarbeit_id, + (tbl_projektbetreuer.stunden * tbl_projektbetreuer.stundensatz) as betrag, + tbl_lehreinheit.studiensemester_kurzbz, + tbl_projektbetreuer.betreuerart_kurzbz, + (SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid) + as bezeichnung, vertrag_id + FROM + lehre.tbl_projektbetreuer + JOIN lehre.tbl_projektarbeit USING(projektarbeit_id) + JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + WHERE + tbl_projektbetreuer.person_id=? + AND vertrag_id = ? + "; + + return $this->execQuery($query, array($person_id, $vertrag_id, $person_id, $vertrag_id)); + } + + /** + * Returns all stati of a contract + * + * @param $vertrag_id + * @return array + */ + public function getStatiOfContract($vertrag_id) + { + $query = " + SELECT + *, + tbl_vertrag_vertragsstatus.datum, + tbl_vertrag_vertragsstatus.insertamum, + tbl_vertrag_vertragsstatus.updateamum + FROM + lehre.tbl_vertrag_vertragsstatus + JOIN lehre.tbl_vertragsstatus USING(vertragsstatus_kurzbz) + WHERE + tbl_vertrag_vertragsstatus.vertrag_id = ? + ORDER BY tbl_vertrag_vertragsstatus.datum DESC"; + + return $this->execQuery($query, array($vertrag_id)); + } + private function _updateVertragRelevant($vertrag_id) { $this->LehreinheitmitarbeiterModel->update( diff --git a/application/models/accounting/Vertragstyp_model.php b/application/models/accounting/Vertragstyp_model.php index 42d248217..a3275af6e 100644 --- a/application/models/accounting/Vertragstyp_model.php +++ b/application/models/accounting/Vertragstyp_model.php @@ -11,4 +11,5 @@ class Vertragstyp_model extends DB_Model $this->dbTable = 'lehre.tbl_vertragstyp'; $this->pk = 'vertragstyp_kurzbz'; } + } diff --git a/application/models/accounting/Vertragvertragsstatus_model.php b/application/models/accounting/Vertragvertragsstatus_model.php index 78a065540..75b0794cc 100644 --- a/application/models/accounting/Vertragvertragsstatus_model.php +++ b/application/models/accounting/Vertragvertragsstatus_model.php @@ -190,4 +190,6 @@ class Vertragvertragsstatus_model extends DB_Model return $this->loadWhere($condition); } + + } diff --git a/application/models/crm/Reihungstest_model.php b/application/models/crm/Reihungstest_model.php index a685b01cd..efef0a8fa 100644 --- a/application/models/crm/Reihungstest_model.php +++ b/application/models/crm/Reihungstest_model.php @@ -10,7 +10,7 @@ class Reihungstest_model extends DB_Model parent::__construct(); $this->dbTable = 'public.tbl_reihungstest'; $this->pk = 'reihungstest_id'; - } + } /** * Gets a test from a test id only if it is available @@ -42,8 +42,8 @@ class Reihungstest_model extends DB_Model /** * Checks if there are active studyplans which have no public placement tests assigned yet. * Only check assignment to studyplans that are - * - Bachelor, - * - active, + * - Bachelor, + * - active, * - set as online application * - valid for 1st terms * @return array Returns object array with studyplans that have no public placement tests assigned yet. @@ -97,7 +97,7 @@ class Reihungstest_model extends DB_Model USING (reihungstest_id) WHERE datum >= now() - AND + AND oeffentlich = \'t\' ) '; @@ -105,7 +105,7 @@ class Reihungstest_model extends DB_Model return $this->execQuery($query); } - /** + /** * Gets amount of free places. * @return array Returns object array with faculty and amount of free places * for each public actual placement test date. @@ -432,10 +432,10 @@ class Reihungstest_model extends DB_Model } /** - * Loads all applicants of a placement test - * @param integer $reihungstest_id ID of placement test - * @return array Returns object array with data of applicants. - */ + * Loads all applicants of a placement test + * @param integer $reihungstest_id ID of placement test + * @return array Returns object array with data of applicants. + */ public function getApplicantsOfPlacementTest($reihungstest_id) { $query = ' @@ -556,13 +556,22 @@ class Reihungstest_model extends DB_Model * Calculates Result of Placement Test for a given Person and given placementtest * and with taking account of weighting per area * - * @param $person_id ID of Person - * @param $punkte if true result is points else result is percentage of sum - * @param $reihungstest_id ID of Placementtest - * @param $weightedArray array of weighting per area (gewicht per gebiet_id) - * @return float result + * @param Number $person_id ID of Person + * @param Boolean $punkte if true result is points else result is percentage of sum + * @param Number $reihungstest_id ID of Placementtest + * @param Array $weightedArray array of weighting per area (gewicht per gebiet_id) + * @param Boolean $has_excluded_gebiete if true, areas in the configArray will be excluded + * @param Array $basis_gebiet_id_toString areas to exclude + * @return float result points of RT */ - public function getReihungstestErgebnisPerson($person_id, $punkte, $reihungstest_id, $weightedArray = null) + public function getReihungstestErgebnisPerson( + $person_id, + $punkte, + $reihungstest_id, + $weightedArray = null, + $has_excluded_gebiete = false, + $basis_gebiet_id_toString = null + ) { $parametersArray = array($reihungstest_id); @@ -577,6 +586,35 @@ class Reihungstest_model extends DB_Model WHERE reihungstest_id = ? "; + //areas of Studiengang + if (!empty($basis_gebiet_id_toString)) + { + $qry .= " + AND + gebiet_id IN (". $basis_gebiet_id_toString. ") + "; + } + + //areas to exclude + if($has_excluded_gebiete) + { + if (defined('FAS_REIHUNGSTEST_EXCLUDE_GEBIETE') && !empty(FAS_REIHUNGSTEST_EXCLUDE_GEBIETE)) + { + $excluded_gebiete = unserialize(FAS_REIHUNGSTEST_EXCLUDE_GEBIETE); + $exclude_gebiet_id_arr = $excluded_gebiete; + if (is_array($exclude_gebiet_id_arr) && count($exclude_gebiet_id_arr) > 0) + { + $exclude_gebiet_id_toString = implode(', ', $exclude_gebiet_id_arr); + $qry .= " + AND + gebiet_id NOT IN (". $exclude_gebiet_id_toString. ") + -- AND + -- typ = 'b' + "; + } + } + } + //using prestudent Status to avoid to get the sum of more than 1 placement tests $qry .= " AND prestudent_id = ( diff --git a/application/models/crm/Student_model.php b/application/models/crm/Student_model.php index 6f2404cbd..ab073996f 100644 --- a/application/models/crm/Student_model.php +++ b/application/models/crm/Student_model.php @@ -169,7 +169,7 @@ class Student_model extends DB_Model $max = 0; if ($matrikelnrres && hasData($matrikelnrres)) { - $max = mb_substr(getData($matrikelnrres)[0]->matrikelnr, 7); + $max = mb_substr(trim(getData($matrikelnrres)[0]->matrikelnr), -3); if (!is_numeric($max)) { $max = (int)$max; } @@ -279,4 +279,12 @@ class Student_model extends DB_Model { return $student_uid . '@' . DOMAIN; } + + public function getEmailAnredeForStudentUID($student_uid) { + $qry = "SELECT anrede, titelpre, vorname, vornamen, nachname, titelpost + FROM campus.vw_student + WHERE uid = ?"; + + return $this->execReadOnlyQuery($qry, array($student_uid)); + } } diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index 7347cf2ca..ccac33bc7 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -316,8 +316,8 @@ class Lehrveranstaltung_model extends DB_Model (SELECT status_kurzbz FROM public.tbl_prestudentstatus WHERE prestudent_id=tbl_student.prestudent_id ORDER BY datum DESC, insertamum DESC, ext_id DESC LIMIT 1) as status, tbl_bisio.bisio_id, tbl_bisio.von, tbl_bisio.bis, tbl_student.studiengang_kz AS stg_kz_student, tbl_zeugnisnote.note, tbl_mitarbeiter.mitarbeiter_uid, tbl_person.matr_nr, tbl_benutzer.uid, - UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as kuerzel, tbl_studiengang.orgform_kurzbz, vw_student_lehrveranstaltung.semester, vw_student_lehrveranstaltung.studiensemester_kurzbz, vw_student_lehrveranstaltung.bezeichnung - + UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) as kuerzel, tbl_studiengang.orgform_kurzbz, vw_student_lehrveranstaltung.semester, vw_student_lehrveranstaltung.studiensemester_kurzbz, vw_student_lehrveranstaltung.bezeichnung, + tbl_student.prestudent_id FROM campus.vw_student_lehrveranstaltung JOIN public.tbl_benutzer USING(uid) @@ -386,6 +386,37 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($query, array($lehrveranstaltung_id, $studiensemester_kurzbz)); } + + /** + * Get LV-Leitung of given Lehrveranstaltung ID and Studiensemester. + * + * @param $lehrveranstaltung_id + * @param $studiensemester + * @return array|stdClass|null + */ + public function getLvLeitung($lehrveranstaltung_id, $studiensemester) + { + $params = [$lehrveranstaltung_id, $studiensemester]; + + $qry = " + SELECT + vorname, nachname, mitarbeiter_uid, lehrfunktion_kurzbz + FROM + lehre.tbl_lehreinheit + JOIN lehre.tbl_lehreinheitmitarbeiter lema USING (lehreinheit_id) + JOIN public.tbl_benutzer b ON b.uid = lema.mitarbeiter_uid + JOIN public.tbl_person p using (person_id) + WHERE + tbl_lehreinheit.lehrveranstaltung_id= ? + AND tbl_lehreinheit.studiensemester_kurzbz = ? + AND lehrfunktion_kurzbz = 'LV-Leitung' + ORDER BY + lema.insertamum DESC + LIMIT 1 + "; + + return $this->execQuery($qry, $params); + } /** * Gets all Leiter of Lehrveranstaltungsorganisationseinheit * @param $lehrveranstaltung_id diff --git a/application/models/education/Note_model.php b/application/models/education/Note_model.php index 80b454398..87a1501e0 100644 --- a/application/models/education/Note_model.php +++ b/application/models/education/Note_model.php @@ -11,4 +11,12 @@ class Note_model extends DB_Model $this->dbTable = 'lehre.tbl_note'; $this->pk = 'note'; } + + public function getAllActive() { + $qry ="SELECT * + FROM lehre.tbl_note + WHERE aktiv = true"; + + return $this->execReadOnlyQuery($qry); + } } \ No newline at end of file diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index 343a86706..be42b7660 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -60,5 +60,69 @@ class Paabgabe_model extends DB_Model return $this->execReadOnlyQuery($qry, array($person_id)); } + + public function findAbgabenNewOrUpdatedSince($interval, $relevantTypes) + { + + $query = "SELECT projektarbeit_id, paabgabe_id, paabgabetyp_kurzbz, fixtermin, datum, campus.tbl_paabgabe.kurzbz, campus.tbl_paabgabetyp.bezeichnung, campus.tbl_paabgabe.abgabedatum, + campus.tbl_paabgabe.insertvon, campus.tbl_paabgabe.insertamum, campus.tbl_paabgabe.updatevon, campus.tbl_paabgabe.updateamum, + campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid, tbl_projektarbeit.note, lehre.tbl_projektarbeit.titel, + UPPER(tbl_studiengang.typ) as stgtyp, UPPER(tbl_studiengang.kurzbz) as stgkz, public.tbl_studiengang.studiengang_kz, + public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_lehreinheit.studiensemester_kurzbz, + public.tbl_person.anrede, public.tbl_person.titelpre, public.tbl_person.vorname, public.tbl_person.nachname, public.tbl_person.titelpost + FROM campus.tbl_paabgabe + JOIN campus.tbl_paabgabetyp USING (paabgabetyp_kurzbz) + JOIN lehre.tbl_projektarbeit USING (projektarbeit_id) + JOIN lehre.tbl_lehreinheit using(lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id) + JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz) + JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid) + JOIN public.tbl_person USING (person_id) + + WHERE (campus.tbl_paabgabe.insertamum >= NOW() - INTERVAL ? + OR campus.tbl_paabgabe.updateamum >= NOW() - INTERVAL ?) + AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?"; + + return $this->execQuery($query, [$interval, $interval, $relevantTypes]); + } + + public function findAbgabenNewOrUpdatedSinceByAbgabedatum($interval, $relevantTypes = null) { + + $queryParams = [$interval]; + $query = "SELECT projektarbeit_id, paabgabe_id, paabgabetyp_kurzbz, fixtermin, datum, campus.tbl_paabgabe.kurzbz, campus.tbl_paabgabetyp.bezeichnung, campus.tbl_paabgabe.abgabedatum, + campus.tbl_paabgabe.insertvon, campus.tbl_paabgabe.insertamum, campus.tbl_paabgabe.updatevon, campus.tbl_paabgabe.updateamum, + campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid, tbl_projektarbeit.note, lehre.tbl_projektarbeit.titel, + UPPER(tbl_studiengang.typ) as stgtyp, UPPER(tbl_studiengang.kurzbz) as stgkz, public.tbl_studiengang.studiengang_kz, + public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_lehreinheit.studiensemester_kurzbz, + lehre.tbl_projektbetreuer.betreuerart_kurzbz, lehre.tbl_projektbetreuer.person_id, + public.tbl_person.anrede, public.tbl_person.titelpre, public.tbl_person.vorname, public.tbl_person.nachname, public.tbl_person.titelpost + + FROM campus.tbl_paabgabe + JOIN campus.tbl_paabgabetyp USING (paabgabetyp_kurzbz) + JOIN lehre.tbl_projektarbeit USING (projektarbeit_id) + JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) + JOIN lehre.tbl_lehreinheit using(lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id) + JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz) + JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid) + JOIN public.tbl_person ON (public.tbl_benutzer.person_id = public.tbl_person.person_id) + + WHERE campus.tbl_paabgabe.abgabedatum IS NOT NULL + AND campus.tbl_paabgabe.abgabedatum >= NOW() - INTERVAL ?"; + + if($relevantTypes !== null) { + $query .= " AND campus.tbl_paabgabe.paabgabetyp_kurzbz IN ?"; + $queryParams[]= $relevantTypes; + } + + $query .= " ORDER BY abgabedatum DESC"; + + return $this->execQuery($query, $queryParams); + } + public function loadByIDs($paabgabe_ids) { + $qry = "SELECT * FROM campus.tbl_paabgabe WHERE paabgabe_id IN ?"; + + return $this->execReadOnlyQuery($qry, [$paabgabe_ids]); + } } diff --git a/application/models/education/Paabgabetyp_model.php b/application/models/education/Paabgabetyp_model.php index b672a3f0e..034daca44 100644 --- a/application/models/education/Paabgabetyp_model.php +++ b/application/models/education/Paabgabetyp_model.php @@ -11,4 +11,10 @@ class Paabgabetyp_model extends DB_Model $this->dbTable = 'campus.tbl_paabgabetyp'; $this->pk = 'paabgabetyp_kurzbz'; } + + public function getAll() { + $qry = "SELECT * FROM campus.tbl_paabgabetyp ORDER BY bezeichnung"; + + return $this->execReadOnlyQuery($qry); + } } diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index 414d1d1be..3b1ea55e5 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -64,16 +64,16 @@ class Projektarbeit_model extends DB_Model if (isset($projekttyp)) { if (is_array($projekttyp)) - $qry .= ' AND tbl_projektarbeit.projekttyp_kurzbz IN ?'; + $qry .= ' AND pa.projekttyp_kurzbz IN ?'; else - $qry .= ' AND tbl_projektarbeit.projekttyp_kurzbz=?'; + $qry .= ' AND pa.projekttyp_kurzbz=?'; $params[] = $projekttyp; } if (isset($final)) { - $qry .= ' AND tbl_projektarbeit.final=?'; + $qry .= ' AND pa.final=?'; $params[] = $final; } @@ -109,36 +109,36 @@ class Projektarbeit_model extends DB_Model */ public function getStudentProjektarbeitenWithBetreuer($studentUID) { - $betreuerQuery = " - SELECT + $betreuerQuery = "SELECT * FROM (SELECT DISTINCT ON(projektarbeit_id) vorname as bvorname, nachname as bnachname, titelpre as btitelpre, titelpost AS btitelpost, - titelpost AS btitelpost, tbl_betreuerart.beschreibung AS betreuerart_beschreibung, - (SELECT person_id - FROM lehre.tbl_projektbetreuer + (SELECT person_id + FROM lehre.tbl_projektbetreuer WHERE projektarbeit_id=tbl_projektarbeit.projektarbeit_id - AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter') LIMIT 1) AS zweitbetreuer_person_id, - (SELECT betreuerart_kurzbz - FROM lehre.tbl_projektbetreuer + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter') LIMIT 1) AS zweitbetreuer_person_id, + (SELECT betreuerart_kurzbz + FROM lehre.tbl_projektbetreuer WHERE projektarbeit_id=tbl_projektarbeit.projektarbeit_id - AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter') LIMIT 1) AS zweitbetreuer_betreuerart_kurzbz, - (SELECT tbl_betreuerart.beschreibung - FROM lehre.tbl_projektbetreuer JOIN lehre.tbl_betreuerart USING(betreuerart_kurzbz) + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter') LIMIT 1) AS zweitbetreuer_betreuerart_kurzbz, + (SELECT tbl_betreuerart.beschreibung + FROM lehre.tbl_projektbetreuer JOIN lehre.tbl_betreuerart USING(betreuerart_kurzbz) WHERE projektarbeit_id=tbl_projektarbeit.projektarbeit_id - AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') LIMIT 1) AS zweitbetreuer_betreuerart_beschreibung, - + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') LIMIT 1) AS zweitbetreuer_betreuerart_beschreibung, + tbl_betreuerart.betreuerart_kurzbz, person_id as bperson_id, projektarbeit_id, lehre.tbl_projekttyp.bezeichnung as projekttypbezeichnung, + lehre.tbl_projekttyp.projekttyp_kurzbz as projekttypkurzbz, lehre.tbl_lehreinheit.studiensemester_kurzbz, lehre.tbl_lehrveranstaltung.studiengang_kz, public.tbl_studiengang.kurzbzlang, - lehre.tbl_projektbetreuer.note as note, + lehre.tbl_projektarbeit.note as note, + lehre.tbl_note.bezeichnung as note_bezeichnung, public.tbl_mitarbeiter.mitarbeiter_uid, lehre.tbl_projektarbeit.titel as titel, lehre.tbl_projektarbeit.sprache as sprache, @@ -147,9 +147,8 @@ class Projektarbeit_model extends DB_Model lehre.tbl_projektarbeit.schlagwoerter as schlagwoerter, lehre.tbl_projektarbeit.schlagwoerter_en as schlagwoerter_en, lehre.tbl_projektarbeit.abstract as abstract, - lehre.tbl_projektarbeit.abstract_en as abstract_en, - (SELECT abgeschicktvon FROM extension.tbl_projektarbeitsbeurteilung WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id AND betreuer_person_id = tbl_projektbetreuer.person_id) AS babgeschickt, - (SELECT abgeschicktvon FROM extension.tbl_projektarbeitsbeurteilung WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter') LIMIT 1) AS zweitbetreuer_abgeschickt, + lehre.tbl_projektarbeit.abstract_en as abstract_en, + lehre.tbl_projektarbeit.insertamum as insertamum, (SELECT datum FROM campus.tbl_paabgabe WHERE paabgabetyp_kurzbz = 'end' AND abgabedatum IS NOT NULL AND projektarbeit_id = tbl_projektarbeit.projektarbeit_id LIMIT 1) AS abgegeben FROM lehre.tbl_projektarbeit @@ -158,15 +157,17 @@ class Projektarbeit_model extends DB_Model LEFT JOIN public.tbl_benutzer USING(person_id) LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz) LEFT JOIN lehre.tbl_betreuerart USING(betreuerart_kurzbz) - LEFT JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) - LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) - LEFT JOIN public.tbl_mitarbeiter ON(public.tbl_mitarbeiter.mitarbeiter_uid = public.tbl_benutzer.uid) - LEFT JOIN public.tbl_studiengang USING(studiengang_kz) - WHERE - tbl_projektarbeit.student_uid = ? AND + LEFT JOIN lehre.tbl_lehreinheit USING(lehreinheit_id) + LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id) + LEFT JOIN public.tbl_mitarbeiter ON(public.tbl_mitarbeiter.mitarbeiter_uid = public.tbl_benutzer.uid) + LEFT JOIN public.tbl_studiengang USING(studiengang_kz) + LEFT JOIN lehre.tbl_note ON(lehre.tbl_projektarbeit.note = lehre.tbl_note.note) + WHERE + tbl_projektarbeit.student_uid = ? AND mitarbeiter_uid IS NOT NULL AND (projekttyp_kurzbz='Bachelor' OR projekttyp_kurzbz='Diplom') - AND betreuerart_kurzbz IN ('Betreuer', 'Begutachter', 'Erstbegutachter', 'Senatsvorsitz')"; - + AND betreuerart_kurzbz IN ('Betreuer', 'Begutachter', 'Erstbegutachter', 'Senatsvorsitz')) as base + ORDER BY insertamum DESC"; + return $this->execReadOnlyQuery($betreuerQuery, array($studentUID)); } @@ -179,8 +180,12 @@ class Projektarbeit_model extends DB_Model campus.tbl_paabgabe.fixtermin, campus.tbl_paabgabe.kurzbz, campus.tbl_paabgabe.datum, + campus.tbl_paabgabe.note, + campus.tbl_paabgabe.upload_allowed, + campus.tbl_paabgabe.beurteilungsnotiz, campus.tbl_paabgabetyp.paabgabetyp_kurzbz, campus.tbl_paabgabetyp.bezeichnung, + campus.tbl_paabgabetyp.benotbar, campus.tbl_paabgabe.abgabedatum, campus.tbl_paabgabe.insertvon FROM campus.tbl_paabgabe JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz) @@ -190,16 +195,76 @@ class Projektarbeit_model extends DB_Model return $this->execReadOnlyQuery($qry, array($projektarbeit_id)); } + public function getProjektarbeitenAbgabetermine($projektarbeiten_ids) { + $qry ="SELECT campus.tbl_paabgabe.paabgabe_id, + campus.tbl_paabgabe.projektarbeit_id, + campus.tbl_paabgabe.fixtermin, + campus.tbl_paabgabe.kurzbz, + campus.tbl_paabgabe.datum, + campus.tbl_paabgabe.note, + campus.tbl_paabgabe.upload_allowed, + campus.tbl_paabgabe.beurteilungsnotiz, + campus.tbl_paabgabetyp.paabgabetyp_kurzbz, + campus.tbl_paabgabetyp.bezeichnung, + campus.tbl_paabgabe.abgabedatum, + campus.tbl_paabgabe.insertvon + FROM campus.tbl_paabgabe JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz) + WHERE campus.tbl_paabgabe.projektarbeit_id IN ? + ORDER BY campus.tbl_paabgabe.datum"; + + return $this->execReadOnlyQuery($qry, array($projektarbeiten_ids)); + } + public function getProjektbetreuerAnrede($bperson_id) { - $qry_betr="SELECT distinct trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')) as first, - public.tbl_mitarbeiter.mitarbeiter_uid, anrede - FROM public.tbl_person JOIN lehre.tbl_projektbetreuer ON(lehre.tbl_projektbetreuer.person_id=public.tbl_person.person_id) - JOIN public.tbl_benutzer ON(public.tbl_benutzer.person_id=public.tbl_person.person_id) - JOIN public.tbl_mitarbeiter ON(public.tbl_benutzer.uid=public.tbl_mitarbeiter.mitarbeiter_uid) - WHERE public.tbl_person.person_id= ?"; + $qry_betr="SELECT DISTINCT ON(public.tbl_person.person_id) trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')) as first, anrede + FROM public.tbl_person JOIN lehre.tbl_projektbetreuer ON(lehre.tbl_projektbetreuer.person_id=public.tbl_person.person_id) + WHERE public.tbl_person.person_id= ?"; return $this->execReadOnlyQuery($qry_betr, [$bperson_id]); + } + + public function getProjektbetreuerEmail($projektarbeit_id) { + $qry = "SELECT ( + SELECT kontakt + FROM public.tbl_kontakt + WHERE kontakttyp = 'email' + AND person_id = pers.person_id + ORDER BY + CASE WHEN zustellung THEN 0 ELSE 1 END, + insertamum DESC NULLS LAST + LIMIT 1 + ) AS private_email, mitarbeiter_uid as uid + FROM lehre.tbl_projektarbeit pa + JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) + JOIN public.tbl_person pers USING (person_id) + LEFT JOIN public.tbl_benutzer ben USING (person_id) + LEFT JOIN public.tbl_mitarbeiter ma ON ben.uid = ma.mitarbeiter_uid + WHERE (ben.aktiv OR ben.aktiv IS NULL) + AND projektarbeit_id = ?"; + return $this->execReadOnlyQuery($qry, [$projektarbeit_id]); + } + + public function getProjektbetreuerEmailByPersonID($person_id) { + $qry = "SELECT ( + SELECT kontakt + FROM public.tbl_kontakt + WHERE kontakttyp = 'email' + AND person_id = pers.person_id + ORDER BY + CASE WHEN zustellung THEN 0 ELSE 1 END, + insertamum DESC NULLS LAST + LIMIT 1 + ) AS private_email, mitarbeiter_uid as uid + FROM lehre.tbl_projektarbeit pa + JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) + JOIN public.tbl_person pers USING (person_id) + LEFT JOIN public.tbl_benutzer ben USING (person_id) + LEFT JOIN public.tbl_mitarbeiter ma ON ben.uid = ma.mitarbeiter_uid + WHERE (ben.aktiv OR ben.aktiv IS NULL) + AND person_id = ?"; + + return $this->execReadOnlyQuery($qry, [$person_id]); } public function getProjektarbeitBenutzer($uid) { @@ -234,9 +299,9 @@ class Projektarbeit_model extends DB_Model * FROM (SELECT tbl_person.vorname, tbl_person.nachname, tbl_studiengang.typ, tbl_studiengang.kurzbz, - tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung, tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id, - tbl_projektbetreuer.betreuerart_kurzbz, tbl_betreuerart.beschreibung AS betreuerart_beschreibung, - tbl_benutzer.uid, tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz + tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung, tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id, tbl_projektarbeit.note, + tbl_projektbetreuer.person_id as betreuer_person_id, tbl_projektbetreuer.betreuerart_kurzbz, tbl_betreuerart.beschreibung AS betreuerart_beschreibung, + tbl_benutzer.uid, tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz, public.tbl_student.student_uid FROM lehre.tbl_projektarbeit LEFT JOIN lehre.tbl_projektbetreuer using(projektarbeit_id) LEFT JOIN lehre.tbl_betreuerart using(betreuerart_kurzbz) @@ -273,7 +338,180 @@ class Projektarbeit_model extends DB_Model return $this->execReadOnlyQuery($qry, array($projektarbeit_id)); } - + + + public function getProjektarbeitenForStudiengang($studiengang_kz, $benotet) { + $new_qry = "SELECT DISTINCT ON(tmp.projektarbeit_id) *, campus.get_betreuer_details(tmp.zweitbetreuer_person_id) as zweitbetreuer_full_name, campus.get_betreuer_details(tmp.betreuer_person_id) as erstbetreuer_full_name + FROM( + SELECT + DISTINCT ON(tbl_projektarbeit.projektarbeit_id) + tbl_projektarbeit.projekttyp_kurzbz, + tbl_projektarbeit.titel, + tbl_projektarbeit.projektarbeit_id, + tbl_studiengang.typ, tbl_studiengang.kurzbz, + student_benutzer.uid as student_uid, + student_person.vorname as student_vorname, + student_person.nachname as student_nachname, + tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz, + betreuer_benutzer.uid as betreuer_benutzer_uid, + betreuer_person.titelpre as betreuer_titelpre, + betreuer_person.vorname as betreuer_vorname, + betreuer_person.nachname as betreuer_nachname, + betreuer_person.titelpost as betreuer_titelpost, + lehre.tbl_projektbetreuer.betreuerart_kurzbz as betreuerart, + lehre.tbl_projektbetreuer.person_id as betreuer_person_id, + lehre.tbl_projektarbeit.sprache as sprache, + lehre.tbl_projektarbeit.seitenanzahl as seitenanzahl, + lehre.tbl_projektarbeit.kontrollschlagwoerter as kontrollschlagwoerter, + lehre.tbl_projektarbeit.schlagwoerter as schlagwoerter, + lehre.tbl_projektarbeit.schlagwoerter_en as schlagwoerter_en, + lehre.tbl_projektarbeit.abstract as abstract, + lehre.tbl_projektarbeit.abstract_en as abstract_en, + lehre.tbl_projektarbeit.insertamum as insertamum, + lehre.tbl_projektarbeit.note as note, + ( + SELECT orgform_kurzbz + FROM tbl_prestudentstatus + WHERE prestudent_id = (SELECT prestudent_id + FROM tbl_student + WHERE student_uid = student_benutzer.uid + LIMIT 1) + ORDER BY datum DESC, insertamum DESC, ext_id DESC + LIMIT 1 + ) + as organisationsform, + ( + SELECT person_id + FROM lehre.tbl_projektbetreuer + WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') + LIMIT 1 + ) + AS zweitbetreuer_person_id, + ( + SELECT betreuerart_kurzbz + FROM lehre.tbl_projektbetreuer + WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') + LIMIT 1 + ) + AS zweitbetreuer_betreuerart_kurzbz, + ( + SELECT tbl_betreuerart.beschreibung + FROM lehre.tbl_projektbetreuer + JOIN lehre.tbl_betreuerart USING (betreuerart_kurzbz) + WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') + LIMIT 1 + ) + AS zweitbetreuer_betreuerart_beschreibung, + ( + SELECT trim(COALESCE(titelpre, '') || ' ' || COALESCE(vorname, '') || ' ' || COALESCE(nachname, '') || ' ' || + COALESCE(titelpost, '')) + FROM public.tbl_person + JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid) + WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') + LIMIT 1 + ) + as zweitbetreuer_full_name, + ( + SELECT titelpre + FROM public.tbl_person + JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid) + WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') + LIMIT 1 + ) + as zweitbetreuer_titelpre, + ( + SELECT vorname + FROM public.tbl_person + JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid) + WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') + LIMIT 1 + ) + as zweitbetreuer_vorname, + ( + SELECT nachname + FROM public.tbl_person + JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid) + WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') + LIMIT 1 + ) + as zweitbetreuer_nachname, + ( + SELECT titelpost + FROM public.tbl_person + JOIN lehre.tbl_projektbetreuer ON (lehre.tbl_projektbetreuer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_benutzer ON (public.tbl_benutzer.person_id = public.tbl_person.person_id) + LEFT JOIN public.tbl_mitarbeiter ON (public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid) + WHERE projektarbeit_id = tbl_projektarbeit.projektarbeit_id + AND betreuerart_kurzbz IN ('Zweitbetreuer', 'Zweitbegutachter', 'Senatsmitglied') + LIMIT 1 + ) + as zweitbetreuer_titelpost, + ( + SELECT + COALESCE(tbl_studienplan.orgform_kurzbz, + tbl_prestudentstatus.orgform_kurzbz, tbl_studiengang.orgform_kurzbz) as + orgform + FROM + public.tbl_prestudent + JOIN public.tbl_prestudentstatus USING(prestudent_id) + JOIN public.tbl_studiensemester USING(studiensemester_kurzbz) + JOIN public.tbl_studiengang USING(studiengang_kz) + LEFT JOIN lehre.tbl_studienplan USING(studienplan_id) + WHERE + prestudent_id=tbl_student.prestudent_id + ORDER BY tbl_prestudentstatus.datum DESC LIMIT 1 + ) as orgform, + (SELECT status_kurzbz FROM public.tbl_prestudentstatus + WHERE prestudent_id=tbl_student.prestudent_id + ORDER BY datum DESC, insertamum DESC, ext_id DESC LIMIT 1) as studienstatus + FROM lehre.tbl_projektarbeit + LEFT JOIN public.tbl_benutzer student_benutzer ON (student_benutzer.uid = lehre.tbl_projektarbeit.student_uid) + LEFT JOIN public.tbl_person student_person ON (student_benutzer.person_id = student_person.person_id) + LEFT JOIN public.tbl_student on(student_benutzer.uid = public.tbl_student.student_uid) + LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id) + LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id) + LEFT JOIN public.tbl_studiengang ON (public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz) + LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz) + LEFT JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) + LEFT JOIN public.tbl_person betreuer_person ON (betreuer_person.person_id = lehre.tbl_projektbetreuer.person_id) + LEFT JOIN public.tbl_benutzer betreuer_benutzer ON (betreuer_person.person_id = betreuer_benutzer.person_id) + WHERE (projekttyp_kurzbz = 'Bachelor' OR projekttyp_kurzbz = 'Diplom') + AND student_benutzer.aktiv AND ( + lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Erstbegutachter' + OR lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Begutachter' + OR lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Betreuer' + OR lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Erstbetreuer' + OR lehre.tbl_projektbetreuer.betreuerart_kurzbz = 'Senatsvorsitz' + ) + AND public.tbl_studiengang.studiengang_kz = ?"; + + if($benotet == 0) { + $new_qry .= " AND lehre.tbl_projektarbeit.note IS NULL "; + } else if ($benotet == 1) { + $new_qry .= " AND lehre.tbl_projektarbeit.note IS NOT NULL "; + } + + $new_qry .= " ORDER BY tbl_projektarbeit.projektarbeit_id DESC, student_person.nachname ASC + ) as tmp"; + + return $this->execReadOnlyQuery($new_qry, array($studiengang_kz)); + } + /** * * @param @@ -299,4 +537,17 @@ class Projektarbeit_model extends DB_Model return false; } + + public function getProjektarbeitByPaabgabeID($paabgabe_id) { + $qry = "SELECT + projektarbeit_id + FROM + campus.tbl_paabgabe + JOIN lehre.tbl_projektarbeit USING(projektarbeit_id) + WHERE + campus.tbl_paabgabe.paabgabe_id = ?; + "; + + return $this->execReadOnlyQuery($qry, [$paabgabe_id]); + } } diff --git a/application/models/education/Projektbetreuer_model.php b/application/models/education/Projektbetreuer_model.php index 02368ae21..47e0239d6 100644 --- a/application/models/education/Projektbetreuer_model.php +++ b/application/models/education/Projektbetreuer_model.php @@ -232,4 +232,41 @@ class Projektbetreuer_model extends DB_Model return $this->execQuery($qry, array($projektarbeit_id, $betreuer_person_id)); } + + /** + * Gets all Betreuer of a Projektarbeit. + * Returns one row for each person. + * @param int $projektarbeit_id + * @return array success with number of Betreuer or error + */ + public function getAllBetreuerOfProjektarbeit($projektarbeit_id) + { + $qry = "SELECT DISTINCT ON (pers.person_id) pers.person_id, betreuerart_kurzbz, vorname, nachname, + trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')) as voller_name, + anrede, titelpre, titelpost, gebdatum, geschlecht, pa.projekttyp_kurzbz, + ben.uid, ben.alias, ma.personalnummer, mitarbeiter_uid, student_uid, + ( + SELECT kontakt + FROM public.tbl_kontakt + WHERE kontakttyp = 'email' + AND person_id = pers.person_id + ORDER BY + CASE WHEN zustellung THEN 0 ELSE 1 END, + insertamum DESC NULLS LAST + LIMIT 1 + ) AS private_email + FROM lehre.tbl_projektarbeit pa + JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id) + JOIN public.tbl_person pers USING (person_id) + LEFT JOIN public.tbl_benutzer ben USING (person_id) + LEFT JOIN public.tbl_mitarbeiter ma ON ben.uid = ma.mitarbeiter_uid + WHERE (ben.aktiv OR ben.aktiv IS NULL) + AND projektarbeit_id = ? + ORDER BY pers.person_id, CASE WHEN ma.mitarbeiter_uid IS NULL THEN 1 ELSE 0 END, /*Mitarbeiter account first*/ + CASE WHEN ben.uid IS NULL THEN 1 ELSE 0 END, /*user with account first*/ + ben.insertamum"; + + return $this->execQuery($qry, array($projektarbeit_id)); + } + } diff --git a/application/models/organisation/Organisationseinheit_model.php b/application/models/organisation/Organisationseinheit_model.php index db56c1930..9f64580a9 100644 --- a/application/models/organisation/Organisationseinheit_model.php +++ b/application/models/organisation/Organisationseinheit_model.php @@ -243,4 +243,20 @@ class Organisationseinheit_model extends DB_Model return $this->execReadOnlyQuery($qry, array($oe_kurzbz)); } + + public function getAssistenzForOE($oe_kurzbz) { + $qry = " + SELECT person_id, uid, benutzerfunktion_id, funktion_kurzbz, oe_kurzbz, alias, + anrede, trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')) as first + FROM tbl_benutzerfunktion + JOIN public.tbl_benutzer USING(uid) + JOIN public.tbl_person USING(person_id) + WHERE funktion_kurzbz = 'ass' + AND oe_kurzbz = ? + AND (datum_bis IS NULL OR NOW() <= datum_bis) + AND public.tbl_benutzer.aktiv = true + "; + + return $this->execReadOnlyQuery($qry, array($oe_kurzbz)); + } } diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index 02f972690..131e1deb5 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -657,37 +657,7 @@ class Studiengang_model extends DB_Model $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); $this->load->model('person/Person_model', 'PersonModel'); $this->load->model('crm/Student_model', 'StudentModel'); - - $addEmailProperty= function(&$benutzerfunktionen){ - if(count($benutzerfunktionen) && defined('DOMAIN')) - { - $benutzerfunktionen = array_map(function($benutzer) - { - $benutzer->email = $benutzer->alias."@".DOMAIN; - return $benutzer; - },$benutzerfunktionen) ; - } - - }; - $addFotoProperty= function(&$collection){ - $collection = array_map(function($item){ - $person_id = $this->PersonModel->getByUid($item->uid); - if(isError($person_id)) - return error($person_id); - $person_id = current(getData($person_id))->person_id; - $this->PersonModel->addSelect('foto'); - $foto = $this->PersonModel->loadWhere(array('person_id'=>$person_id)); - if(isError($foto)) - return error($foto); - $foto = current(getData($foto))->foto; - $item->foto = $foto; - return $item; - },$collection); - }; - - $this->load->model('crm/Student_model', 'StudentModel'); - $student = $this->StudentModel->loadWhere(['student_uid' => getAuthUID()]); if (isError($student)) return error($student); @@ -712,7 +682,7 @@ class Studiengang_model extends DB_Model $stg_ltg = array_values(array_filter($stg_ltg, function($stg_leitung){ return $stg_leitung->aktiv; })); - $addFotoProperty($stg_ltg); + $this->addFotoProperty($stg_ltg); $gf_ltg = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('gLtg', $stg_obj->oe_kurzbz); if (isError($gf_ltg)) @@ -721,8 +691,8 @@ class Studiengang_model extends DB_Model $gf_ltg = array_values(array_filter($gf_ltg, function($gf_leitung){ return $gf_leitung->aktiv; })); - $addEmailProperty($gf_ltg); - $addFotoProperty($gf_ltg); + $this->addEmailProperty($gf_ltg); + $this->addFotoProperty($gf_ltg); $stv_ltg = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('stvLtg', $stg_obj->oe_kurzbz); if (isError($stv_ltg)) @@ -731,8 +701,8 @@ class Studiengang_model extends DB_Model $stv_ltg = array_values(array_filter($stv_ltg, function($stv_leitung){ return $stv_leitung->aktiv; })); - $addEmailProperty($stv_ltg); - $addFotoProperty($stv_ltg); + $this->addEmailProperty($stv_ltg); + $this->addFotoProperty($stv_ltg); $ass = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('ass', $stg_obj->oe_kurzbz); if (isError($ass)) @@ -741,8 +711,8 @@ class Studiengang_model extends DB_Model $ass = array_values(array_filter($ass, function($assistenz){ return $assistenz->aktiv; })); - $addEmailProperty($ass); - $addFotoProperty($ass); + $this->addEmailProperty($ass); + $this->addFotoProperty($ass); $hochschulvertr = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('hsv'); if (isError($hochschulvertr)) @@ -751,7 +721,7 @@ class Studiengang_model extends DB_Model $hochschulvertr = array_values(array_filter($hochschulvertr, function($hochschul_vertreter){ return $hochschul_vertreter->aktiv; })); - $addEmailProperty($hochschulvertr); + $this->addEmailProperty($hochschulvertr); $stdv = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('stdv', $stg_obj->oe_kurzbz); @@ -761,7 +731,7 @@ class Studiengang_model extends DB_Model $stdv = array_values(array_filter($stdv, function($std_vertreter){ return $std_vertreter->aktiv; })); - $addEmailProperty($stdv); + $this->addEmailProperty($stdv); $jahrgangsvertr = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('jgv', $stg_obj->oe_kurzbz, $semester); @@ -771,7 +741,7 @@ class Studiengang_model extends DB_Model $jahrgangsvertr = array_values(array_filter($jahrgangsvertr, function($jahrgang_vertreter){ return $jahrgang_vertreter->aktiv; })); - $addEmailProperty($jahrgangsvertr); + $this->addEmailProperty($jahrgangsvertr); $result_object = new stdClass(); @@ -801,4 +771,141 @@ class Studiengang_model extends DB_Model return $this->execReadOnlyQuery($qry, array($studiengang_kz, $orgform_kurzbz, $studiensemester_kurzbz)); } + + /** + * Get active Studiengänge with Kuerzel by given Studiengang-Kennzahlen. + * Helpful to easily get Studiengänge the user is entitled for. + * + * @param $studiengang_kz_arr + * @param $studiensemester_kurzbz + * @return array|stdClass|null Returns one row per Studiengang. Not considering the Orgforms. + */ + public function getByStgs($studiengang_kz_arr, $studiensemester_kurzbz) + { + if (is_numeric($studiengang_kz_arr)) + { + $studiengang_kz_arr = [$studiengang_kz_arr]; + } + + $qry = ' + SELECT + DISTINCT stg.*, UPPER(typ::varchar(1) || kurzbz) AS kuerzel + FROM + public.tbl_studiengang stg + JOIN lehre.tbl_studienordnung sto USING(studiengang_kz) + JOIN lehre.tbl_studienplan stpl USING(studienordnung_id) + JOIN lehre.tbl_studienplan_semester stplsem USING(studienplan_id) + WHERE + stg.studiengang_kz IN ? + AND stplsem.studiensemester_kurzbz = ? + ORDER BY + stg.kurzbzlang + '; + + return $this->execQuery($qry, [$studiengang_kz_arr, $studiensemester_kurzbz]); + } + + /** + * Get OrgForms of given Studiengang and Studiensemester. + * + * @param $studiengang_kz + * @param $studiensemester_kurzbz + * @return array|stdClass|null + */ + public function getOrgformsByStg($studiengang_kz, $studiensemester_kurzbz) + { + $qry = ' + SELECT + stpl.orgform_kurzbz + FROM + public.tbl_studiengang stg + JOIN lehre.tbl_studienordnung sto USING(studiengang_kz) + JOIN lehre.tbl_studienplan stpl USING(studienordnung_id) + JOIN lehre.tbl_studienplan_semester stplsem USING(studienplan_id) + WHERE + stg.studiengang_kz = ? + AND stg.aktiv = TRUE + AND stplsem.studiensemester_kurzbz = ? + GROUP BY + stpl.orgform_kurzbz + ORDER BY + CASE stpl.orgform_kurzbz + WHEN \'VZ\' THEN 1 + WHEN \'BB\' THEN 2 + WHEN \'DUA\' THEN 3 + ELSE 4 + END, + stpl.orgform_kurzbz; + '; + + return $this->execQuery($qry, [$studiengang_kz, $studiensemester_kurzbz]); + } + + public function getStudiengaengeFiltered($allowed_stg) { + $query ="SELECT DISTINCT + public.tbl_studiengang.studiengang_kz, + public.tbl_studiengang.bezeichnung, + public.tbl_studiengang.kurzbzlang, + public.tbl_studiengang.orgform_kurzbz + FROM public.tbl_studiengang JOIN lehre.tbl_studienordnung USING(studiengang_kz) + JOIN lehre.tbl_studienplan USING(studienordnung_id) + JOIN lehre.tbl_studienplan_semester USING(studienplan_id) + WHERE public.tbl_studiengang.aktiv = true + + AND public.tbl_studiengang.studiengang_kz IN ? + ORDER BY public.tbl_studiengang.kurzbzlang"; + + return $this->execReadOnlyQuery($query, [$allowed_stg]); + } + + public function getAssistenzForStudiengangKZ($stg_kz) { + $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); + + $stg_obj = $this->load($stg_kz); + if(isError($stg_obj)) + return error($stg_obj); + if(getData($stg_obj)) + { + $stg_obj = current(getData($stg_obj)); + } + + $ass = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('ass', $stg_obj->oe_kurzbz); + if (isError($ass)) + return $ass; + $ass = getData($ass) ?: []; + $ass = array_values(array_filter($ass, function($assistenz){ + return $assistenz->aktiv; + })); + + $this->addEmailProperty($ass); + + return success($ass); + } + + private function addEmailProperty(&$benutzerfunktionen) { + if(count($benutzerfunktionen) && defined('DOMAIN')) + { + $benutzerfunktionen = array_map(function($benutzer) + { + $benutzer->email = $benutzer->alias."@".DOMAIN; + return $benutzer; + },$benutzerfunktionen) ; + } + } + + private function addFotoProperty (&$collection) { + $collection = array_map(function($item){ + $person_id = $this->PersonModel->getByUid($item->uid); + if(isError($person_id)) + return error($person_id); + $person_id = current(getData($person_id))->person_id; + $this->PersonModel->addSelect('foto'); + $foto = $this->PersonModel->loadWhere(array('person_id'=>$person_id)); + if(isError($foto)) + return error($foto); + $foto = current(getData($foto))->foto; + $item->foto = $foto; + return $item; + },$collection); + } } diff --git a/application/models/person/Person_model.php b/application/models/person/Person_model.php index 233cfc751..e72b24de4 100644 --- a/application/models/person/Person_model.php +++ b/application/models/person/Person_model.php @@ -420,4 +420,17 @@ class Person_model extends DB_Model return success($result); } } + + public function loadAllStudentUIDSForPersonID($person_id) { + $qry = "SELECT + CONCAT(tp.vorname, ' ', tp.nachname) AS name, + ARRAY_AGG(DISTINCT b.uid ORDER BY b.uid) AS uids + FROM public.tbl_student s + JOIN public.tbl_benutzer b ON s.student_uid = b.uid + JOIN public.tbl_person tp ON b.person_id = tp.person_id + GROUP BY tp.vorname, tp.nachname, b.aktiv, b.person_id + HAVING b.person_id = ? AND b.aktiv IS TRUE;"; + + return $this->execReadOnlyQuery($qry, [$person_id]); + } } diff --git a/application/models/person/Profil_update_model.php b/application/models/person/Profil_update_model.php index 31005c4b7..039810537 100644 --- a/application/models/person/Profil_update_model.php +++ b/application/models/person/Profil_update_model.php @@ -135,7 +135,8 @@ class Profil_update_model extends DB_Model attachment_id, UPPER(public.tbl_studiengang.typ || public.tbl_studiengang.kurzbz) AS studiengang, COALESCE(of.orgform_kurzbz, public.tbl_studiengang.orgform_kurzbz) AS orgform, - NULL as oezuordnung + NULL as oezuordnung, + tbl_student.semester FROM public.tbl_profil_update JOIN public.tbl_profil_update_status ON public.tbl_profil_update_status.status_kurzbz = public.tbl_profil_update.status JOIN public.tbl_student ON public.tbl_student.student_uid=public.tbl_profil_update.uid diff --git a/application/models/ressource/Mitarbeiter_model.php b/application/models/ressource/Mitarbeiter_model.php index a650643f1..d8bbd7d63 100644 --- a/application/models/ressource/Mitarbeiter_model.php +++ b/application/models/ressource/Mitarbeiter_model.php @@ -209,7 +209,7 @@ class Mitarbeiter_model extends DB_Model { $qry = " SELECT - titelpre, vorname, nachname, titelpost, foto, foto_sperre, person_id, alias, telefonklappe + titelpre, vorname, nachname, titelpost, foto, foto_sperre, person_id, alias, telefonklappe, personalnummer, mitarbeiter_uid FROM public.tbl_person JOIN public.tbl_benutzer b USING(person_id) @@ -363,14 +363,14 @@ class Mitarbeiter_model extends DB_Model $returnwert .= ", ma.mitarbeiter_uid, CONCAT(p.nachname, ' ', p.vorname, ' (', ma.mitarbeiter_uid , ')') as mitarbeiter"; $qry = " - SELECT " . $returnwert . " - FROM + SELECT " . $returnwert . " + FROM public.tbl_mitarbeiter ma - JOIN + JOIN public.tbl_benutzer b on (ma.mitarbeiter_uid = b.uid) - JOIN + JOIN public.tbl_person p on (p.person_id = b.person_id) - WHERE + WHERE lower (p.nachname) LIKE '%". $this->db->escape_like_str($filter)."%' OR lower (p.vorname) LIKE '%". $this->db->escape_like_str($filter)."%' @@ -393,14 +393,14 @@ class Mitarbeiter_model extends DB_Model public function getMitarbeiterFromLV($lehrveranstaltung_id) { $qry = "SELECT DISTINCT - lehrveranstaltung_id, uid, vorname, wahlname, vornamen, nachname, titelpre, titelpost, kurzbz, mitarbeiter_uid - FROM + lehrveranstaltung_id, uid, vorname, wahlname, vornamen, nachname, titelpre, titelpost, kurzbz, mitarbeiter_uid + FROM lehre.tbl_lehreinheitmitarbeiter, campus.vw_mitarbeiter, lehre.tbl_lehreinheit - WHERE + WHERE lehrveranstaltung_id= ? - AND - mitarbeiter_uid=uid - AND + AND + mitarbeiter_uid=uid + AND tbl_lehreinheitmitarbeiter.lehreinheit_id=tbl_lehreinheit.lehreinheit_id;"; $parametersArray = array($lehrveranstaltung_id); diff --git a/application/models/ressource/Stundenplan_model.php b/application/models/ressource/Stundenplan_model.php index 389be582d..d0a97ed9d 100644 --- a/application/models/ressource/Stundenplan_model.php +++ b/application/models/ressource/Stundenplan_model.php @@ -470,12 +470,12 @@ class Stundenplan_model extends DB_Model } foreach($studentlehrverbaende[$sem_date] as $key=>$lehrverband) { - $query .= "((sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND sp.gruppe = ".$this->escape($lehrverband->gruppe)." AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")"; + $query .= "(((sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND sp.gruppe = ".$this->escape($lehrverband->gruppe)." AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")"; // Eintraege fuer den ganzen Verband $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND (sp.gruppe is null OR sp.gruppe='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")"; // Eintraege fuer das ganze Semester $query .= "OR (sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND (sp.verband is null OR sp.verband='') AND sp.datum BETWEEN ".$this->escape($sem_date_range->start) - ." AND ".$this->escape($sem_date_range->ende).")". $stringGroupLv. ")"; + ." AND ".$this->escape($sem_date_range->ende).")) AND gruppe_kurzbz is null)"; $query .="OR"; } @@ -535,4 +535,53 @@ class Stundenplan_model extends DB_Model return $this->execQuery($query, [$uid, $uid]); } + + /** + * Get Stundenplantermine for given Lehreinheit. + * + * @param $lehreinheit_id + * @return array|stdClass|null + */ + public function getTermineByLe($lehreinheit_id) + { + $qry = ' + SELECT DISTINCT + datum + FROM + lehre.vw_stundenplan + WHERE + lehreinheit_id = ? + ORDER BY + datum ASC + '; + + return $this->execQuery($qry, [$lehreinheit_id]); + } + + /** + * Get Stundenplantermine for given Lehrveranstaltung of given Studiensemester. + * + * @param $lehrveranstaltung_id + * @param $studiensemester_kurzbz + * @return array|stdClass|null + */ + public function getTermineByLv($lehrveranstaltung_id, $studiensemester_kurzbz) + { + $qry = ' + SELECT DISTINCT + datum + FROM + lehre.vw_stundenplan + WHERE + lehreinheit_id IN ( + SELECT lehreinheit_id + FROM lehre.tbl_lehreinheit + WHERE lehrveranstaltung_id = ? + AND studiensemester_kurzbz = ? + ) + ORDER BY datum ASC + '; + + return $this->execQuery($qry, [$lehrveranstaltung_id, $studiensemester_kurzbz]); + } } diff --git a/application/models/system/Message_model.php b/application/models/system/Message_model.php index e0a185f9b..3e59d7250 100644 --- a/application/models/system/Message_model.php +++ b/application/models/system/Message_model.php @@ -242,74 +242,91 @@ class Message_model extends DB_Model */ public function getMessagesForTable($person_id, $offset, $limit) { - $sql_base = " - SELECT + $sql = <<execQuery($sql, $parametersArray); - - if (isError($count)) - return $count; - - $count = ceil(current(getData($count))->count/$limit); - $sql = " - SELECT * FROM ( - " . $sql_base . " - ) a - ORDER BY insertamum DESC - LIMIT ? - OFFSET ? - "; + (COALESCE(ps.titelpre,'') || ' ' || COALESCE(ps.vorname,'') || ' ' || COALESCE(ps.nachname,'') || ' ' || COALESCE(ps.titelpost,'')) as sender, + (COALESCE(pr.titelpre,'') || ' ' || COALESCE(pr.vorname,'') || ' ' || COALESCE(pr.nachname,'') || ' ' || COALESCE(pr.titelpost,'')) as recipient, + fm.sender_id, + fm.recipient_id, + ms.status, + ms.insertamum as statusdatum + from + filtered_messages fm + join + public.tbl_msg_message m on fm.message_id = m.message_id + join + lastmsgstatus ms on fm.message_id = ms.message_id and fm.recipient_id = ms.person_id + left join + public.tbl_person ps on ps.person_id = fm.sender_id + left join + public.tbl_person pr on pr.person_id = fm.recipient_id + order by + m.insertamum DESC + limit ? + offset ?; +EOSQL; $parametersArray = array($person_id, $person_id, $limit, $offset); + $count = 0; $data = $this->execQuery($sql, $parametersArray); if (isError($data)) return $data; $data = getData($data); + if($data) + { + $count = ceil($data[0]->total_msgs / $limit); + } return success(['data' => $data, 'count' => $count]); } diff --git a/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php b/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php index c50627697..2669105a1 100644 --- a/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php +++ b/application/models/vertragsbestandteil/Gehaltsbestandteil_model.php @@ -286,7 +286,13 @@ EOSQL; foreach( $rows as $row ) { $tmpgb = new Gehaltsbestandteil(); $tmpgb->hydrateByStdClass($row, true); - + + if ($row->betrag_valorisiert != null && $row->valorisierungsdatum != null + && $row->valorisierungsdatum == $row->von) { + // neuer Gehaltsbestandteil mit Valorisierungsdatum aber auch valorisiert + $tmpgb->setGrundbetrag($row->betrag_valorisiert); + } + // prevent duplication (caused by the join with historic values) if (!isset($lastRecords[(string)$row->gehaltsbestandteil_id])) { $gehaltsbestandteile[] = $tmpgb; diff --git a/application/views/Cis/Abgabetool.php b/application/views/Cis/Abgabetool.php new file mode 100644 index 000000000..86e8721f2 --- /dev/null +++ b/application/views/Cis/Abgabetool.php @@ -0,0 +1,47 @@ + 'Cis4', + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'tabulator5' => true, // TODO: upgrade to 6 when available + 'vue3' => true, + 'primevue3' => true, + 'skipID' => '#fhccontent', + 'vuedatepicker11' => true, + 'customCSSs' => array( + 'public/css/components/verticalsplit.css', + 'public/css/components/FilterComponent.css', + 'public/css/components/FormUnderline.css', + 'public/css/theme/default.css', + 'public/css/components/abgabetool/abgabe.css' + ), + 'customJSs' => array( + 'vendor/npm-asset/primevue/accordion/accordion.min.js', + 'vendor/npm-asset/primevue/accordiontab/accordiontab.min.js', + 'vendor/npm-asset/primevue/checkbox/checkbox.min.js', + 'vendor/npm-asset/primevue/inputnumber/inputnumber.min.js', + 'vendor/npm-asset/primevue/speeddial/speeddial.min.js', + 'vendor/npm-asset/primevue/textarea/textarea.min.js', + 'vendor/npm-asset/primevue/timeline/timeline.min.js', + 'vendor/npm-asset/primevue/inplace/inplace.min.js', + 'vendor/npm-asset/primevue/message/message.min.js', + 'vendor/npm-asset/primevue/tieredmenu/tieredmenu.js', + 'vendor/moment/luxonjs/luxon.min.js' + ), + 'customJSModules' => array( + 'public/js/apps/Abgabetool/Abgabetool.js', + ), + +); + +$this->load->view('templates/FHC-Header', $includesArray); +?> +
+ uid= + student_uid_prop="" + stg_kz_prop="" + > +
+load->view('templates/FHC-Footer', $includesArray); ?> diff --git a/application/views/Cis/LvInfo.php b/application/views/Cis/LvInfo.php deleted file mode 100644 index 49a7b7a85..000000000 --- a/application/views/Cis/LvInfo.php +++ /dev/null @@ -1,15 +0,0 @@ - 'LvInfo', - 'customJSModules' => ['public/js/apps/Cis/LvInfo.js'] -); - -$this->load->view('templates/CISVUE-Header', $includesArray); -?> - -
- - -
- -load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/Cis/Profil.php b/application/views/Cis/Profil.php deleted file mode 100644 index f66ebf8a9..000000000 --- a/application/views/Cis/Profil.php +++ /dev/null @@ -1,18 +0,0 @@ - 'Profil', - 'customJSModules' => ['public/js/apps/Cis/Profil.js'], - 'tabulator5' => true, - 'primevue3' => true, - 'customCSSs' => ['public/css/components/calendar.css', 'public/css/components/FilterComponent.css','public/css/components/Profil.css','public/css/components/FormUnderline.css'], - -); - -$this->load->view('templates/CISVUE-Header', $includesArray); -?> - -
- -
- -load->view('templates/CISVUE-Footer', $includesArray); ?> diff --git a/application/views/CisRouterView/CisRouterView.php b/application/views/CisRouterView/CisRouterView.php index ab22fbb81..6ff428362 100644 --- a/application/views/CisRouterView/CisRouterView.php +++ b/application/views/CisRouterView/CisRouterView.php @@ -21,19 +21,25 @@ $includesArray = array( 'public/css/components/FilterComponent.css', 'public/css/components/Profil.css', 'public/css/components/FormUnderline.css', + 'public/css/components/abgabetool/abgabe.css', 'public/css/Cis4/Cms.css', 'public/css/Cis4/Studium.css', ), 'customJSs' => array( 'vendor/npm-asset/primevue/accordion/accordion.min.js', 'vendor/npm-asset/primevue/accordiontab/accordiontab.min.js', - 'vendor/npm-asset/primevue/inputnumber/inputnumber.min.js', - 'vendor/npm-asset/primevue/textarea/textarea.min.js', 'vendor/npm-asset/primevue/checkbox/checkbox.min.js', + 'vendor/npm-asset/primevue/inputnumber/inputnumber.min.js', + 'vendor/npm-asset/primevue/speeddial/speeddial.min.js', + 'vendor/npm-asset/primevue/textarea/textarea.min.js', + 'vendor/npm-asset/primevue/timeline/timeline.min.js', + 'vendor/npm-asset/primevue/inplace/inplace.min.js', + 'vendor/npm-asset/primevue/message/message.min.js', + 'vendor/npm-asset/primevue/tieredmenu/tieredmenu.js', 'vendor/moment/luxonjs/luxon.min.js' ), 'customJSModules' => array( - 'public/js/apps/Dashboard/Fhc.js' + 'public/js/apps/Dashboard/Fhc.js', ), ); diff --git a/application/views/Studentenverwaltung.php b/application/views/Studentenverwaltung.php index 1cd28d735..8dd2dd93d 100644 --- a/application/views/Studentenverwaltung.php +++ b/application/views/Studentenverwaltung.php @@ -7,19 +7,21 @@ 'vue3' => true, 'primevue3' => true, #'filtercomponent' => true, - 'tabulator5' => true, + 'tabulator6' => true, 'tinymce5' => true, 'phrases' => array( 'global', 'ui', 'notiz', ), + 'tags' => true, 'customCSSs' => [ #datepicker fuer component functions 'public/css/components/vue-datepicker.css', 'public/css/components/primevue.css', 'public/css/Studentenverwaltung.css', - 'public/css/components/function.css' + 'public/css/components/function.css', + 'public/css/components/Detailheader.css' ], 'customJSs' => [ 'vendor/vuejs/vuedatepicker_js/vue-datepicker.iife.js', @@ -45,6 +47,8 @@ $configArray = [ 'showAufnahmegruppen' => !defined('FAS_REIHUNGSTEST_AUFNAHMEGRUPPEN') ? false : FAS_REIHUNGSTEST_AUFNAHMEGRUPPEN, 'allowUebernahmePunkte' => !defined('FAS_REIHUNGSTEST_PUNKTEUEBERNAHME') ? true : FAS_REIHUNGSTEST_PUNKTEUEBERNAHME, 'useReihungstestPunkte' => !defined('FAS_REIHUNGSTEST_PUNKTE') ? true : FAS_REIHUNGSTEST_PUNKTE, + 'hasExcludedAreas' => defined('FAS_REIHUNGSTEST_EXCLUDE_GEBIETE') && !empty(FAS_REIHUNGSTEST_EXCLUDE_GEBIETE), + 'stvTagsEnabled' => defined('STV_TAGS_ENABLED') ? STV_TAGS_ENABLED : false, ]; ?> diff --git a/application/views/Vertragsverwaltung.php b/application/views/Vertragsverwaltung.php new file mode 100644 index 000000000..8fa6dff27 --- /dev/null +++ b/application/views/Vertragsverwaltung.php @@ -0,0 +1,50 @@ + 'Vertragsverwaltung', + 'axios027' => true, + 'bootstrap5' => true, + 'fontawesome6' => true, + 'vue3' => true, + 'primevue3' => true, + 'filtercomponent' => true, + 'navigationcomponent' => true, + 'tabulator6' => true, + 'tinymce5' => true, + 'phrases' => array( + 'global', + 'ui', + ), + 'customCSSs' => [ + 'public/css/components/vue-datepicker.css', + 'public/css/components/primevue.css', + 'public/css/Vertragsverwaltung.css', + 'public/css/components/Detailheader.css' + ], + 'customJSs' => [ + #'vendor/npm-asset/primevue/tree/tree.min.js', + #'vendor/npm-asset/primevue/toast/toast.min.js' + ], + 'customJSModules' => [ + 'public/js/apps/Vertragsverwaltung.js' + ] +); + +$this->load->view('templates/FHC-Header', $includesArray); +?> + + !defined('DOMAIN') ? 'notDefined' : DOMAIN, +]; +?> + +
+ + +
+ +load->view('templates/FHC-Footer', $includesArray); ?> + diff --git a/application/views/templates/CISVUE-Header.php b/application/views/templates/CISVUE-Header.php index 358fc75c9..804a43821 100644 --- a/application/views/templates/CISVUE-Header.php +++ b/application/views/templates/CISVUE-Header.php @@ -36,4 +36,4 @@ $this->load->view('templates/FHC-Header', $includesArray); > -
\ No newline at end of file +
\ No newline at end of file diff --git a/application/views/templates/FHC-Footer.php b/application/views/templates/FHC-Footer.php index c816ebf2e..d2eb229f1 100644 --- a/application/views/templates/FHC-Footer.php +++ b/application/views/templates/FHC-Footer.php @@ -17,6 +17,7 @@ $use_vuejs_dev_version = $this->config->item('use_vuejs_dev_version'); // By default set the parameters to null + $customCSSs = isset($customCSSs) ? $customCSSs : null; $customJSs = isset($customJSs) ? $customJSs : null; $customJSModules = isset($customJSModules) ? $customJSModules : null; @@ -191,12 +192,13 @@ // NOTE: keep it as the last but one if ($addons === true) generateAddonsJSsInclude($calledPath.'/'.$calledMethod); - - + $extapphelper = ExtendableAppsHelper::getInstance(); + $extapphelper->init($customCSSs, $customJSs, $customJSModules); + // Eventually required JS // NOTE: keep it as the latest - generateJSsInclude($customJSs); - generateJSModulesInclude($customJSModules); + generateJSsInclude($extapphelper->getCustomJSs()); + generateJSModulesInclude($extapphelper->getCustomJSModules()); ?> diff --git a/application/views/templates/FHC-Header.php b/application/views/templates/FHC-Header.php index f7b5491a1..7b53cbf5d 100644 --- a/application/views/templates/FHC-Header.php +++ b/application/views/templates/FHC-Header.php @@ -9,6 +9,8 @@ $title = isset($title) ? $title : null; $refresh = isset($refresh) ? $refresh : null; $customCSSs = isset($customCSSs) ? $customCSSs : null; + $customJSs = isset($customJSs) ? $customJSs : null; + $customJSModules = isset($customJSModules) ? $customJSModules : null; $skipID = isset($skipID) ? $skipID : null; ?> @@ -132,8 +134,11 @@ //Tags if ($tags === true) generateCSSsInclude('public/css/tags.css'); + $extapphelper = ExtendableAppsHelper::getInstance(); + $extapphelper->init($customCSSs, $customJSs, $customJSModules); + // Eventually required CSS - generateCSSsInclude($customCSSs); // Eventually required CSS + generateCSSsInclude($extapphelper->getCustomCSSs()); // Eventually required CSS ?> diff --git a/cis/private/lehre/notenliste.xls.php b/cis/private/lehre/notenliste.xls.php index 6c8db5246..25f353c12 100644 --- a/cis/private/lehre/notenliste.xls.php +++ b/cis/private/lehre/notenliste.xls.php @@ -264,7 +264,7 @@ else tbl_bisio.bisio_id, tbl_bisio.bis, tbl_bisio.von, tbl_zeugnisnote.note,tbl_mobilitaet.mobilitaetstyp_kurzbz, (CASE WHEN bis.tbl_mobilitaet.studiensemester_kurzbz = vw_student_lehrveranstaltung.studiensemester_kurzbz THEN '1' ELSE '' END) as doubledegree, - tbl_note.lkt_ueberschreibbar, tbl_note.anmerkung + tbl_note.lkt_ueberschreibbar, tbl_note.anmerkung, tbl_zeugnisnote.punkte FROM campus.vw_student_lehrveranstaltung JOIN public.tbl_benutzer USING(uid) JOIN public.tbl_person USING(person_id) JOIN public.tbl_student ON(uid=student_uid) @@ -306,7 +306,14 @@ else && $elem->von < $stsemdatumbis && (anzahlTage($elem->von, $elem->bis) >= 30)) $inc.=' (o)'; - $note = $elem->note; + if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE==true) + { + $note = $elem->punkte; + } + else + { + $note = $elem->note; + } if($elem->lkt_ueberschreibbar == 'f') // angerechnet / intern angerechnet / nicht zugelassen { @@ -339,20 +346,23 @@ else { $worksheet->write($lines,8, trim($elem->matrikelnr), $format_highlight); $pr = new Pruefung(); - $pr->getPruefungen($elem->uid, "Termin2", $lvid, $sem); + $pr->getPruefungen($elem->uid, "Termin2", $lvid, $stsem); $output2 = $pr->result; if ($output2) { $resultPr = $output2[0]; $worksheet->write($lines,9, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright_date); - $worksheet->write($lines,10, $resultPr->note, $format_highlightright); + if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE==true) + $worksheet->write($lines,10, $resultPr->punkte, $format_highlightright); + else + $worksheet->write($lines,10, $resultPr->note, $format_highlightright); + } + else + { + $worksheet->write($lines,9, '', $format_highlightright_date); + $worksheet->write($lines,10, '', $format_highlightright); } - else - { - $worksheet->write($lines,9, '', $format_highlightright_date); - $worksheet->write($lines,10, '', $format_highlightright); - } } // Nachprüfung @@ -360,20 +370,23 @@ else { $worksheet->write($lines,12, trim($elem->matrikelnr), $format_highlight); $pr = new Pruefung(); - $pr->getPruefungen($elem->uid, "Termin3", $lvid, $sem); + $pr->getPruefungen($elem->uid, "Termin3", $lvid, $stsem); $output3 = $pr->result; if ($output3) { $resultPr = $output3[0]; $worksheet->write($lines,13, date('d.m.Y', strtotime($resultPr->datum)), $format_highlightright_date); - $worksheet->write($lines,14, $resultPr->note, $format_highlightright); + if(defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE==true) + $worksheet->write($lines,14, $resultPr->punkte, $format_highlightright); + else + $worksheet->write($lines,14, $resultPr->note, $format_highlightright); + } + else + { + $worksheet->write($lines,13, '', $format_highlightright_date); + $worksheet->write($lines,14, '', $format_highlightright); } - else - { - $worksheet->write($lines,13, '', $format_highlightright_date); - $worksheet->write($lines,14, '', $format_highlightright); - } } $i++; diff --git a/cis/public/coodle.php b/cis/public/coodle.php index 2b8421db0..05eaa41df 100644 --- a/cis/public/coodle.php +++ b/cis/public/coodle.php @@ -1041,7 +1041,7 @@ function sendEmail($coodle_id) ."END:STANDARD\r\n" ."END:VTIMEZONE\r\n" ."BEGIN:VEVENT\r\n" - .$coodle->foldContentLine("ORGANIZER:MAILTO:".$erstellername." <".$coodle->ersteller_uid."@".DOMAIN)."\r\n" + .$coodle->foldContentLine("ORGANIZER:MAILTO:".$erstellername." <".$coodle->ersteller_uid."@".DOMAIN).">\r\n" .rtrim($teilnehmer)."\r\n" ."DTSTART;TZID=Europe/Vienna:".$dtstart."\r\n" ."DTEND;TZID=Europe/Vienna:".$dtend."\r\n" diff --git a/cis/public/testtool_test/MathML_Beispiel.png b/cis/public/testtool_test/MathML_Beispiel.png new file mode 100644 index 000000000..d6ef2403f Binary files /dev/null and b/cis/public/testtool_test/MathML_Beispiel.png differ diff --git a/cis/public/testtool_test/testseite.php b/cis/public/testtool_test/testseite.php index a200b95b2..34ea12818 100644 --- a/cis/public/testtool_test/testseite.php +++ b/cis/public/testtool_test/testseite.php @@ -86,67 +86,88 @@ echo '';

Formel / Formula

- - 5 - 3 - - - + - - 7 - 6 - - = - - - 10 - 6 - - + - - - 7 - 6 - - = - - 17 - - 6 - + + + 5 + 3 + + + + + 7 + 6 + + = + + 10 + 6 + + + + + 7 + 6 + + = + + 17 + 6 + +

- - - - k=1 - 5 - - - - (-1) - k+1 - - - - - - x - 2k + 1 - - - - (2k+1)! - - - - + + + + + k + = + 1 + + 5 + + + + + ( + - + 1 + ) + + + k + + + 1 + + + + + + x + + 2 + k + + + 1 + + + + + ( + 2 + k + + + 1 + ) + ! + + + +

Bild / Picture

- Beispielbild + Beispielbild
diff --git a/cis/testtool/admin/index.php b/cis/testtool/admin/index.php index 4f010784f..f8e8d36ed 100644 --- a/cis/testtool/admin/index.php +++ b/cis/testtool/admin/index.php @@ -1172,8 +1172,8 @@ if ($frage_id != '') echo ""; //Vorschau fuer das Text-Feld echo "Vorschau:
-
$frage->text
- Derzeit:
$frage->text
+
$frage->text
+ Derzeit:
$frage->text
"; echo ""; echo ''; @@ -1280,8 +1280,8 @@ if ($frage_id != '') echo "/>"; echo "".($vorschlag_id != ''?"frage_id'\" />":'').""; //Vorschau fuer das Text-Feld - echo "Vorschau:
$vorschlag->text
- Derzeit:
$vorschlag->text
"; + echo "Vorschau:
$vorschlag->text
+ Derzeit:
$vorschlag->text
"; echo ""; echo ""; echo ''; diff --git a/cis/testtool/externeueberwachung.js b/cis/testtool/externeueberwachung.js new file mode 100644 index 000000000..71951779f --- /dev/null +++ b/cis/testtool/externeueberwachung.js @@ -0,0 +1,15 @@ +(function () { + function sendMessage() { + let frame = window.frames['content']; + if (frame) + frame.postMessage({ type: "proctoringReady" }); + } + + window.addEventListener("message", function (e) + { + if (e.data.indexOf("proctoringReady_") === 0) + { + sendMessage(); + } + }); +})(); diff --git a/cis/testtool/frage.css b/cis/testtool/frage.css new file mode 100644 index 000000000..04024ae53 --- /dev/null +++ b/cis/testtool/frage.css @@ -0,0 +1,30 @@ +.proctoring-blocker +{ + position: fixed; + inset: 0; + z-index: 99999; + backdrop-filter: blur(6px); + pointer-events: all; + user-select: none; +} + +.proctoring-blocker.hidden +{ + display: none !important; +} + +.proctoring-text +{ + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + color: #fff; + font-size: 16px; + font-family: sans-serif; +} + +.proctoring-blur-fallback +{ + filter: blur(6px); +} diff --git a/cis/testtool/frage.php b/cis/testtool/frage.php index c38229cdf..a5f4100c9 100644 --- a/cis/testtool/frage.php +++ b/cis/testtool/frage.php @@ -45,7 +45,7 @@ if (!$db = new basis_db()) $PHP_SELF=$_SERVER["PHP_SELF"]; // Start session -session_start(); +require_once './session_init.php'; // If language is changed by language select menu, reset language variables if (isset($_GET['sprache_user']) && !empty($_GET['sprache_user'])) @@ -182,6 +182,12 @@ echo ' if(!isset($_SESSION['pruefling_id'])) die($p->t('testtool/bitteZuerstAnmelden')); +if (!empty($_SESSION['externe_ueberwachung']) && isset($_SESSION['externe_ueberwachung_verified'])): ?> + + + +load($_SESSION['pruefling_id']); @@ -575,14 +581,14 @@ if($frage->frage_id!='') else $value=$p->t('testtool/blaettern').' >>'; - echo " $value"; + echo "$value"; } else { if(!$demo) { //Wenns der letzte Eintrag ist, wieder zum ersten springen - echo " ".$p->t('testtool/blaettern')." >>"; + echo "".$p->t('testtool/blaettern')." >>"; } } } diff --git a/cis/testtool/frage_externe_ueberwachung.js b/cis/testtool/frage_externe_ueberwachung.js new file mode 100644 index 000000000..31a7b414f --- /dev/null +++ b/cis/testtool/frage_externe_ueberwachung.js @@ -0,0 +1,53 @@ +(function () { + let ok = false; + let blocker; + + function showBlocker() { + blocker = document.getElementById("proctoringBlocker"); + + if (!blocker) + { + blocker = document.createElement("div"); + blocker.id = "proctoringBlocker"; + blocker.className = "proctoring-blocker"; + blocker.innerHTML = '
Loading...
'; + document.body.appendChild(blocker); + } + document.documentElement.classList.add("proctoring-blur-fallback"); + } + + function block() { + showBlocker(); + blocker.classList.remove("hidden"); + } + + function unblock() { + document.documentElement.classList.remove("proctoring-blur-fallback"); + if (!blocker) return; + blocker.classList.add("hidden"); + } + + const blockTimer = setTimeout(function () { + if (!ok) + block(); + }, 1500); + + window.addEventListener("message", function (e) { + const data = e.data || {}; + + if (data.type === "proctoringReady") + { + ok = true; + clearTimeout(blockTimer); + unblock(); + } + }); + + setTimeout(function () { + if (!ok) { + top.location.href = "resetconnection.php"; + } + }, 3000); +})(); + + diff --git a/cis/testtool/index.php b/cis/testtool/index.php index d235e6ce9..6f2cfac26 100644 --- a/cis/testtool/index.php +++ b/cis/testtool/index.php @@ -1,16 +1,79 @@ TestTool - FH Technikum Wien + + + + @@ -26,3 +89,4 @@ if(isset($_GET['prestudent']) && is_numeric($_GET['prestudent'])) + diff --git a/cis/testtool/login.php b/cis/testtool/login.php index 5a2ae0dea..cfc1ba63b 100644 --- a/cis/testtool/login.php +++ b/cis/testtool/login.php @@ -40,8 +40,7 @@ if (!$db = new basis_db()) die('Fehler beim Oeffnen der Datenbankverbindung'); // Start session -session_start(); - +require_once './session_init.php'; // Logout (triggered by logout button in menu.php) if (isset($_GET['logout']) && $_GET['logout'] == true) { @@ -173,6 +172,12 @@ if (isset($_REQUEST['prestudent'])) else $reload_menu = true; } + + if ($rt->externe_ueberwachung && defined('TESTTOOL_EXTERNE_UEBERWACHUNG_ALLOWED') && TESTTOOL_EXTERNE_UEBERWACHUNG_ALLOWED) + { + $_SESSION['externe_ueberwachung'] = true; + $_SESSION['externe_ueberwachung_verified'] = false; + } } $pruefling = new pruefling(); @@ -335,11 +340,26 @@ else } } -if ((isset($_SESSION['prestudent_id']) && !isset($_SESSION['pruefling_id']) && - !isset($_SESSION['confirmation_needed']) && !isset($_SESSION['confirmed_code'])) || - (isset($_SESSION['confirmation_needed']) && $_SESSION['confirmation_needed'] === true && - isset($_SESSION['confirmed_code']) && $_SESSION['confirmed_code'] === true && - isset($_SESSION['prestudent_id']) && !isset($_SESSION['pruefling_id']))) +if ( + ( + isset($_SESSION['prestudent_id']) && !isset($_SESSION['pruefling_id']) && + !isset($_SESSION['confirmation_needed']) && !isset($_SESSION['confirmed_code']) && + !isset($_SESSION['externe_ueberwachung']) && !isset($_SESSION['externe_ueberwachung_verified']) + ) + || + ( + isset($_SESSION['confirmation_needed']) && $_SESSION['confirmation_needed'] === true && + isset($_SESSION['confirmed_code']) && $_SESSION['confirmed_code'] === true && + isset($_SESSION['prestudent_id']) && !isset($_SESSION['pruefling_id']) + ) + || + ( + isset($_SESSION['externe_ueberwachung']) && $_SESSION['externe_ueberwachung'] === true && + isset($_SESSION['externe_ueberwachung_verified']) && $_SESSION['externe_ueberwachung_verified'] === true && + isset($_SESSION['prestudent_id']) && !isset($_SESSION['pruefling_id']) + ) + +) { $pruefling = new pruefling(); @@ -447,14 +467,6 @@ if (isset($_POST['save']) && isset($_SESSION['prestudent_id'])) { e.preventDefault(); }); - // If Browser is any other than Mozilla Firefox and the test includes any MathML, - // show message to use Mozilla Firefox - var ua = navigator.userAgent; - if ((ua.indexOf("Firefox") > -1) == false) - { - $("#alertmsgdiv").html("
BITTE VERWENDEN SIE DEN MOZILLA FIREFOX BROWSER!
(Manche Prüfungsfragen werden sonst nicht korrekt dargestellt.

PLEASE USE MOZILLA FIREFOX BROWSER!
(Otherwise some exam items will not be displayed correctly
"); - //alert('BITTE VERWENDEN SIE DEN MOZILLA FIREFOX BROWSER!\n(Manche Prüfungsfragen werden sonst nicht korrekt dargestellt.\n\nPLEASE USE MOZILLA FIREFOX BROWSER!\n(Ohterwise some exam items will not be displayed correctly.)'); - } }); top.location.href = 'resetconnection.php';"; + exit; +} +else if (isset($_SESSION['confirmation_needed']) && $_SESSION['confirmation_needed'] === true && isset($_SESSION['confirmed_code']) && $_SESSION['confirmed_code'] === false) { echo ' @@ -660,10 +678,11 @@ elseif (isset($prestudent_id)) else { // Letzten Status für des Prestudenten einholen - $ps_master = new Prestudent(); + $ps_master = new Prestudent($prestudent_id); $ps_master->getLastStatus($prestudent_id); $sto = new Studienordnung(); $sto->getStudienordnungFromStudienplan($ps_master->studienplan_id); + $stg = new Studiengang($ps_master->studiengang_kz); // Name des Studiengangs aus Studienordnung laden, ansonsten Fallback auf Studiengang $stg_name = $sto->studiengangbezeichnung; $stg_name_eng = $sto->studiengangbezeichnung_englisch; @@ -726,7 +745,7 @@ else // LOGIN Site (vor Login) echo ''; echo '
@@ -736,6 +755,12 @@ else // LOGIN Site (vor Login) '.$p->t('testtool/confirmationText').'

+ + '.$p->t('testtool/dsgvoConfirmText').' +

+ + '.$p->t('testtool/procotoringConfirmText').' +

diff --git a/cis/testtool/menu.php b/cis/testtool/menu.php index 7c8b12b9d..11e032f0b 100644 --- a/cis/testtool/menu.php +++ b/cis/testtool/menu.php @@ -34,7 +34,7 @@ if (!$db = new basis_db()) die('Fehler beim Oeffnen der Datenbankverbindung'); // Start session -session_start(); +require_once './session_init.php'; // If language is changed by language select menu, reset language and session variables if(isset($_GET['sprache_user']) && !empty($_GET['sprache_user'])) @@ -61,8 +61,12 @@ $p = new phrasen($sprache_user); db_add_param($_SESSION['studiengang_kz'])." LIMIT 1"; @@ -73,7 +77,7 @@ if (isset($_SESSION['pruefling_id'])) // Link zur Startseite echo ' - '.$p->t('testtool/startseite').' + '.$p->t('testtool/startseite').' '; // Link zur Einleitung @@ -83,7 +87,7 @@ if (isset($_SESSION['pruefling_id'])) { echo ' - '.$p->t('testtool/einleitung').' + '.$p->t('testtool/einleitung').' '; } @@ -379,10 +383,13 @@ if (isset($_SESSION['pruefling_id'])) } } + echo ' + - '.$gebietbezeichnung.' + '.$gebietbezeichnung.' + '; @@ -401,7 +408,7 @@ if (isset($_SESSION['pruefling_id'])) // Link zum Logout echo ' - Logout + Logout '; echo ''; @@ -425,28 +432,6 @@ else e.preventDefault(); }); }); - // Get users Browser - var ua = navigator.userAgent; - - // If Browser is any other than Mozilla Firefox and the test includes any MathML, - // show message to use Mozilla Firefox - if ((ua.indexOf("Firefox") > -1) == false) - { - let hasMathML = ""; - let userLang = ""; - if (hasMathML == true) - { - if (userLang == 'German') - { - alert('BITTE VERWENDEN SIE DEN MOZILLA FIREFOX BROWSER!\n(Manche Prüfungsfragen werden sonst nicht korrekt dargestellt.)'); - } - else if(userLang == 'English') - { - alert('PLEASE USE MOZILLA FIREFOX BROWSER!\n(Ohterwise some exam items will not be displayed correctly.)'); - } - } - } - // Error massage if check_gebiet function returns false $(function() { var invalid_gebiete = ""; @@ -461,5 +446,22 @@ else ''); } }); + + function loadContent(url) + { + if (parent && typeof parent.loadInContent === 'function') + { + parent.loadInContent(url); + return false; + } + + let frame = parent?.frames?.["content"]; + if (frame) + { + frame.location.href = url; + return false; + } + } + diff --git a/cis/testtool/resetconnection.php b/cis/testtool/resetconnection.php new file mode 100644 index 000000000..ab2806a1f --- /dev/null +++ b/cis/testtool/resetconnection.php @@ -0,0 +1,18 @@ +start($_SESSION['prestudent_id'], $_SESSION['reihungstestID'], $_SESSION['sprache']); + $urlSafe = htmlspecialchars($url, ENT_QUOTES); + header("Location: $urlSafe"); + $_SESSION['externe_ueberwachung_verified'] = true; +} \ No newline at end of file diff --git a/cis/testtool/session_init.php b/cis/testtool/session_init.php new file mode 100644 index 000000000..fd7f0b5f3 --- /dev/null +++ b/cis/testtool/session_init.php @@ -0,0 +1,11 @@ +=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">=4.8 <=9" + }, + "suggest": { + "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "support": { + "issues": "https://github.com/firebase/php-jwt/issues", + "source": "https://github.com/firebase/php-jwt/tree/v6.0.0" + }, + "time": "2022-01-24T15:18:34+00:00" + }, { "name": "fortawesome/font-awesome4", "version": "4.7.0", diff --git a/config/cis.config-default.inc.php b/config/cis.config-default.inc.php index 9985a90d4..5dba1cea8 100644 --- a/config/cis.config-default.inc.php +++ b/config/cis.config-default.inc.php @@ -301,4 +301,17 @@ define ('DEFAULT_ECHTER_DIENSTVERTRAG',[103,111]); // Weiterleiten zu CIS neu (wenn Rechte vorhanden) define('CIS_REDIRECT_TO_CIS4', false); + +//Externe Ueberwachung +define('EXTERNE_UEBERWACHUNG_PROTOCOL_URL', 'https://example.com'); +define('EXTERNE_UEBERWACHUNG_SECRET_KEY', null); +define('EXTERNE_UEBERWACHUNG_INTEGRATION_NAME', 'example'); +define('EXTERNE_UEBERWACHUNG_SESSION_URL', 'https://example.com'); +define('EXTERNE_UEBERWACHUNG_TRIAL_TEST', false); +define('EXTERNE_UEBERWACHUNG_EXAM_PARAMS', []); +define('EXTERNE_UEBERWACHUNG_EXAM_RULES', []); +define('EXTERNE_UEBERWACHUNG_EXAM_SCORE', []); +define('EXTERNE_UEBERWACHUNG_EXAM_WARNINGS', []); + + ?> diff --git a/config/global.config-default.inc.php b/config/global.config-default.inc.php index 37bedbdcb..943363f6d 100644 --- a/config/global.config-default.inc.php +++ b/config/global.config-default.inc.php @@ -28,11 +28,15 @@ define('CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN',false); define('CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN', true); define('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN', true); define('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN', true); +define('CIS_LEHRVERANSTALTUNG_EVALUIERUNG_ANZEIGEN', true); // Wenn gesetzt, werden die Digitale Anwesenheit-Icons nur fuer diese Studiengaenge angezeigt, sonst für alle // define('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN_STG', serialize(array('257'))); // define('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN_LVA', serialize(array('39455','39481','39480','41906','41905','41904','39459','39512','39454','39482','42230','42231','39458','41921','41922','39457','42896'))); +// Wenn gesetzt, werden die LV-Evaluierung-Icons nur für diese Studiengaenge angezeigt, sonst alle +define('CIS_EVALUIERUNG_ANZEIGEN_STG', serialize((array('335', '585', '914', '298')))); // BIW, MAI, BUB, MIO + // Im CIS Menue Links bei Modulen anzeigen wenn Lehrauftrag define('CIS_LEHRVERANSTALTUNG_MODULE_LINK',true); @@ -364,4 +368,9 @@ define('SANCHO_MAIL_FOOTER_IMG', 'sancho_footer_DEFAULT.jpg'); // Gibt an, ob in der StudVW der Status vorgerueckt werden kann define('STATUS_VORRUECKEN_ANZEIGEN', true); +//externe Ueberwachung im Testtool erlauben +define('TESTTOOL_EXTERNE_UEBERWACHUNG_ALLOWED', false); + +//enable tags in StudVW +define('STV_TAGS_ENABLED', false); ?> diff --git a/content/student/studentdetailoverlay.xul.php b/content/student/studentdetailoverlay.xul.php index 36740d209..c3bf8c191 100644 --- a/content/student/studentdetailoverlay.xul.php +++ b/content/student/studentdetailoverlay.xul.php @@ -798,6 +798,10 @@ echo ''; class="sortDirectionIndicator" sort="rdf:http://www.technikum-wien.at/prestudentrolle/rdf#updatevon" /> +
` -} - +} \ No newline at end of file diff --git a/public/js/components/Bootstrap/Modal.js b/public/js/components/Bootstrap/Modal.js index a84d9d8d7..e320d4429 100644 --- a/public/js/components/Bootstrap/Modal.js +++ b/public/js/components/Bootstrap/Modal.js @@ -46,7 +46,8 @@ export default { "hiddenBsModal", "hidePreventedBsModal", "showBsModal", - "shownBsModal" + "shownBsModal", + "toggleFullscreen" ], methods: { dispose() { @@ -66,6 +67,7 @@ export default { }, toggleFullscreen() { this.fullscreen = !this.fullscreen + this.$emit('toggleFullscreen') } }, mounted() { @@ -135,10 +137,16 @@ export default {