diff --git a/application/config/Events.php b/application/config/Events.php index 191a1eb98..3e0a5248f 100644 --- a/application/config/Events.php +++ b/application/config/Events.php @@ -3,12 +3,35 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); use CI3_Events as Events; -/** - * NOTE(chris): example: - Events::on('stv_conf_student', function (&$res) { - $res['test'] = [ - 'title' => 'TEST', - 'component' => './Stv/Studentenverwaltung/Details/Notizen.js' - ]; - }); - */ +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' + ); +}); + +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' + ); +}); + +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' + ); +}); + + + diff --git a/application/config/calendar.php b/application/config/calendar.php new file mode 100644 index 000000000..99bb9b2c6 --- /dev/null +++ b/application/config/calendar.php @@ -0,0 +1,6 @@ + array( 'link' => site_url('lehre/lvplanung/AdminZeitverfuegbarkeit'), - 'description' => 'Zeitverfügbarkeit', + 'description' => 'Zeitverfügbarkeit', 'expand' => true, 'sort' => 45, 'requiredPermissions' => array( @@ -325,4 +325,4 @@ $config['navigation_menu']['system/issues/Issues/*'] = array( 'target' => '_blank', 'requiredPermissions' => array('admin:rw') ), -); \ No newline at end of file +); diff --git a/application/config/raumsuche.php b/application/config/raumsuche.php new file mode 100644 index 000000000..afc4beaf8 --- /dev/null +++ b/application/config/raumsuche.php @@ -0,0 +1,25 @@ + 'person_id', + 'table' => 'public.tbl_person', + 'searchfields' => [ + 'uid' => [ + 'comparison' => 'equals', + 'field' => 'uid', + 'join' => [ + 'table' => "public.tbl_benutzer", + 'using' => "person_id" + ], + '1-n' => true + ], + 'vorname' => [ + 'alias' => ['firstname'], + 'comparison' => 'similar', + 'field' => 'vorname' + ], + 'nachname' => [ + 'alias' => ['lastname', 'surename'], + 'comparison' => 'similar', + 'field' => 'nachname' + ], + 'name' => [ + 'comparison' => 'similar', + 'field' => "(vorname || ' ' || nachname)" + ], + 'email' => [ + 'comparison' => 'similar', + 'field' => 'kontakt', + 'join' => [ + 'table' => "public.tbl_kontakt", + 'on' => "kontakttyp = 'email' AND tbl_kontakt.person_id = tbl_person.person_id" + ], + "1-n" => true + ], + 'tel' => [ + 'alias' => ['phone', 'telefon'], + 'comparison' => 'similar', + 'field' => 'kontakt', + 'join' => [ + 'table' => "public.tbl_kontakt", + 'on' => "kontakttyp IN ('telefon', 'so.tel', 'mobil') AND tbl_kontakt.person_id = tbl_person.person_id" + ], + "1-n" => true + ], + 'preid' => [ + 'alias' => ['prestudent_id'], + 'comparison' => 'equal-int', + 'field' => 'prestudent_id', + 'join' => [ + 'table' => "public.tbl_prestudent", + 'using' => "person_id" + ], + '1-n' => true + ], + 'pid' => [ + 'alias' => ['person_id'], + 'comparison' => 'equal-int', + 'field' => 'person_id' + ] + ], + 'resultfields' => [ + "ARRAY( SELECT uid FROM public.tbl_benutzer WHERE person_id = p.person_id ) AS uids", + "p.person_id", + "(p.vorname || ' ' || p.nachname) AS name", + "ARRAY( SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp = 'email' AND person_id=p.person_id ) AS email", + "CASE + WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto + ELSE NULL END + AS photo_url" + ], + 'resultjoin' => " + JOIN public.tbl_person p USING (person_id)" +]; + +$config['student'] = [ + 'primarykey' => 'student_uid', + 'table' => 'public.tbl_student', + 'searchfields' => [ + 'uid' => [ + 'comparison' => 'equals', + 'field' => 'student_uid' + ], + 'vorname' => [ + 'alias' => ['firstname'], + 'comparison' => 'similar', + 'field' => 'vorname', + 'join' => [ + [ + 'table' => "public.tbl_prestudent", + 'using' => "prestudent_id" + ], + [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ] + ], + 'nachname' => [ + 'alias' => ['lastname', 'surename'], + 'comparison' => 'similar', + 'field' => 'nachname', + 'join' => [ + [ + 'table' => "public.tbl_prestudent", + 'using' => "prestudent_id" + ], + [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ] + ], + 'name' => [ + 'comparison' => 'similar', + 'field' => "(vorname || ' ' || nachname)", + 'join' => [ + [ + 'table' => "public.tbl_prestudent", + 'using' => "prestudent_id" + ], + [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ] + ], + 'email' => [ + 'comparison' => 'similar', + 'field' => 'kontakt', + 'join' => [ + [ + 'table' => "public.tbl_prestudent", + 'using' => "prestudent_id" + ], + [ + 'table' => "public.tbl_kontakt", + 'on' => "kontakttyp = 'email' AND tbl_kontakt.person_id = tbl_prestudent.person_id" + ] + ], + "1-n" => true + ], + 'tel' => [ + 'alias' => ['phone', 'telefon'], + 'comparison' => 'similar', + 'field' => 'kontakt', + 'join' => [ + [ + 'table' => "public.tbl_prestudent", + 'using' => "prestudent_id" + ], + [ + 'table' => "public.tbl_kontakt", + 'on' => "kontakttyp IN ('telefon', 'so.tel', 'mobil') AND tbl_kontakt.person_id = tbl_prestudent.person_id" + ] + ], + "1-n" => true + ], + 'stg' => [ + 'alias' => ['studiengang'], + 'comparison' => 'equals', + 'field' => "typ || kurzbz", + 'join' => [ + [ + 'table' => "public.tbl_prestudent", + 'using' => "prestudent_id" + ], + [ + 'table' => "public.tbl_studiengang", + 'on' => "tbl_studiengang.studiengang_kz = tbl_prestudent.studiengang_kz" + ] + ] + ], + 'preid' => [ + 'alias' => ['prestudent_id'], + 'comparison' => 'equal-int', + 'field' => 'prestudent_id' + ], + 'pid' => [ + 'alias' => ['person_id'], + 'comparison' => 'equal-int', + 'field' => 'person_id', + 'join' => [ + 'table' => "public.tbl_prestudent", + 'using' => "prestudent_id" + ] + ] + ], + 'resultfields' => [ + "s.student_uid AS uid", + "s.matrikelnr", + "p.person_id", + "(p.vorname || ' ' || p.nachname) AS name", + "(s.student_uid || '@" . DOMAIN . "') || ARRAY( SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp = 'email' AND person_id=p.person_id ) AS email", + "CASE + WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto + ELSE NULL END + AS photo_url", + "b.aktiv" + ], + 'resultjoin' => " + JOIN public.tbl_student s USING (student_uid) + JOIN public.tbl_benutzer b ON(b.uid = s.student_uid) + JOIN public.tbl_person p USING(person_id)" +]; + +$prestudent_sort = [ + "Student", + "Incoming", + "Outgoing", + "Diplomand", + "Unterbrecher", + "Aufgenommener", + "Wartender", + "Bewerber", + "Interessent", + "Abgewiesener", + "Absolvent", + "Abbrecher", + "Ausserordentlicher", + "Praktikant" +]; +$prestudent_sort_array = "array['" . implode("','", $prestudent_sort) . "']"; +$config['prestudent'] = [ + 'primarykey' => 'prestudent_id', + 'table' => 'public.tbl_prestudent', + 'searchfields' => [ + 'uid' => [ + 'comparison' => 'equals', + 'field' => 'student_uid', + 'join' => [ + 'table' => "public.tbl_student", + 'using' => "prestudent_id" + ] + ], + 'vorname' => [ + 'alias' => ['firstname'], + 'comparison' => 'similar', + 'field' => 'vorname', + 'join' => [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ], + 'nachname' => [ + 'alias' => ['lastname', 'surename'], + 'comparison' => 'similar', + 'field' => 'nachname', + 'join' => [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ], + 'name' => [ + 'comparison' => 'similar', + 'field' => "(vorname || ' ' || nachname)", + 'join' => [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ], + 'email' => [ + 'comparison' => 'similar', + 'field' => 'kontakt', + 'join' => [ + 'table' => "public.tbl_kontakt", + 'on' => "kontakttyp = 'email' AND tbl_kontakt.person_id = tbl_prestudent.person_id" + ], + "1-n" => true + ], + 'tel' => [ + 'alias' => ['phone', 'telefon'], + 'comparison' => 'similar', + 'field' => 'kontakt', + 'join' => [ + 'table' => "public.tbl_kontakt", + 'on' => "kontakttyp IN ('telefon', 'so.tel', 'mobil') AND tbl_kontakt.person_id = tbl_prestudent.person_id" + ], + "1-n" => true + ], + 'stg' => [ + 'alias' => ['studiengang'], + 'comparison' => 'equals', + 'field' => "typ || kurzbz", + 'join' => [ + 'table' => "public.tbl_studiengang", + 'using' => "studiengang_kz" + ] + ], + 'preid' => [ + 'alias' => ['prestudent_id'], + 'comparison' => 'equal-int', + 'field' => 'prestudent_id' + ], + 'pid' => [ + 'alias' => ['person_id'], + 'comparison' => 'equal-int', + 'field' => 'person_id', + 'join' => [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ] + ], + 'resultfields' => [ + "ps.prestudent_id", + "ps.studiengang_kz", + "s.matrikelnr", + "p.person_id", + "b.uid", + "(p.vorname || ' ' || p.nachname) AS name", + "(b.uid || '@" . DOMAIN . "') || ARRAY( SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp = 'email' AND person_id=p.person_id ) AS email", + "CASE + WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto + ELSE NULL END + AS photo_url", + "UPPER(sg.typ || sg.kurzbz) AS stg_kuerzel", + "sg.bezeichnung", + "( + SELECT bezeichnung_mehrsprachig[(TABLE lang)] + FROM public.tbl_status + WHERE status_kurzbz = public.get_rolle_prestudent(ps.prestudent_id, NULL) + LIMIT 1 + ) AS status", + "COALESCE( + ( + SELECT COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz) + FROM public.tbl_prestudentstatus pss + LEFT JOIN lehre.tbl_studienplan plan USING (studienplan_id) + WHERE pss.prestudent_id=ps.prestudent_id + ORDER BY pss.datum DESC, pss.insertamum DESC, pss.ext_id DESC + LIMIT 1 + ), + sg.orgform_kurzbz + ) AS orgform", + "b.aktiv", + "array_position(" . $prestudent_sort_array . ", public.get_rolle_prestudent(ps.prestudent_id, NULL)) AS sort" + ], + 'resultjoin' => " + LEFT JOIN public.tbl_prestudent ps USING (prestudent_id) + LEFT JOIN public.tbl_student s ON (ps.prestudent_id = s.prestudent_id) + LEFT JOIN public.tbl_benutzer b ON (b.uid = s.student_uid) + JOIN public.tbl_person p ON (p.person_id = ps.person_id) + LEFT JOIN public.tbl_studiengang sg ON (sg.studiengang_kz = ps.studiengang_kz)" +]; + +$config['employee'] = [ + 'alias' => ['ma', 'mitarbeiter'], + 'primarykey' => 'mitarbeiter_uid', + 'table' => 'public.tbl_mitarbeiter', + 'searchfields' => [ + 'uid' => [ + 'alias' => ['mitarbeiter_uid'], + 'comparison' => 'equals', + 'field' => "mitarbeiter_uid" + ], + 'vorname' => [ + 'alias' => ['firstname'], + 'comparison' => 'similar', + 'field' => "vorname", + 'join' => [ + [ + 'table' => "public.tbl_benutzer", + 'on' => "uid = mitarbeiter_uid" + ], + [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ] + ], + 'nachname' => [ + 'alias' => ['lastname', 'surename'], + 'comparison' => 'similar', + 'field' => "nachname", + 'join' => [ + [ + 'table' => "public.tbl_benutzer", + 'on' => "uid = mitarbeiter_uid" + ], + [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ] + ], + 'name' => [ + 'comparison' => 'similar', + 'field' => "(vorname || ' ' || nachname)", + 'join' => [ + [ + 'table' => "public.tbl_benutzer", + 'on' => "uid = mitarbeiter_uid" + ], + [ + 'table' => "public.tbl_person", + 'using' => "person_id" + ] + ] + ], + 'email' => [ + 'comparison' => 'similar', + 'field' => "COALESCE(alias, uid) || '" . '@' . DOMAIN . "'", + 'join' => [ + 'table' => "public.tbl_benutzer", + 'on' => "uid = mitarbeiter_uid" + ] + ], + 'tel' => [ + 'alias' => ['phone', 'telefon'], + 'comparison' => 'similar', + 'field' => "TRIM(COALESCE(kontakt, '') || ' ' || COALESCE(telefonklappe, ''))", + 'join' => [ + 'table' => "public.tbl_kontakt", + 'on' => "kontakttyp = 'telefon' AND tbl_kontakt.standort_id = tbl_mitarbeiter.standort_id" + ], + "1-n" => true + ], + 'pid' => [ + 'alias' => ['person_id'], + 'comparison' => 'equal-int', + 'field' => "person_id", + 'join' => [ + 'table' => "public.tbl_benutzer", + 'on' => "uid = mitarbeiter_uid" + ] + ], + 'oe' => [ + 'alias' => ['ou', 'organisationseinheit', 'organisationunit'], + 'comparison' => 'vector', + 'field' => "fts_bezeichnung", + 'join' => [ + [ + 'table' => "public.tbl_benutzerfunktion", + 'on' => "mitarbeiter_uid = uid + AND funktion_kurzbz = 'oezuordnung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW())" + ], + [ + 'table' => "public.tbl_organisationseinheit", + 'using' => "oe_kurzbz" + ] + ], + '1-n' => true + ], + 'kst' => [ + 'comparison' => 'vector', + 'field' => "fts_bezeichnung", + 'join' => [ + [ + 'table' => "public.tbl_benutzerfunktion", + 'on' => "mitarbeiter_uid = uid + AND funktion_kurzbz = 'kstzuordnung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW())" + ], + [ + 'table' => "public.tbl_organisationseinheit", + 'using' => "oe_kurzbz" + ] + ], + '1-n' => true + ] + ], + 'resultfields' => [ + "b.uid", + "p.person_id", + "(p.vorname || ' ' || p.nachname) AS name", + "ARRAY( + SELECT + '[' || ot.bezeichnung || '] ' || o.bezeichnung AS bezeichnung + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) + WHERE bf.funktion_kurzbz = 'oezuordnung' + AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) + AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) + AND bf.uid = b.uid + GROUP BY o.bezeichnung, ot.bezeichnung + ) AS organisationunit_name", + "COALESCE(b.alias, b.uid) || '" . '@' . DOMAIN . "' AS email", + "TRIM(COALESCE(k.kontakt, '') || ' ' || COALESCE(m.telefonklappe, '')) AS phone", + "'" . base_url("/cis/public/bild.php?src=person&person_id=") . "' || p.person_id AS photo_url", + "ARRAY( + SELECT + '[' || ot.bezeichnung || '] ' || o.bezeichnung AS bezeichnung + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_organisationseinheit o USING(oe_kurzbz) + JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz) + WHERE bf.funktion_kurzbz = 'kstzuordnung' + AND (bf.datum_von IS NULL OR bf.datum_von <= NOW()) + AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW()) + AND bf.uid = b.uid + GROUP BY o.bezeichnung, ot.bezeichnung + ) AS standardkostenstelle" + ], + 'resultjoin' => " + JOIN public.tbl_mitarbeiter m USING (mitarbeiter_uid) + JOIN public.tbl_benutzer b ON (b.uid = m.mitarbeiter_uid) + JOIN public.tbl_person p USING(person_id) + LEFT JOIN ( + SELECT kontakt, standort_id + FROM public.tbl_kontakt + WHERE kontakttyp = 'telefon' + ) k ON (k.standort_id = m.standort_id)" +]; + +// TODO(chris): move to searchpv21.php +$config['unassigned_employee'] = $config['employee']; +$config['unassigned_employee']['alias'] = ['mitarbeiter_ohne_zuordnung']; +$config['unassigned_employee']['prepare'] = "unassigned_employee AS ( + SELECT tbl_mitarbeiter.* + FROM public.tbl_mitarbeiter + LEFT JOIN public.tbl_benutzerfunktion ON ( + uid = mitarbeiter_uid + AND funktion_kurzbz = 'kstzuordnung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + ) + WHERE tbl_benutzerfunktion.bezeichnung IS NULL + UNION + SELECT tbl_mitarbeiter.* + FROM public.tbl_mitarbeiter + LEFT JOIN public.tbl_benutzerfunktion ON ( + uid = mitarbeiter_uid + AND funktion_kurzbz = 'oezuordnung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + ) + WHERE tbl_benutzerfunktion.bezeichnung IS NULL +)"; +$config['unassigned_employee']['table'] = "unassigned_employee"; +$config['unassigned_employee']['searchfields']['tel']['join']['on'] = " + kontakttyp = 'telefon' + AND tbl_kontakt.standort_id = unassigned_employee.standort_id +"; +$config['unassigned_employee']['renderer'] = 'employee'; + +$config['organisationunit'] = [ + 'alias' => ['ou', 'organisationseinheit', 'oe'], + 'primarykey' => 'oe_kurzbz', + 'table' => 'public.tbl_organisationseinheit', + 'searchfields' => [ + 'uid' => [ + 'comparison' => 'equals', + 'field' => 'uid', + 'prepare' => "organisationunit_leader(oe_kurzbz, uid, vorname, nachname) AS ( + SELECT oe_kurzbz, vorname, nachname, uid + FROM public.tbl_benutzerfunktion + JOIN public.tbl_benutzer USING (uid) + JOIN public.tbl_person USING (person_id) + WHERE funktion_kurzbz = 'Leitung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + AND tbl_benutzer.aktiv = TRUE + )", + 'join' => [ + 'table' => "organisationunit_leader", + 'using' => "oe_kurzbz" + ], + '1-n' => true + ], + 'vorname' => [ + 'alias' => ['firstname'], + 'comparison' => 'similar', + 'field' => 'vorname', + 'prepare' => "organisationunit_leader(oe_kurzbz, uid, vorname, nachname) AS ( + SELECT oe_kurzbz, vorname, nachname, uid + FROM public.tbl_benutzerfunktion + JOIN public.tbl_benutzer USING (uid) + JOIN public.tbl_person USING (person_id) + WHERE funktion_kurzbz = 'Leitung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + AND tbl_benutzer.aktiv = TRUE + )", + 'join' => [ + 'table' => "organisationunit_leader", + 'using' => "oe_kurzbz" + ], + '1-n' => true + ], + 'nachname' => [ + 'alias' => ['lastname', 'surename'], + 'comparison' => 'similar', + 'field' => 'nachname', + 'prepare' => "organisationunit_leader(oe_kurzbz, uid, vorname, nachname) AS ( + SELECT oe_kurzbz, vorname, nachname, uid + FROM public.tbl_benutzerfunktion + JOIN public.tbl_benutzer USING (uid) + JOIN public.tbl_person USING (person_id) + WHERE funktion_kurzbz = 'Leitung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + AND tbl_benutzer.aktiv = TRUE + )", + 'join' => [ + 'table' => "organisationunit_leader", + 'using' => "oe_kurzbz" + ], + '1-n' => true + ], + 'name' => [ + 'comparison' => 'similar', + 'field' => "(vorname || ' ' || nachname)", + 'prepare' => "organisationunit_leader(oe_kurzbz, uid, vorname, nachname) AS ( + SELECT oe_kurzbz, vorname, nachname, uid + FROM public.tbl_benutzerfunktion + JOIN public.tbl_benutzer USING (uid) + JOIN public.tbl_person USING (person_id) + WHERE funktion_kurzbz = 'Leitung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + AND tbl_benutzer.aktiv = TRUE + )", + 'join' => [ + 'table' => "organisationunit_leader", + 'using' => "oe_kurzbz" + ], + '1-n' => true + ], + 'oe' => [ + 'alias' => ['ou', 'organisationseinheit', 'organisationunit'], + 'comparison' => 'vector', + 'field' => "fts_bezeichnung" + ], + 'kurzbz' => [ + 'alias' => ['oe_kurzbz'], + 'comparison' => 'equals', + 'field' => "oe_kurzbz" + ] + ], + 'resultfields' => [ + "oe.oe_kurzbz", + "('[' || type.bezeichnung || '] ' || oe.bezeichnung) AS name", + "oe_parent.oe_kurzbz AS parentoe_kurzbz", + "(CASE WHEN oe_parent.bezeichnung IS NOT NULL THEN '[' || type_parent.bezeichnung || '] ' || oe_parent.bezeichnung END) AS parentoe_name", + "ARRAY( + SELECT JSON_BUILD_OBJECT('uid', b.uid, 'vorname', p.vorname, 'nachname', p.nachname, 'name', (p.vorname || ' ' || p.nachname)) + FROM public.tbl_benutzerfunktion bf + JOIN public.tbl_benutzer b USING (uid) + JOIN public.tbl_person p USING (person_id) + WHERE funktion_kurzbz = 'Leitung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + AND b.aktiv = TRUE + AND oe_kurzbz = oe.oe_kurzbz + ) AS leaders", + "( + SELECT COUNT(*) + FROM public.tbl_benutzerfunktion + WHERE funktion_kurzbz = 'oezuordnung' + AND (datum_von IS NULL OR datum_von <= NOW()) + AND (datum_bis IS NULL OR datum_bis >= NOW()) + AND oe_kurzbz = oe.oe_kurzbz + ) AS number_of_people", + "(CASE WHEN oe.mailverteiler THEN oe.oe_kurzbz || '" . '@' . DOMAIN . "' END) AS mailgroup" + ], + 'resultjoin' => " + JOIN public.tbl_organisationseinheit oe + USING (oe_kurzbz) + JOIN public.tbl_organisationseinheittyp type + USING (organisationseinheittyp_kurzbz) + LEFT JOIN public.tbl_organisationseinheit oe_parent + ON (oe_parent.oe_kurzbz = oe.oe_parent_kurzbz) + LEFT JOIN public.tbl_organisationseinheittyp type_parent + ON (oe_parent.organisationseinheittyp_kurzbz = type_parent.organisationseinheittyp_kurzbz)" +]; + +$config['room'] = [ + 'alias' => ['raum'], + 'primarykey' => 'ort_kurzbz', + 'table' => 'public.tbl_ort', + 'searchfields' => [ + 'name' => [ + 'comparison' => 'similar', + 'field' => 'ort_kurzbz' + ] + ], + 'resultfields' => [ + "ort.ort_kurzbz", + "ort.gebteil AS building", + "ort.ausstattung AS equipment", + "ort.stockwerk AS floor", + "ort.dislozierung AS room_number", + "ort.content_id", + "address.ort AS city", + "address.plz AS zip", + "address.strasse AS street", + "ort.max_person", + "ort.arbeitsplaetze AS workplaces" + ], + 'resultjoin' => " + JOIN public.tbl_ort ort + USING (ort_kurzbz) + LEFT JOIN public.tbl_standort + USING (standort_id) + LEFT JOIN public.tbl_adresse address + USING (adresse_id)" +]; +$sprache = getUserLanguage(); +$config['cms'] = [ + 'primarykey' => 'contentsprache_id', + 'table' => 'campus.tbl_contentsprache', + 'prepare' => " + cms_auth (content_id) AS ( + SELECT content_id + FROM campus.tbl_content c + WHERE NOT EXISTS (SELECT 1 FROM campus.tbl_contentgruppe g WHERE g.content_id=c.content_id) + UNION + SELECT content_id + FROM public.vw_gruppen g + JOIN campus.tbl_contentgruppe c USING (gruppe_kurzbz) + WHERE uid = (TABLE auth) + ), + cms_active (content_id, template_kurzbz) AS ( + SELECT content_id, template_kurzbz + FROM cms_auth + JOIN campus.tbl_content USING (content_id) + WHERE aktiv = TRUE + ), + cms_active_redirect (content_id) AS ( + SELECT content_id + FROM cms_active + WHERE template_kurzbz = 'redirect' + ), + cms_active_redirect_linked (content_id) AS ( + SELECT content_id + FROM cms_active_redirect + JOIN campus.tbl_contentsprache USING (content_id) + WHERE LEFT((xpath('string(/content/url)', content))[1]::text, 1) <> '#' + ), + cms_active_others (content_id) AS ( + SELECT content_id + FROM cms_active + WHERE template_kurzbz IN ('contentmittitel', 'contentohnetitel', 'contentmittitel_filterwidget') + ) + ", + 'searchfields' => [ + 'content' => [ + 'alias' => ['inhalt'], + 'comparison' => "vector", + 'field' => "( + setweight(to_tsvector('simple', COALESCE(titel, '')), 'A') + || + setweight(to_tsvector('simple', COALESCE(content, '')::text), 'B') + )" + ], + 'content_id' => [ + 'alias' => ['id'], + 'comparison' => "equal-int", + 'field' => "content_id" + ], + 'lang' => [ + 'alias' => ['language', 'sprache'], + 'comparison' => "equals", + 'field' => "sprache" + ] + ], + 'resultfields' => [ + "contentsprache.content_id", + "content.template_kurzbz", + "contentsprache.version", + "contentsprache.sprache AS language", + "contentsprache.titel AS title", + "contentsprache.content", + "(xpath('string(/content/url)', contentsprache.content))[1] AS content_url" + ], + 'resultjoin' => " + JOIN campus.tbl_contentsprache contentsprache + USING (contentsprache_id) + JOIN campus.tbl_content content + USING (content_id) + WHERE content_id IN ( + SELECT content_id + FROM cms_active_redirect_linked + UNION + SELECT content_id + FROM cms_active_others + ) + AND version = campus.get_highest_content_version(content_id) + AND contentsprache.sprache = '{$sprache}'" +]; + +$config['dms'] = [ + 'primarykey' => 'dms_id, version', + 'table' => 'campus.tbl_dms_version', + 'searchfields' => [ + 'keywords' => [ + 'alias' => ['keyword', 'keywords', 'schlagwort', 'schlagworte'], + 'comparison' => "vector", + 'field' => "(to_tsvector('simple', COALESCE(schlagworte, '')))" + ] + ], + 'resultfields' => [ + "v.dms_id", + "v.version", + "v.filename", + "v.mimetype", + "v.name", + "v.beschreibung AS description", + "v.schlagworte AS keywords" + ], + 'resultjoin' => " + JOIN campus.tbl_dms_version v + USING (dms_id, version) + WHERE cis_suche = TRUE + AND version=(SELECT MAX(version) FROM campus.tbl_dms_version WHERE dms_id=v.dms_id) + AND NOT EXISTS ( + SELECT + 1 + FROM + fue.tbl_projekt_dokument p + WHERE p.dms_id = v.dms_id + ) AND ( + NOT EXISTS ( + WITH RECURSIVE categories (kategorie_kurzbz) AS ( + SELECT + kategorie_kurzbz + FROM + campus.tbl_dms c + WHERE c.dms_id = v.dms_id + UNION ALL + SELECT + cat.parent_kategorie_kurzbz AS kategorie_kurzbz + FROM + categories + JOIN campus.tbl_dms_kategorie cat USING (kategorie_kurzbz) + ) + SELECT + 1 + FROM + categories + JOIN campus.tbl_dms_kategorie_gruppe USING (kategorie_kurzbz) + UNION + SELECT + 1 + FROM + categories + JOIN campus.tbl_dms_kategorie USING (kategorie_kurzbz) + WHERE + berechtigung_kurzbz IS NOT NULL + ) OR EXISTS ( + WITH RECURSIVE categories (kategorie_kurzbz) AS ( + SELECT + kategorie_kurzbz + FROM + campus.tbl_dms c + WHERE c.dms_id = v.dms_id + UNION ALL + SELECT + cat.parent_kategorie_kurzbz AS kategorie_kurzbz + FROM + categories + JOIN campus.tbl_dms_kategorie cat USING (kategorie_kurzbz) + ) + SELECT + 1 + FROM + categories + JOIN campus.tbl_dms_kategorie_gruppe USING (kategorie_kurzbz) + JOIN public.tbl_benutzergruppe USING(gruppe_kurzbz) + WHERE + uid = (TABLE auth) + ) + )" +]; diff --git a/application/config/searchcis.php b/application/config/searchcis.php new file mode 100644 index 000000000..e3d1e2213 --- /dev/null +++ b/application/config/searchcis.php @@ -0,0 +1,48 @@ +config->item('employee', 'search'); +$config['employee']['resultjoin'] = " + JOIN public.tbl_mitarbeiter m USING (mitarbeiter_uid) + JOIN public.tbl_benutzer b ON (b.uid = m.mitarbeiter_uid AND b.aktiv = true) + JOIN public.tbl_person p USING(person_id) + LEFT JOIN ( + SELECT kontakt, standort_id + FROM public.tbl_kontakt + WHERE kontakttyp = 'telefon' + ) k ON (k.standort_id = m.standort_id)"; + +$config['student'] = $CI->config->item('student', 'search'); +unset($config['student']['searchfields']['email']); +unset($config['student']['searchfields']['tel']); +$config['student']['resultfields'] = [ + "s.student_uid AS uid", + "s.matrikelnr", + "p.person_id", + "(p.vorname || ' ' || p.nachname) AS name", + "ARRAY[s.student_uid || '@' || '" . DOMAIN . "'] AS email", + "CASE + WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto + ELSE NULL END + AS photo_url", + "b.aktiv" +]; +$config['student']['resultjoin'] = " + JOIN public.tbl_student s USING (student_uid) + JOIN public.tbl_benutzer b ON(b.uid = s.student_uid AND b.aktiv = true) + JOIN public.tbl_person p USING(person_id)"; + +$config['organisationunit'] = $CI->config->item('organisationunit', 'search'); +$config['organisationunit']['prepare'] = 'active_organisationseinheit AS (SELECT * FROM public.tbl_organisationseinheit WHERE aktiv = true AND organisationseinheittyp_kurzbz <> \'Container\')'; +$config['organisationunit']['table'] = 'active_organisationseinheit'; + +$config['room'] = $CI->config->item('room', 'search'); + +$config['cms'] = $CI->config->item('cms', 'search'); + +$config['dms'] = $CI->config->item('dms', 'search'); diff --git a/application/config/searchfunctions.php b/application/config/searchfunctions.php new file mode 100644 index 000000000..276652997 --- /dev/null +++ b/application/config/searchfunctions.php @@ -0,0 +1,35 @@ + 4, + 'rank' => "0", + 'compare' => "{field}::text = {word}::text", + 'force_integer' => true +]; + +$config['equals'] = [ + 'priority' => 3, + 'rank' => "0", + 'compare' => "LOWER({field}) = {word}" +]; + +$config['similar'] = [ + 'priority' => 2, + 'rank' => "(COALESCE({field}, '') <->> {word})", + 'compare' => "COALESCE({field}, '') %> {word}", + 'compare_boolean' => "COALESCE({field}, '') ILIKE {like:word}" +]; + +$config['vector'] = [ + 'priority' => 1, + 'rank' => "ts_rank({field}, to_tsquery('simple', {word}))", + 'compare' => "to_tsquery('simple', {word}) @@ {field}" +]; + diff --git a/application/config/searchstv.php b/application/config/searchstv.php new file mode 100644 index 000000000..96c118ac8 --- /dev/null +++ b/application/config/searchstv.php @@ -0,0 +1,11 @@ +config->item('student', 'search'); + +$config['prestudent'] = $CI->config->item('prestudent', 'search'); diff --git a/application/config/stv.php b/application/config/stv.php index 50d4e74a9..39eae5067 100644 --- a/application/config/stv.php +++ b/application/config/stv.php @@ -1,5 +1,6 @@ [ diff --git a/application/config/theme.php b/application/config/theme.php new file mode 100644 index 000000000..715c4e39c --- /dev/null +++ b/application/config/theme.php @@ -0,0 +1,11 @@ + self::PERM_LOGGED, + 'getStudentProjektarbeitAbgabeFile' => self::PERM_LOGGED, + 'Mitarbeiter' => self::PERM_LOGGED, + 'Student' => self::PERM_LOGGED, + 'Deadlines' => self::PERM_LOGGED + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + + $viewData = array( + 'uid'=>getAuthUID(), + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']); + } + + public function Student() + { + + $viewData = array( + 'uid'=>getAuthUID(), + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']); + } + + public function Mitarbeiter() + { + + $viewData = array( + 'uid'=>getAuthUID(), + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolMitarbeiter']); + } + + 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'); + } + } else { + $this->terminateWithJsonError('Keine Zuordnung!'); + } + } +} diff --git a/application/controllers/Cis/LvPlan.php b/application/controllers/Cis/LvPlan.php new file mode 100644 index 000000000..884c8a9a0 --- /dev/null +++ b/application/controllers/Cis/LvPlan.php @@ -0,0 +1,39 @@ + ['basis/cis:r'] + ]); + + // Load Config + $this->load->config('calendar'); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + + $viewData = array( + 'uid'=>getAuthUID(), + 'timezone' => $this->config->item('timezone') + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'LvPlan']); + } +} diff --git a/application/controllers/Cis/MyLvPlan.php b/application/controllers/Cis/MyLvPlan.php new file mode 100644 index 000000000..366ce8e65 --- /dev/null +++ b/application/controllers/Cis/MyLvPlan.php @@ -0,0 +1,39 @@ + ['basis/cis:r'] + ]); + + // Load Config + $this->load->config('calendar'); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + /** + * @return void + */ + public function index() + { + + $viewData = array( + 'uid'=>getAuthUID(), + 'timezone' => $this->config->item('timezone') + ); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLvPlan']); + } +} diff --git a/application/controllers/Cis/Profil.php b/application/controllers/Cis/Profil.php index 8c3088bd7..c287d87d0 100644 --- a/application/controllers/Cis/Profil.php +++ b/application/controllers/Cis/Profil.php @@ -55,8 +55,13 @@ class Profil extends Auth_Controller */ public function index() { + + $this->load->library('ProfilLib'); + $profil_data = $this->profillib->getView(getAuthUID()); + $profil_data = hasData($profil_data) ? getData($profil_data) : null; $viewData = array( - + 'editable'=>true, + 'profil_data' => $profil_data, ); $this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'profilIndex']); } @@ -68,8 +73,16 @@ class Profil extends Auth_Controller */ public function View($uid) { - $viewData = array ('uid' => $uid); - + $this->load->library('ProfilLib'); + $profil_data = $this->profillib->getView($uid); + $profil_data = hasData($profil_data) ? getData($profil_data) : null; + $viewData = array ( + 'uid' => $uid, + 'profil_data'=>$profil_data, + ); + if($uid == getAuthUID()){ + $viewData['editable'] = true; + } $this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'profilViewUid']); } diff --git a/application/controllers/Cis/Stundenplan.php b/application/controllers/Cis/Raumsuche.php similarity index 84% rename from application/controllers/Cis/Stundenplan.php rename to application/controllers/Cis/Raumsuche.php index 71e01be8b..055038275 100644 --- a/application/controllers/Cis/Stundenplan.php +++ b/application/controllers/Cis/Raumsuche.php @@ -5,7 +5,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** * */ -class Stundenplan extends Auth_Controller +class Raumsuche extends Auth_Controller { /** * Constructor @@ -25,11 +25,11 @@ class Stundenplan extends Auth_Controller */ public function index() { - + $viewData = array( 'uid'=>getAuthUID(), ); - - $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Stundenplan']); + + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Raumsuche']); } } diff --git a/application/controllers/Cis/Studium.php b/application/controllers/Cis/Studium.php new file mode 100644 index 000000000..a298de648 --- /dev/null +++ b/application/controllers/Cis/Studium.php @@ -0,0 +1,40 @@ + ['basis/cis:r'], + + ]); + } + + // ----------------------------------------------------------------------------------------------------------------- + // Public methods + + + /** + * index loads the Studium view + * @access public + * @return void + */ + public function index() + { + $viewData = array( + + ); + $this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'studium']); + } + + + +} diff --git a/application/controllers/Cis4.php b/application/controllers/Cis4.php index c0ca8d503..b7ba2029d 100644 --- a/application/controllers/Cis4.php +++ b/application/controllers/Cis4.php @@ -17,6 +17,9 @@ class Cis4 extends Auth_Controller 'index' => 'basis/cis:r' ) ); + + // Load Config + $this->load->config('calendar'); } // ----------------------------------------------------------------------------------------------------------------- @@ -27,15 +30,16 @@ class Cis4 extends Auth_Controller */ public function index() { - $this->load->model('person/Person_model','PersonModel'); + $this->load->model('person/Person_model', 'PersonModel'); $personData = getData($this->PersonModel->getByUid(getAuthUID()))[0]; $viewData = array( 'uid' => getAuthUID(), 'name' => $personData->vorname, - 'person_id' => $personData->person_id + 'person_id' => $personData->person_id, + 'timezone' => $this->config->item('timezone') ); - $this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'FhcDashboard']); + $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'FhcDashboard']); } -} \ No newline at end of file +} diff --git a/application/controllers/CisVue/Cms.php b/application/controllers/CisVue/Cms.php index a9ff13c53..aa07b919f 100644 --- a/application/controllers/CisVue/Cms.php +++ b/application/controllers/CisVue/Cms.php @@ -87,9 +87,14 @@ class Cms extends Auth_Controller $this->load->view('CisRouterView/CisRouterView.php', ['viewData'=>$viewData, 'route' => 'News']); } - public function getRoomInformation($ort_kurzbz){ + public function getRoomInformation($ort_kurzbz) + { + // Load Config + $this->load->config('calendar'); + $viewData = array( - 'ort_kurzbz' => $ort_kurzbz + 'ort_kurzbz' => $ort_kurzbz, + 'timezone' => $this->config->item('timezone') ); $this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'CmsRoom']); } diff --git a/application/controllers/api/frontend/v1/AuthInfo.php b/application/controllers/api/frontend/v1/AuthInfo.php index 1362aee18..72f396b4f 100644 --- a/application/controllers/api/frontend/v1/AuthInfo.php +++ b/application/controllers/api/frontend/v1/AuthInfo.php @@ -20,6 +20,10 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); class AuthInfo extends FHCAPI_Controller { + protected $uid; + protected $pid; + protected $isMitarbeiter; + protected $isStudent; /** * Object initialization @@ -28,10 +32,16 @@ class AuthInfo extends FHCAPI_Controller { parent::__construct([ 'getAuthUID' => self::PERM_LOGGED, + 'getAuthInfo' => self::PERM_LOGGED, ]); + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + $this->uid = getAuthUID(); $this->pid = getAuthPersonID(); + $this->isMitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter($this->uid)) ?? false; + $this->isStudent = getData($this->StudentModel->isStudent($this->uid)) ?? false; } //------------------------------------------------------------------------------------------------------------------ @@ -47,6 +57,14 @@ class AuthInfo extends FHCAPI_Controller $this->terminateWithSuccess(['uid'=>$this->uid]); } - + public function getAuthInfo() + { + $data = (object) array( + 'uid' => $this->uid, + 'isMitarbeiter' => $this->isMitarbeiter, + 'isStudent' => $this->isStudent + ); + $this->terminateWithSuccess($data); + } } diff --git a/application/controllers/api/frontend/v1/Documents.php b/application/controllers/api/frontend/v1/Documents.php index ebd1b269b..2d2c410cf 100644 --- a/application/controllers/api/frontend/v1/Documents.php +++ b/application/controllers/api/frontend/v1/Documents.php @@ -152,7 +152,7 @@ class Documents extends FHCAPI_Controller * @param string $xml * @param string $xsl * @param string $sign_user (optional) - * + * * @return array with Akte data and export data */ private function _getAkteExportData($xml, $xsl, $sign_user = null) @@ -235,7 +235,7 @@ class Documents extends FHCAPI_Controller $student = current($this->getDataOrTerminateWithError($result)); $ss = $this->input->post_get('ss'); - + if ($ss !== null) { $this->load->model('crm/prestudentstatus_model', 'PrestudentstatusModel'); $result = $this->PrestudentstatusModel->getLastStatus($student->prestudent_id, $ss); @@ -334,7 +334,7 @@ class Documents extends FHCAPI_Controller $this->PrestudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT'); $result = $this->PrestudentModel->load($prestudent_id); $prestudent = current($this->getDataOrTerminateWithError($result)); - + $studiengang_kz = $prestudent->studiengang_kz; $akteData['person_id'] = $prestudent->person_id; $akteData['titel'] = mb_substr($xsl . "_" . $prestudent->kuerzel, 0, 64); @@ -380,7 +380,7 @@ class Documents extends FHCAPI_Controller // TODO: was bedeutet wenn keine berechtigung? if (!$access_rights || !$access_rights->berechtigung) return show_404(); - + $allowed = false; foreach ($access_rights->berechtigung as $access_right) { if ($this->permissionlib->isBerechtigt($access_right)) { @@ -454,11 +454,11 @@ class Documents extends FHCAPI_Controller if (!$vorlage->archivierbar) $this->terminateWithError($this->p->t("stv", "grades_error_archive")); - + if ($sign_user && !$vorlage->signierbar) $this->terminateWithError($this->p->t("stv", "grades_error_sign")); - + $this->load->library('DocumentExportLib'); // XML Data diff --git a/application/controllers/api/frontend/v1/Language.php b/application/controllers/api/frontend/v1/Language.php new file mode 100644 index 000000000..797af4804 --- /dev/null +++ b/application/controllers/api/frontend/v1/Language.php @@ -0,0 +1,47 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +/** + * This controller operates between (interface) the JS (GUI) and the back-end + * Provides data to the ajax get calls about languages + * This controller works with JSON calls on the HTTP GET and the output is always JSON + */ +class Language extends FHCAPI_Controller +{ + public function __construct() + { + parent::__construct([ + 'get' => self::PERM_LOGGED + ]); + + // Load models + $this->load->model('system/Sprache_model', 'SpracheModel'); + } + + public function get() + { + $this->SpracheModel->addOrder('sprache'); + + $result = $this->SpracheModel->load(); + $data = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($data); + } +} diff --git a/application/controllers/api/frontend/v1/Lehre.php b/application/controllers/api/frontend/v1/Lehre.php index f079a5b37..d5d0282bd 100644 --- a/application/controllers/api/frontend/v1/Lehre.php +++ b/application/controllers/api/frontend/v1/Lehre.php @@ -18,6 +18,14 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); +//require_once('../../../include/studiengang.class.php'); +//require_once('../../../include/student.class.php'); +//require_once('../../../include/datum.class.php'); +//require_once('../../../include/mail.class.php'); +//require_once('../../../include/benutzerberechtigung.class.php'); +//require_once('../../../include/phrasen.class.php'); +//require_once('../../../include/projektarbeit.class.php'); +//require_once('../../../include/projektbetreuer.class.php'); class Lehre extends FHCAPI_Controller { @@ -31,10 +39,33 @@ class Lehre extends FHCAPI_Controller '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 ]); - + $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'); } //------------------------------------------------------------------------------------------------------------------ @@ -94,10 +125,557 @@ 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/Lehrveranstaltung.php b/application/controllers/api/frontend/v1/Lehrveranstaltung.php index 1b2e2bc35..2e254bfc8 100644 --- a/application/controllers/api/frontend/v1/Lehrveranstaltung.php +++ b/application/controllers/api/frontend/v1/Lehrveranstaltung.php @@ -27,8 +27,8 @@ class Lehrveranstaltung extends FHCAPI_Controller public function __construct() { parent::__construct([ - 'loadByEmployee' => ['admin:r', 'assistenz:r'], - 'loadByStudiengang' => ['admin:r', 'assistenz:r'], + 'getByEmp' => ['admin:r', 'assistenz:r'], + 'getByStg' => ['admin:r', 'assistenz:r'], 'loadByLV' => ['admin:r', 'assistenz:r'], ]); @@ -37,15 +37,24 @@ class Lehrveranstaltung extends FHCAPI_Controller $this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel'); $this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); $this->_ci->load->library('VariableLib', ['uid' => $this->_uid]); - } - public function loadByEmployee($mitarbeiter_uid = null, $stg_kz = null) - { - if (is_null($mitarbeiter_uid)) - $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); - $studiensemester_kurzbz = $this->_ci->variablelib->getVar('semester_aktuell'); + $this->loadPhrases( + array( + 'ui' + ) + ); + } + + public function getByEmp($studiensemester_kurzbz = null, $mitarbeiter_uid = null, $stg_kz = null) + { + + if (is_null($mitarbeiter_uid)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + $studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz); $lehrveranstaltungen = $this->_ci->LehreinheitModel->getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz); $lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen); @@ -54,7 +63,7 @@ class Lehrveranstaltung extends FHCAPI_Controller foreach ($lehrveranstaltungen_data as $lehrveranstaltung) { - $lehreinheiten = $this->_ci->LehreinheitModel->getLEByLV($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz, $mitarbeiter_uid); + $lehreinheiten = $this->_ci->LehreinheitModel->getByLvidStudiensemester($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz, $mitarbeiter_uid); $lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten); if (!isset($lehrveranstaltung->_children)) @@ -66,11 +75,10 @@ class Lehrveranstaltung extends FHCAPI_Controller $this->terminateWithSuccess($tree); } - - public function loadByStudiengang($studiengang_kz = null, $semester = null) + public function getByStg($studiensemester_kurzbz = null, $studiengang_kz = null, $semester = null) { - if (is_null($studiengang_kz) || !ctype_digit((string)$studiengang_kz)) - $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + if (is_null($studiengang_kz) || !preg_match("/^-?[1-9][0-9]*$/", (string)$studiengang_kz)) + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); $verband = null; if (!is_null($semester) && !is_numeric($semester)) @@ -81,7 +89,7 @@ class Lehrveranstaltung extends FHCAPI_Controller $this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel'); - $studiensemester_kurzbz = $this->_ci->variablelib->getVar('semester_aktuell'); + $studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz); $studienplan_data = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $semester, $verband); $studienplan_ids = array(); @@ -101,7 +109,6 @@ class Lehrveranstaltung extends FHCAPI_Controller $lehrveranstaltungen_data = $this->_ci->LehrveranstaltungModel->getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester, $verband); $lehrveranstaltungen_data = hasData($lehrveranstaltungen_data) ? getData($lehrveranstaltungen_data) : array(); - $tree = []; foreach ($lehrveranstaltungen_data as $row) { @@ -164,7 +171,7 @@ class Lehrveranstaltung extends FHCAPI_Controller if (is_null($lehrveranstaltung_id) || !ctype_digit((string)$lehrveranstaltung_id)) $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); - $this->_ci->LehrveranstaltungModel->addSelect('lehrveranstaltung_id, lehrform_kurzbz, lehre, bezeichnung as lvbezeichnung'); + $this->_ci->LehrveranstaltungModel->addSelect('lehrveranstaltung_id, lehrform_kurzbz, lehre, bezeichnung as lvbezeichnung, sprache'); $lehrveranstaltung_result = $this->_ci->LehrveranstaltungModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung_id)); $lehrveranstaltung_result = $this->getDataOrTerminateWithError($lehrveranstaltung_result); $lehrveranstaltung = $lehrveranstaltung_result[0]; @@ -202,7 +209,7 @@ class Lehrveranstaltung extends FHCAPI_Controller foreach ($lehrveranstaltungen_data as $lehrveranstaltung) { - $lehreinheiten = $this->LehreinheitModel->getLEByLV($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz); + $lehreinheiten = $this->LehreinheitModel->getByLvidStudiensemester($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz); $lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten); if (!isset($lehrveranstaltung->_children)) @@ -240,4 +247,19 @@ class Lehrveranstaltung extends FHCAPI_Controller } } } + + private function getStudiensemesterKurzbz($studiensemester_kurzbz = null) + { + if (!is_null($studiensemester_kurzbz)) + { + $studiensemester_result = $this->_ci->StudiensemesterModel->load($studiensemester_kurzbz); + + if (isError($studiensemester_result) || !hasData($studiensemester_result)) + $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + + return getData($studiensemester_result)[0]->studiensemester_kurzbz; + } + + $this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); + } } diff --git a/application/controllers/api/frontend/v1/LvPlan.php b/application/controllers/api/frontend/v1/LvPlan.php new file mode 100644 index 000000000..3b6b55911 --- /dev/null +++ b/application/controllers/api/frontend/v1/LvPlan.php @@ -0,0 +1,362 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use CI3_Events as Events; +use \DateTime as DateTime; +use \DateTimeZone as DateTimeZone; + +class LvPlan extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + + parent::__construct([ + 'getRoomplan' => self::PERM_LOGGED, + 'Stunden' => self::PERM_LOGGED, + 'getReservierungen' => self::PERM_LOGGED, + 'LvPlanEvents' => self::PERM_LOGGED, + 'eventsPersonal' => self::PERM_LOGGED, + 'eventsLv' => self::PERM_LOGGED, + 'getLehreinheitStudiensemester' => self::PERM_LOGGED, + 'studiensemesterDateInterval' => self::PERM_LOGGED, + 'getLvPlanForStudiensemester' => self::PERM_LOGGED, + 'getLv' => self::PERM_LOGGED + ]); + + $this->load->library('LogLib'); + $this->loglib->setConfigs(array( + 'classIndex' => 5, + 'functionIndex' => 5, + 'lineIndex' => 4, + 'dbLogType' => 'API', // required + 'dbExecuteUser' => 'RESTful API' + )); + + $this->load->library('form_validation'); + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * fetches LvPlan and Moodle events together + * @access public + * + */ + public function LvPlanEvents() + { + $hasLv = $this->input->post('lv_id'); + + return $hasLv ? $this->eventsLv() : $this->eventsPersonal(); + } + + /** + * fetches LvPlan, Moodle and Ferien events together for the logged in user + * + * @access public + */ + public function eventsPersonal() + { + $this->load->library('StundenplanLib'); + + // form validation + $this->form_validation->set_rules('start_date', "start_date", "required"); + $this->form_validation->set_rules('end_date', "end_date", "required"); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // storing the post parameter in local variables + $start_date = $this->input->post('start_date', true); + $end_date = $this->input->post('end_date', true); + + // fetching lvplan events + $result = $this->stundenplanlib->getEventsUser($start_date, $end_date); + $lvplanEvents = $this->getDataOrTerminateWithError($result); + + // fetching moodle events + $moodleEvents = $this->fetchMoodleEvents($start_date, $end_date); + + // fetching ferien events + $ferienEvents = $this->fetchFerienEvents($start_date, $end_date); + + + $this->terminateWithSuccess(array_merge( + $lvplanEvents, + $moodleEvents, + $ferienEvents + )); + } + + /** + * fetches LvPlan and Ferien events together for the lv + * + * @access public + */ + public function eventsLv() + { + $this->load->library('StundenplanLib'); + + // form validation + $this->form_validation->set_rules('start_date', "start_date", "required"); + $this->form_validation->set_rules('end_date', "end_date", "required"); + $this->form_validation->set_rules('lv_id', "lv_id", "required|integer"); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // storing the post parameter in local variables + $start_date = $this->input->post('start_date', true); + $end_date = $this->input->post('end_date', true); + $lv_id = $this->input->post('lv_id', true); + + // fetching lvplan events + $result = $this->stundenplanlib->getEventsLv($lv_id, $start_date, $end_date); + $lvplanEvents = $this->getDataOrTerminateWithError($result); + + // fetching ferien events + $ferienEvents = $this->fetchFerienEvents($start_date, $end_date); + + + $this->terminateWithSuccess(array_merge( + $lvplanEvents, + $ferienEvents + )); + } + + //TODO: delete this function if we don't use the old calendar export endpoints anymore + public function studiensemesterDateInterval($date){ + $this->load->model('organisation/Studiensemester_model','StudiensemesterModel'); + $studiensemester =$this->StudiensemesterModel->getByDate(date_format(date_create($date),'Y-m-d')); + $studiensemester =current($this->getDataOrTerminateWithError($studiensemester)); + $this->terminateWithSuccess($studiensemester); + } + + public function getLvPlanForStudiensemester($studiensemester,$lvid){ + $this->load->library('StundenplanLib'); + $this->load->model('organisation/Studiensemester_model','StudiensemesterModel'); + + $studiensemester_result = $this->StudiensemesterModel->loadWhere(["studiensemester_kurzbz"=>$studiensemester]); + $studiensemester_result = current($this->getDataOrTerminateWithError($studiensemester_result)); + $timespan_start = new DateTime($studiensemester_result->start); + $timespan_ende = new DateTime($studiensemester_result->ende); + $lvplan = $this->stundenplanlib->getStundenplan(date_format($timespan_start, 'Y-m-d'),date_format($timespan_ende, 'Y-m-d'), $lvid); + $this->terminateWithSuccess($lvplan); + + } + + + /** + * fetches Stunden layout from database + * @access public + * + */ + public function Stunden() + { + $this->load->model('ressource/Stunde_model', 'StundeModel'); + + $stunden = $this->StundeModel->load(); + + $stunden = $this->getDataOrTerminateWithError($stunden); + + $this->terminateWithSuccess($stunden); + } + + /** + * fetches room events from a certain date + * @access public + * + * @return void + */ + public function getRoomplan() + { + $this->form_validation->set_rules('ort_kurzbz', "Ort", "required"); + $this->form_validation->set_rules('start_date', "start_date", "required"); + $this->form_validation->set_rules('end_date', "end_date", "required"); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // storing the post parameter in local variables + $ort_kurzbz = $this->input->post('ort_kurzbz', true); + $start_date = $this->input->post('start_date', true); + $end_date = $this->input->post('end_date', true); + + // get data + $this->load->library('StundenplanLib'); + + $roomplan_data = $this->stundenplanlib->getRoomplan($ort_kurzbz, $start_date, $end_date); + + $roomplan_data = $this->getDataOrTerminateWithError($roomplan_data); + + $this->terminateWithSuccess($roomplan_data); + } + + /** + * gets the reservierungen of a room if the ort_kurzbz parameter is + * supplied otherwise gets the reservierungen of the lvplan of a student + * @access public + * + * @param string $ort_kurzbz + * @return void + */ + public function getReservierungen($ort_kurzbz = null) + { + $this->form_validation->set_rules('start_date', "StartDate", "required"); + $this->form_validation->set_rules('end_date', "EndDate", "required"); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // storing the post parameter in local variables + $start_date = $this->input->post('start_date', true); + $end_date = $this->input->post('end_date', true); + + // get data + $this->load->library('StundenplanLib'); + + $result = $this->stundenplanlib->getReservierungen($start_date, $end_date, $ort_kurzbz); + + $result = $this->getDataOrTerminateWithError($result); + + $this->terminateWithSuccess($result); + } + + public function getLehreinheitStudiensemester($lehreinheit_id){ + $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); + $this->LehreinheitModel->addSelect(["studiensemester_kurzbz"]); + $result = $this->LehreinheitModel->load($lehreinheit_id); + $result = current($this->getDataOrTerminateWithError($result))->studiensemester_kurzbz; + $this->terminateWithSuccess($result); + } + + /** + * get details for a lv + * @access public + * + * @param integer $lehrveranstaltung_id + * @return void + */ + public function getLv($lehrveranstaltung_id) + { + if (!$lehrveranstaltung_id && $lehrveranstaltung_id !== 0 && $lehrveranstaltung_id !== '0') + return show_404(); + + // Load Phrases + $this->loadPhrases(['lehre']); + + // Validation + $this->form_validation->set_data([ + 'lehrveranstaltung_id' => $lehrveranstaltung_id + ]); + + $this->form_validation->set_rules('lehrveranstaltung_id', $this->p->t('lehre', 'lehrveranstaltung_id'), 'integer'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // Get Data + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id); + + $result = $this->getDataOrTerminateWithError($result); + + return $this->terminateWithSuccess(current($result)); + } + + /** + * fetch moodle events + * + * @param string $start_date + * @param string $end_date + * @return array + */ + private function fetchMoodleEvents($start_date, $end_date) + { + $this->load->config('calendar'); + + $tz = new DateTimeZone($this->config->item('timezone')); + + $start = new DateTime($start_date); + $start->setTimezone($tz); + + $end = new DateTime($end_date); + $end->setTimezone($tz); + $end->modify('+1 day -1 second'); + + $moodle_events = []; + + Events::trigger( + 'moodleCalendarEvents', + function & () use (&$moodle_events) { + return $moodle_events; + }, + [ + 'start_date' => $start->format('c'), + 'end_date' => $end->format('c'), + 'username' => getAuthUID() + ] + ); + + return $moodle_events; + } + + /** + * fetch ferien events + * + * @param string $start_date + * @param string $end_date + * @return array + */ + private function fetchFerienEvents($start_date, $end_date) + { + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $this->load->model('education/Studentlehrverband_model', 'StudentLehrverbandModel'); + + $currentStudiensemester = $this->StudiensemesterModel->getByDate($start_date); + $currentStudiensemester = $this->getDataOrTerminateWithError($currentStudiensemester); + + if ($currentStudiensemester) { + $studentsemester_kurzbz = current($currentStudiensemester)->studiensemester_kurzbz; + + $studiengang = $this->StudentLehrverbandModel->loadWhere([ + "student_uid" => getAuthUID(), + "studiensemester_kurzbz" => $studentsemester_kurzbz + ]); + $studiengang = $this->getDataOrTerminateWithError($studiengang); + + if ($studiengang) + $studiengang_kz = current($studiengang)->studiengang_kz; + else + $studiengang_kz = 0; + } else { + $studiengang_kz = 0; + } + + $ferienEvents = $this->stundenplanlib->fetchFerienTageEvents($start_date, $end_date, $studiengang_kz); + + return $this->getDataOrTerminateWithError($ferienEvents); + } +} diff --git a/application/controllers/api/frontend/v1/Ort.php b/application/controllers/api/frontend/v1/Ort.php index 8c4059824..0d8074fa9 100644 --- a/application/controllers/api/frontend/v1/Ort.php +++ b/application/controllers/api/frontend/v1/Ort.php @@ -35,15 +35,98 @@ class Ort extends FHCAPI_Controller parent::__construct([ 'ContentID' => self::PERM_LOGGED, 'getOrtKurzbzContent' => self::PERM_LOGGED, + 'getRooms' => self::PERM_LOGGED, + 'getTypes' => self::PERM_LOGGED ]); $this->load->model('ressource/Ort_model', 'OrtModel'); - + $this->config->load('raumsuche'); } //------------------------------------------------------------------------------------------------------------------ // Public methods + /** + * Retrieves all Ort entries filtered by the provided parameters + */ + public function getRooms() + { + $this->load->library('form_validation'); + $this->form_validation->set_data($_GET); + $this->form_validation->set_rules('datum','Datum','required'); + $this->form_validation->set_rules('von','Uhrzeit Von','required|regex_match[/^[0-9]{2}:[0-9]{2}$/]'); + $this->form_validation->set_rules('bis','Uhrzeit Bis','required|regex_match[/^[0-9]{2}:[0-9]{2}$/]'); + if($this->form_validation->run() == FALSE) { + $this->terminateWithValidationErrors($this->form_validation->error_array()); + } + + $datum = $this->input->get('datum', TRUE); + $von = $this->input->get('von', TRUE); + $bis = $this->input->get('bis', TRUE); + $typ = $this->input->get('typ', TRUE); + $personenanzahl = $this->input->get('personenanzahl', TRUE); + + + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID())->retval; + + $this->load->model('ressource/Stunde_model', 'StundeModel'); + $vonStunde = getData($this->StundeModel->getStundeForTime($von))[0]->stunde; + $bisStunde = getData($this->StundeModel->getStundeForTime($bis))[0]->stunde; + + $params = array(); + $qry = "SELECT DISTINCT tbl_ort.* + FROM public.tbl_ort JOIN public.tbl_ortraumtyp USING(ort_kurzbz) + WHERE aktiv AND lehre AND ort_kurzbz NOT LIKE '\\\\_%'"; + if($typ) { + $params[] = $typ; + $qry.= "AND raumtyp_kurzbz = ?"; + } + + if(!$isMitarbeiter) { // students are only allowed to get a subset defined by config + $qry.= ' AND raumtyp_kurzbz IN ?'; + $params[] = $this->config->item('roomtypes_student'); + $this->addMeta('config', $this->config->item('roomtypes_student')); + } + + $qry.= "AND (max_person>= ? OR max_person is null)"; + $params[] = $personenanzahl; + + $qry.=" AND ort_kurzbz NOT IN + ( + SELECT ort_kurzbz FROM lehre.tbl_stundenplandev WHERE datum = ? AND stunde >= ? AND stunde <= ? + UNION + SELECT ort_kurzbz FROM campus.tbl_reservierung WHERE datum= ? AND stunde >= ? AND stunde <= ? + ) + "; + $params = array_merge($params, [$datum, $vonStunde, $bisStunde, $datum, $vonStunde, $bisStunde]); +// $this->addMeta('qry', $qry); +// $this->addMeta('params', $params); + $result = $this->OrtModel->execReadOnlyQuery($qry, $params); + + $this->terminateWithSuccess($result); + } + + public function getTypes() + { + $this->load->model('ressource/Raumtyp_model', 'RaumtypModel'); + $qry = "SELECT * FROM public.tbl_raumtyp WHERE aktiv = true"; + $params = array(); + $this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + + $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID())->retval; + if(!$isMitarbeiter) { // students are only allowed to get a subset defined by config + $qry.= ' AND raumtyp_kurzbz IN ?'; + $params[] = $this->config->item('roomtypes_student'); + } + + $qry .= " ORDER BY raumtyp_kurzbz;"; + + $result = $this->OrtModel->execReadOnlyQuery($qry, $params); + + $this->terminateWithSuccess(getData($result)); + } + /** * Gets a JSON body via HTTP POST and provides the parameters */ diff --git a/application/controllers/api/frontend/v1/Profil.php b/application/controllers/api/frontend/v1/Profil.php index c52d8bae5..3133b107a 100644 --- a/application/controllers/api/frontend/v1/Profil.php +++ b/application/controllers/api/frontend/v1/Profil.php @@ -27,27 +27,17 @@ class Profil extends FHCAPI_Controller public function __construct() { parent::__construct([ - 'getView' => self::PERM_LOGGED, 'fotoSperre' => self::PERM_LOGGED, 'getGemeinden' => self::PERM_LOGGED, 'getAllNationen' => self::PERM_LOGGED, 'isMitarbeiter' => self::PERM_LOGGED, - + 'profilViewData' => self::PERM_LOGGED, ]); $this->load->library('PermissionLib'); $this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel'); - $this->load->model('crm/Student_model', 'StudentModel'); - $this->load->model('person/Benutzer_model', 'BenutzerModel'); $this->load->model('person/Person_model', 'PersonModel'); - $this->load->model('person/Adresse_model', 'AdresseModel'); - $this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel'); - $this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel'); - $this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel'); - $this->load->model('person/Kontakt_model', 'KontaktModel'); - $this->load->model('person/Profil_update_model', 'ProfilUpdateModel'); - $this->load->model('content/DmsVersion_model', 'DmsVersionModel'); //? put the uid and pid inside the controller for reusability @@ -58,66 +48,25 @@ class Profil extends FHCAPI_Controller //------------------------------------------------------------------------------------------------------------------ // Public methods - - - /** - * function that returns the data used for the corresponding view - * the client side parses the @param $uid and calls this function to get the data to the correct view - * @access public - * @param boolean $uid the userID used to identify which information should be retrieved for which view - * @return stdClass all the data corresponding to a view of a user - */ - public function getView($uid) - { - $res = new stdClass(); - $editAllowed = getAuthUID() == $uid || $this->permissionlib->isBerechtigt('admin'); - - // if parsing the URL did not found a UID then the UID of the logged in user is used - if ($uid == "Profil" || $uid == $this->uid) { - $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($this->uid); - if (isError($isMitarbeiter)) { - show_error("error while checking if UID: " . $this->uid . " is a mitarbeiter"); + public function profilViewData($uid=null){ + $this->load->library('ProfilLib'); + $editable = false; + if(isset($uid) && $uid != null){ + $profil_data = $this->profillib->getView($uid); + if($uid == getAuthUID()){ + $editable = true; } - $isMitarbeiter = getData($isMitarbeiter); - if ($isMitarbeiter) { - $res->view = "MitarbeiterProfil"; - $res->data = $this->mitarbeiterProfil(); - $res->data->pid = $this->pid; - } else { - $res->view = "StudentProfil"; - $res->data = $this->studentProfil(); - $res->data->pid = $this->pid; - } - // editing your own profil - true - $editAllowed = true; + }else{ + $editable = true; + $profil_data = $this->profillib->getView(getAuthUID()); } - // UID is availabe when accessing Profil/View/:uid - else { - $this->PersonModel->addSelect(["person_id"]); - $pid = $this->PersonModel->getByUid($uid); - if (isError($pid)) { - show_error("error while trying to update table public.tbl_person while searching for a person with UID: " . $uid); - } - $pid = hasData($pid) ? getData($pid)[0] : null; - if (!$pid) { - show_error("Person with UID: " . $uid . " does not exist"); - } - $isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid); - if (isError($isMitarbeiter)) { - show_error("error while checking if UID: " . $uid . " is a mitarbeiter"); - } - $isMitarbeiter = getData($isMitarbeiter); - if ($isMitarbeiter) { - $res->view = "ViewMitarbeiterProfil"; - $res->data = $this->viewMitarbeiterProfil($uid); - - } else { - $res->view = "ViewStudentProfil"; - $res->data = $this->viewStudentProfil($uid); - } - } - $res->data->editAllowed = $editAllowed; - $this->terminateWithSuccess($res); + + $profil_data = hasData($profil_data) ? getData($profil_data) : null; + $viewData = array( + 'editable'=>$editable, + 'profil_data' => $profil_data, + ); + $this->terminateWithSuccess($viewData); } /** @@ -134,14 +83,11 @@ class Profil extends FHCAPI_Controller $res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]); if (isError($res)) { - show_error("error while trying to update table public.tbl_person"); + $this->terminateWithError("error while trying to update table public.tbl_person"); } $this->PersonModel->addSelect("foto_sperre"); $res = $this->PersonModel->load($this->pid); - if (isError($res)) { - show_error("error while trying to query table public.tbl_person"); - } - + $res = $this->getDataOrTerminateWithError($res); $this->terminateWithSuccess(current($res)); @@ -194,91 +140,7 @@ class Profil extends FHCAPI_Controller } - - // ----------------------------------------------------------------------------------------------------------------- - // Private methods - - /** - * function that returns the data used for viewing another mitarbeiter profile - * @access private - * @param integer $uid the userID to retrieve the mitarbeiter data - * @return stdClass restricted mitarbeiter data - */ - private function viewMitarbeiterProfil($uid) - { - $mailverteiler_res = $this->getMailverteiler($uid); - $benutzer_funktion_res = $this->getBenutzerFunktion($uid); - $benutzer_res = $this->getBenutzerAlias($uid); - $person_res = $this->getPersonInfo($uid); - $mitarbeiter_res = $this->getMitarbeiterInfo($uid); - $telefon_res = $this->getTelefonInfo($uid); - - $res = new stdClass(); - $res->username = $uid; - - //? Person Info - foreach ($person_res as $key => $val) { - $res->$key = $val; - } - - //? Mitarbeiter Info - foreach ($mitarbeiter_res as $key => $val) { - $res->$key = $val; - - } - - $intern_email = array(); - $intern_email["type"] = "intern"; - $intern_email["email"] = $uid . "@" . DOMAIN; - $extern_email = array(); - $extern_email["type"] = "alias"; - $extern_email["email"] = $benutzer_res->alias . "@" . DOMAIN; - $res->emails = array($intern_email, $extern_email); - - $res->funktionen = $benutzer_funktion_res; - $res->mailverteiler = $mailverteiler_res; - $res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null; - - return $res; - } - - /** - * function that returns the data used for viewing another student profile - * @access private - * @param integer $uid the userID to retrieve the student data - * @return stdClass restricted student data - */ - private function viewStudentProfil($uid) - { - $mailverteiler_res = $this->getMailverteiler($uid); - $person_res = $this->getPersonInfo($uid); - $student_res = $this->getStudentInfo($uid); - $matr_res = $this->getMatrikelNummer($uid); - - $res = new stdClass(); - $res->username = $uid; - - //? Person Information - foreach ($person_res as $key => $value) { - $res->$key = $value; - } - - //? Student Information - foreach ($student_res as $key => $value) { - $res->$key = $value; - } - - $intern_email = array(); - $intern_email["type"] = "intern"; - $intern_email["email"] = $uid . "@" . DOMAIN; - - $res->emails = [$intern_email]; - $res->matrikelnummer = $matr_res->matr_nr; - $res->mailverteiler = $mailverteiler_res; - - return $res; - } - + /** * checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php) * @access public @@ -302,394 +164,9 @@ class Profil extends FHCAPI_Controller $this->terminateWithSuccess($result); } - /** - * function that returns the data used for the mitarbeiter profile - * @access private - * @return stdClass mitarbeiter data - */ - private function mitarbeiterProfil() - { + // ----------------------------------------------------------------------------------------------------------------- + // Private methods - $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid); - $adresse_res = $this->getAdressenInfo($this->pid); - $kontakte_res = $this->getKontaktInfo($this->pid); - $mailverteiler_res = $this->getMailverteiler($this->uid); - $person_res = $this->getPersonInfo($this->uid, true); - $benutzer_funktion_res = $this->getBenutzerFunktion($this->uid); - $betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid); - $profilUpdates = $this->getProfilUpdates($this->uid); - $telefon_res = $this->getTelefonInfo($this->uid); - $mitarbeiter_res = $this->getMitarbeiterInfo($this->uid); - - $res = new stdClass(); - $res->username = $this->uid; - - //? Person Information - foreach ($person_res as $key => $value) { - $res->$key = $value; - } - - //? Mitarbeiter Information - foreach ($mitarbeiter_res as $key => $value) { - $res->$key = $value; - } - - $res->adressen = $adresse_res; - $res->zutrittsdatum = $zutrittskarte_ausgegebenam; - $res->kontakte = $kontakte_res; - $res->mittel = $betriebsmittelperson_res; - $res->mailverteiler = $mailverteiler_res; - - $intern_email = array(); - $intern_email["type"] = "intern"; - $intern_email["email"] = $this->uid . "@" . DOMAIN; - $extern_email = array(); - $extern_email["type"] = "alias"; - $extern_email["email"] = $mitarbeiter_res->alias . "@" . DOMAIN; - $res->emails = [$intern_email, $extern_email]; - - $res->funktionen = $benutzer_funktion_res; - $res->standort_telefon = $telefon_res; - $res->profilUpdates = $profilUpdates; - - return $res; - } - - /** - * function that returns the data used for the student profile - * @access private - * @return stdClass student data - */ - private function studentProfil() - { - $betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid); - $kontakte_res = $this->getKontaktInfo($this->pid); - $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid); - $adresse_res = $this->getAdressenInfo($this->pid); - $mailverteiler_res = $this->getMailverteiler($this->uid); - $person_res = $this->getPersonInfo($this->uid, true); - $zutrittsgruppe_res = $this->getZutrittsgruppen($this->uid); - $student_res = $this->getStudentInfo($this->uid); - $matr_res = $this->getMatrikelNummer($this->uid); - $profilUpdates = $this->getProfilUpdates($this->uid); - - $res = new stdClass(); - $res->username = $this->uid; - - //? Person Information - foreach ($person_res as $key => $value) { - $res->$key = $value; - } - - //? Student Information - foreach ($student_res as $key => $value) { - $res->$key = trim($value); - } - - $intern_email = array(); - $intern_email["type"] = "intern"; - $intern_email["email"] = $this->uid . "@" . DOMAIN; - - $res->emails = [$intern_email]; - $res->adressen = $adresse_res; - $res->zutrittsdatum = $zutrittskarte_ausgegebenam; - $res->kontakte = $kontakte_res; - $res->mittel = $betriebsmittelperson_res; - $res->matrikelnummer = $matr_res->matr_nr; - $res->zuttritsgruppen = $zutrittsgruppe_res; - $res->mailverteiler = $mailverteiler_res; - $res->profilUpdates = $profilUpdates; - - return $res; - } - - - /** - * gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe - * @access private - * @param integer $uid the userID used to retrieve the mailverteiler - * @return array returns the mailvertailer corresponding to a userID - */ - private function getMailverteiler($uid) - { - $this->PersonModel->addSelect('gruppe_kurzbz, beschreibung'); - $this->PersonModel->addJoin('tbl_benutzer', 'person_id'); - $this->PersonModel->addJoin('tbl_benutzergruppe', 'uid'); - $this->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); - - $mailverteiler_res = $this->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid)); - if (isError($mailverteiler_res)) { - show_error("was not able to query the table public.tbl_benutzer:" . getData($mailverteiler_res)); - } - $mailverteiler_res = hasData($mailverteiler_res) ? getData($mailverteiler_res) : null; - $mailverteiler_res = array_map(function ($element) { - $element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN; - return $element; - }, $mailverteiler_res); - return $mailverteiler_res; - } - - /** - * gets all the Benutzerfunktionen of a corresponding user - * @access private - * @param integer $uid the userID used to retrieve the Benutzerfunktionen - * @return array returns the Benutzerfunktionen corresponding to a userID - */ - private function getBenutzerFunktion($uid) - { - $this->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]); - $this->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz"); - - $benutzer_funktion_res = $this->BenutzerfunktionModel->loadWhere(array('uid' => $uid)); - if (isError($benutzer_funktion_res)) { - show_error("was not able to query the table public.tbl_benutzerfunktion:" . getData($benutzer_funktion_res)); - } - $benutzer_funktion_res = hasData($benutzer_funktion_res) ? getData($benutzer_funktion_res) : null; - return $benutzer_funktion_res; - } - - /** - * gets all the Betriebsmittel of a corresponding user - * @access private - * @param integer $uid the userID used to retrieve the Betriebsmittel - * @return array returns the Betriebsmittel corresponding to a userID - */ - private function getBetriebsmittelInfo($pid) - { - $this->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]); - - //? betriebsmittel are not needed in a view - $betriebsmittelperson_res = $this->BetriebsmittelpersonModel->getBetriebsmittel($pid); - if (isError($betriebsmittelperson_res)) { - show_error("was not able to query the table public.tbl_betriebsmittelperson:" . getData($betriebsmittelperson_res)); - } - $betriebsmittelperson_res = hasData($betriebsmittelperson_res) ? getData($betriebsmittelperson_res) : null; - return $betriebsmittelperson_res; - } - - /** - * gets the alias of a corresponding user - * @access private - * @param integer $uid the userID used to get the alias - * @return string the alias of the userID - */ - private function getBenutzerAlias($uid) - { - $this->BenutzerModel->addSelect(["alias"]); - $benutzer_res = $this->BenutzerModel->load([$uid]); - if (isError($benutzer_res)) { - show_error("was not able to query the table public.tbl_benutzer:" . getData($benutzer_res)); - } else { - $benutzer_res = hasData($benutzer_res) ? getData($benutzer_res)[0] : null; - } - - return $benutzer_res; - } - - /** - * gets the person information corresponding to a user - * @access private - * @param integer $uid the userID used to get the person information - * @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not - * @return array all the person informaion corresponding to a userID - */ - private function getPersonInfo($uid, $geburtsInfo = null) - { - $selectClause = ["foto", "foto_sperre", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"]; - /** @param integer $geburtsInfo */ - if ($geburtsInfo) { - array_push($selectClause, "gebort"); - array_push($selectClause, "TO_CHAR(gebdatum, 'DD.MM.YYYY') as gebdatum"); - } - $this->BenutzerModel->addSelect($selectClause); - $this->BenutzerModel->addJoin("tbl_person", "person_id"); - - $person_res = $this->BenutzerModel->load([$uid]); - if (isError($person_res)) { - show_error("was not able to query the table public.tbl_benutzer:" . getData($person_res)); - } else { - $person_res = hasData($person_res) ? getData($person_res)[0] : null; - } - - if( ($person_res->foto === null) || (($this->uid !== $uid) && ($person_res->foto_sperre !== false)) ) - { - $dummy_foto = base64_encode(file_get_contents(DOC_ROOT.'skin/images/profilbild_dummy.jpg')); - $person_res->foto = $dummy_foto; - } - - return $person_res; - } - - /** - * gets the mitarbeiter information corresponding to a user - * @access private - * @param integer $uid the userID used to get the mitarbeiter information - * @return array all the mitarbeiter informaion corresponding to a userID - */ - private function getMitarbeiterInfo($uid) - { - $this->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]); - $this->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid"); - $mitarbeiter_res = $this->MitarbeiterModel->load($uid); - if (isError($mitarbeiter_res)) { - show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($mitarbeiter_res)); - } else { - $mitarbeiter_res = hasData($mitarbeiter_res) ? getData($mitarbeiter_res)[0] : null; - } - - return $mitarbeiter_res; - } - - /** - * gets the telefon information corresponding to a user - * @access private - * @param integer $uid the userID used to get the telefon information - * @return array all the telefon informaion corresponding to a userID - */ - private function getTelefonInfo($uid) - { - $this->MitarbeiterModel->addSelect(["kontakt"]); - $this->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id"); - $this->MitarbeiterModel->addLimit(1); - $telefon_res = $this->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]); - if (isError($telefon_res)) { - show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($telefon_res)); - } - $telefon_res = hasData($telefon_res) ? getData($telefon_res)[0] : null; - return $telefon_res; - } - - /** - * gets the student information corresponding to a user - * @access private - * @param integer $uid the userID used to get the student information - * @return array all the student informaion corresponding to a userID - */ - private function getStudentInfo($uid) - { - $this->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_studiengang.studiengang_kz as studiengang_kz', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']); - $this->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz"); - - $student_res = $this->StudentModel->load([$uid]); - if (isError($student_res)) { - show_error("was not able to query the table public.tbl_student:" . getData($student_res)); - } - $student_res = hasData($student_res) ? getData($student_res)[0] : null; - return $student_res; - } - - /** - * gets the profil updates corresponding to a user - * @access private - * @param integer $uid the userID used to get the profil updates - * @return array all the profil updates corresponding to a userID - */ - private function getProfilUpdates($uid) - { - $profilUpdates = $this->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]); - if (isError($profilUpdates)) { - show_error("was not able to query the table public.tbl_profil_update:" . getData($profilUpdates)); - } - $profilUpdates = hasData($profilUpdates) ? getData($profilUpdates) : null; - return $profilUpdates; - } - - /** - * gets the Matrikelnummer corresponding to a user - * @access private - * @param integer $uid the userID used to get the Matrikelnummer - * @return integer the Matrikelnummer corresponding to a userID - */ - private function getMatrikelNummer($uid) - { - $this->BenutzerModel->addSelect(["matr_nr"]); - $this->BenutzerModel->addJoin("tbl_person", "person_id"); - - $matr_res = $this->BenutzerModel->load([$uid]); - if (isError($matr_res)) { - show_error("was not able to query the table public.tbl_benutzer:" . getData($matr_res)); - } - $matr_res = hasData($matr_res) ? getData($matr_res)[0] : []; - return $matr_res; - } - - /** - * gets the Zutrittsgruppen corresponding to a user - * @access private - * @param integer $uid the userID used to get the Zutrittsgruppen - * @return array all the Zutrittsgruppen corresponding to a userID - */ - private function getZutrittsgruppen($uid) - { - $this->BenutzergruppeModel->addSelect(['bezeichnung']); - $this->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); - - $zutrittsgruppe_res = $this->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true)); - if (isError($zutrittsgruppe_res)) { - show_error("was not able to query the table public.tbl_benutzergruppe:" . getData($zutrittsgruppe_res)); - } - $zutrittsgruppe_res = hasData($zutrittsgruppe_res) ? getData($zutrittsgruppe_res) : null; - return $zutrittsgruppe_res; - } - - /** - * gets the address information corresponding to a user - * @access private - * @param integer $uid the userID used to get the address information - * @return array all the address information corresponding to a userID - */ - private function getAdressenInfo($pid) - { - $adresse_res = $this->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]); - $adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC"); - $adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz"); - - $adresse_res = $this->AdresseModel->loadWhere(["person_id" => $pid]); - if (isError($adresse_res)) { - show_error("was not able to query the table public.tbl_adresse:" . getData($adresse_res)); - } - $adresse_res = hasData($adresse_res) ? getData($adresse_res) : null; - return $adresse_res; - } - - /** - * gets the kontakt information corresponding to a user - * @access private - * @param integer $uid the userID used to get the kontakt information - * @return array all the kontakt information corresponding to a userID - */ - private function getKontaktInfo($pid) - { - $this->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']); - $this->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT'); - $this->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT'); - $this->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum'); - - $kontakte_res = $this->KontaktModel->loadWhere(['person_id' => $pid]); - if (isError($kontakte_res)) { - show_error("was not able to query the table public.tbl_kontakt:" . getData($kontakte_res)); - } - $kontakte_res = hasData($kontakte_res) ? getData($kontakte_res) : null; - return $kontakte_res; - } - - /** - * gets the date of issue of the FH access card corresponding to a user - * @access private - * @param integer $uid the userID used to get the date of issue of the FH access card - * @return string the date of issue of the FH access card corresponding to a userID - */ - private function getZutrittskarteDatum($uid) - { - $zutrittskarte_ausgegebenam = $this->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte"); - if (isError($zutrittskarte_ausgegebenam)) { - show_error("was not able to query the table wavi.tbl_bentriebsmittelperson:" . getData($zutrittskarte_ausgegebenam)); - } - $zutrittskarte_ausgegebenam = hasData($zutrittskarte_ausgegebenam) ? getData($zutrittskarte_ausgegebenam)[0]->ausgegebenam : null; - - //? formats date from 01-01-2000 to 01.01.2000 - $zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam); - return $zutrittskarte_ausgegebenam; - } + } diff --git a/application/controllers/api/frontend/v1/ProfilUpdate.php b/application/controllers/api/frontend/v1/ProfilUpdate.php index 827654d21..929ea49d6 100644 --- a/application/controllers/api/frontend/v1/ProfilUpdate.php +++ b/application/controllers/api/frontend/v1/ProfilUpdate.php @@ -44,6 +44,7 @@ class ProfilUpdate extends FHCAPI_Controller 'updateProfilRequest' => self::PERM_LOGGED, 'deleteProfilRequest' => self::PERM_LOGGED, 'insertFile' => self::PERM_LOGGED, + 'updateProfilbild' => self::PERM_LOGGED, 'show' => self::PERM_LOGGED, ]); @@ -478,6 +479,96 @@ class ProfilUpdate extends FHCAPI_Controller $this->terminateWithSuccess($res); } + public function updateProfilbild() + { + + $resize = function($filename, $width, $height){ + // Hoehe und Breite neu berechnen + list($width_orig, $height_orig) = getimagesize($filename); + + if ($width && ($width_orig < $height_orig)) + { + $width = ($height / $height_orig) * $width_orig; + } + else + { + $height = ($width / $width_orig) * $height_orig; + } + + $image_p = imagecreatetruecolor($width, $height); + + $image = imagecreatefromjpeg($filename); + + //Bild nur verkleinern aber nicht vergroessern + if($width_orig>$width || $height_orig>$height) + imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); + else + $image_p = $image; + + imagejpeg($image_p, $filename, 80); + + @imagedestroy($image_p); + @imagedestroy($image); + }; + + if (!count($_FILES)) { + $this->terminateWithError("No file available for upload"); + } + + $files = $_FILES['files']; + + $_FILES['files']['name'] = current($files['name']); + $_FILES['files']['type'] = current($files['type']); + $_FILES['files']['tmp_name'] = current($files['tmp_name']); + $_FILES['files']['error'] = current($files['error']); + $_FILES['files']['size'] = current($files['size']); + $_FILES['files']['tmp_name'] = current($files['tmp_name']); + + $filename = $_FILES['files']['tmp_name']; + + $ext = substr(current($files['name']), strrpos(current($files['name']), '.') + 1); + if($ext!='jpg' && $ext!='jpeg'){ + $this->terminateWithError("Only jpg and jpeg files are allowed for profilbild upload"); + } + + // resize + $resize($filename, 827, 1063); + + //akte + $fp = fopen($filename,'r'); + //auslesen + $content = fread($fp, filesize($filename)); + $base64_content = base64_encode($content); + $this->load->library('AkteLib'); + $aktenInsertResult = $this->aktelib->add($this->pid,'Lichtbil',"Lichtbild_".$this->pid.".jpg","image/jpg",$fp,"Lichtbild gross"); + fclose($fp); + if (isError($aktenInsertResult)) { + $this->terminateWithError(getError($aktenInsertResult)); + } + + // in person abspeichern + $resize($filename, 101, 130); + $fp = fopen($filename,'r'); + $content = fread($fp, filesize($filename)); + fclose($fp); + $base64_content = base64_encode($content); + $this->load->model('person/Person_model','PersonModel'); + $personUpdate = $this->PersonModel->update($this->pid, ["foto"=>$base64_content]); + if(isError($personUpdate)){ + $this->terminateWithError(getError($personUpdate)); + } + + + // update foto status + $this->load->model('person/Fotostatusperson_model','FotostatusModel'); + $fotoInsert = $this->FotostatusModel->insert(["person_id"=>$this->pid,"fotostatus_kurzbz"=>"hochgeladen","datum"=>date('Y-m-d'),"insertamum"=>date('Y-m-d H:i:s'),"insertvon"=>$this->uid,"updateamum"=>date('Y-m-d H:i:s'),"updatevon"=>$this->uid]); + if(isError($fotoInsert)){ + $this->terminateWithError(getError($fotoInsert)); + } + + $this->terminateWithSuccess(); + } + public function getProfilUpdateWithPermission($status = null) { // early return if no status has been passed as argument diff --git a/application/controllers/api/frontend/v1/RendererLoader.php b/application/controllers/api/frontend/v1/RendererLoader.php new file mode 100644 index 000000000..dc16bb3fc --- /dev/null +++ b/application/controllers/api/frontend/v1/RendererLoader.php @@ -0,0 +1,72 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use CI3_Events as Events; + +class RendererLoader extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + + parent::__construct([ + 'GetRenderers' => self::PERM_LOGGED, + + ]); + + $this->load->library('LogLib'); + $this->loglib->setConfigs(array( + 'classIndex' => 5, + 'functionIndex' => 5, + 'lineIndex' => 4, + 'dbLogType' => 'API', // required + 'dbExecuteUser' => 'RESTful API' + )); + + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * fetches Stundenplan and Moodle events together + * @access public + * + */ + public function GetRenderers(){ + $renderer_paths = []; + Events::trigger( + 'loadRenderers', + function & () use (&$renderer_paths) + { + return $renderer_paths; + } + ); + $this->terminateWithSuccess($renderer_paths); + } + + + + +} diff --git a/application/controllers/api/frontend/v1/Searchbar.php b/application/controllers/api/frontend/v1/Searchbar.php index 8b383e042..363b6e534 100644 --- a/application/controllers/api/frontend/v1/Searchbar.php +++ b/application/controllers/api/frontend/v1/Searchbar.php @@ -35,11 +35,10 @@ class Searchbar extends FHCAPI_Controller { // NOTE(chris): additional permission checks will be done in SearchBarLib parent::__construct([ - 'search' => self::PERM_LOGGED + 'search' => self::PERM_LOGGED, + 'searchCis' => self::PERM_LOGGED, + 'searchStv' => self::PERM_LOGGED ]); - - // Load the library SearchBarLib - $this->load->library('SearchBarLib'); } //------------------------------------------------------------------------------------------------------------------ @@ -50,6 +49,7 @@ class Searchbar extends FHCAPI_Controller */ public function search() { + $this->load->library('SearchBarLib'); $this->load->library('form_validation'); // Checks if the searchstr and the types parameters are in the POSTed JSON @@ -63,7 +63,53 @@ class Searchbar extends FHCAPI_Controller $result = $this->searchbarlib->search($this->input->post(self::SEARCHSTR_PARAM), $this->input->post(self::TYPES_PARAM)); if (property_exists($result, 'error')) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - $this->terminateWithSuccess($result); + + $this->addMeta('mode', 'simple'); + + $this->terminateWithSuccess($result->data); + } + + /** + * Gets a JSON body via HTTP POST and provides the parameters + */ + public function searchCis() + { + return $this->searchAdvanced([ 'config' => 'searchcis' ]); + } + + /** + * Gets a JSON body via HTTP POST and provides the parameters + */ + public function searchStv() + { + return $this->searchAdvanced([ 'config' => 'searchstv' ]); + } + + /** + * Gets a JSON body via HTTP POST and provides the parameters + */ + private function searchAdvanced($config) + { + $this->load->library('SearchLib', $config); + $this->load->library('form_validation'); + + // Checks if the searchstr and the types parameters are in the POSTed JSON + $this->form_validation->set_rules(self::SEARCHSTR_PARAM, null, 'required'); + $this->form_validation->set_rules(self::TYPES_PARAM . '[]', null, 'required'); + + if (!$this->form_validation->run()) + $this->terminateWithValidationErrors($this->form_validation->error_array()); + + // Convert to json the result from searchlib->search + $result = $this->searchlib->search($this->input->post(self::SEARCHSTR_PARAM), $this->input->post(self::TYPES_PARAM)); + + $data = $this->getDataOrTerminateWithError($result); + + $this->addMeta('time', $result->meta['time']); + $this->addMeta('searchstring', $result->meta['searchstring']); + $this->addMeta('mode', 'advanced'); + + $this->terminateWithSuccess($data); } } diff --git a/application/controllers/api/frontend/v1/Studium.php b/application/controllers/api/frontend/v1/Studium.php new file mode 100644 index 000000000..d17f0c1a1 --- /dev/null +++ b/application/controllers/api/frontend/v1/Studium.php @@ -0,0 +1,329 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use CI3_Events as Events; + +class Studium extends FHCAPI_Controller +{ + + /** + * Object initialization + */ + public function __construct() + { + parent::__construct([ + 'getStudienAllSemester'=> self::PERM_LOGGED, + 'getStudiengaengeForStudienSemester'=> self::PERM_LOGGED, + 'getStudienplaeneBySemester'=> self::PERM_LOGGED, + 'getLvEvaluierungInfo'=> self::PERM_LOGGED, + ]); + + $this->load->model('crm/Student_model', 'StudentModel'); + $this->load->model('organisation/Studiengang_model', 'StudiengangModel'); + $this->load->model('organisation/Studienordnung_model','StudienordnungModel'); + $this->load->model('organisation/Studiensemester_model',"StudiensemesterModel"); + $this->load->model('organisation/Studienplan_model', 'StudienplanModel'); + $this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel'); + $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); + $this->load->model('codex/Orgform_model','OrgformModel'); + $this->load->model('person/Person_model','PersonModel'); + + + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + public function getStudienAllSemester(){ + + $parameter_studiensemester = $this->input->get('studiensemester',true); + $parameter_studiengang = $this->input->get('studiengang',true); + $parameter_semester = $this->input->get('semester',true); + $parameter_studienplan = $this->input->get('studienplan',true); + + $aktuelles_studiensemester = current($this->getDataOrTerminateWithError($this->StudiensemesterModel->getAktOrNextSemester())); + + if($this->getDataOrTerminateWithError($this->StudentModel->isStudent(getAuthUID()))){ + $studentLehrverband =$this->StudentlehrverbandModel->loadWhere(["student_uid" => getAuthUID(), "studiensemester_kurzbz" => $aktuelles_studiensemester->studiensemester_kurzbz]); + $studentLehrverband = current($this->getDataOrTerminateWithError($studentLehrverband)); + + $student_studiensemester = $studentLehrverband->studiensemester_kurzbz; + $student_studiengang = $studentLehrverband->studiengang_kz; + $student_semester = $studentLehrverband->semester; + $student_studienplan = $this->getStudienPlanFromPrestudentStatus(getAuthPersonId())->studienplan_id; + + if(!isset($parameter_studiensemester)) + $parameter_studiensemester = $student_studiensemester; + if(!isset($parameter_studiengang)) + $parameter_studiengang = $student_studiengang; + if(!isset($parameter_semester)) + $parameter_semester = $student_semester; + if(!isset($parameter_studienplan)) + $parameter_studienplan = $student_studienplan; + } + + if(isset($parameter_studiensemester)){ + $parameter_studiensemester = current($this->getDataOrTerminateWithError($this->StudiensemesterModel->loadWhere(["studiensemester_kurzbz" => $parameter_studiensemester]))); + } + + if(isset($parameter_studiengang)){ + $parameter_studiengang = current($this->getDataOrTerminateWithError($this->StudiengangModel->loadWhere(["studiengang_kz" => $parameter_studiengang]))); + } + + if(isset($parameter_studienplan)){ + $this->StudienplanModel->addJoin("lehre.tbl_studienordnung", "studienordnung_id"); + $this->StudienplanModel->addJoin("lehre.tbl_studienplan_semester", "studienplan_id"); + $parameter_studienplan = $this->StudienplanModel->loadWhere(["studienplan_id" => $parameter_studienplan, "aktiv" => TRUE]); + $parameter_studienplan = current($this->getDataOrTerminateWithError($parameter_studienplan)); + } + + // fetch studiensemester + $allStudienSemester = $this->getDataOrTerminateWithError($this->StudiensemesterModel->load()); + + + if(isset($parameter_studiensemester) && !empty(array_filter($allStudienSemester, function($studiensemester) use($parameter_studiensemester){ + return $studiensemester->studiensemester_kurzbz == $parameter_studiensemester->studiensemester_kurzbz; + }))){ + $aktuelles_studiensemester = $parameter_studiensemester; + } + + // fetch studiengaenge + $studiengaenge = $this->computeStudiengaenge($aktuelles_studiensemester->studiensemester_kurzbz); + $aktuelles_studiengang = current($studiengaenge); + if(!$aktuelles_studiengang){ + $aktuelles_studiengang = null; + } + if(isset($parameter_studiengang) && !empty(array_filter( $studiengaenge,function($studiengang)use($parameter_studiengang){ + return $studiengang->studiengang_kz == $parameter_studiengang->studiengang_kz; + }))){ + $aktuelles_studiengang = $parameter_studiengang; + } + + // compute semester and studienplaene + if($aktuelles_studiengang){ + $studienplaene = $this->computeStudienplaene($aktuelles_studiengang->studiengang_kz, $aktuelles_studiensemester->studiensemester_kurzbz); + }else{ + $studienplaene =[]; + } + + $semester = array_values(array_unique(array_map(function($item){ + return $item->semester; + }, $studienplaene))); + $aktuelles_semester = current($semester); + if(!$aktuelles_semester){ + $aktuelles_semester = null; + } + if(isset($parameter_semester) && in_array($parameter_semester, $semester)){ + $aktuelles_semester = $parameter_semester; + } + + $semester_studienplan = array_filter($studienplaene, function($item) use($aktuelles_semester){ + return $item->semester == $aktuelles_semester; + }); + + // fetch current studienplan based on semester + $aktuelles_studienplan = current($semester_studienplan); + if(!$aktuelles_studienplan){ + $aktuelles_studienplan = null; + } + if(isset($parameter_studienplan) && !empty(array_filter( $semester_studienplan, function($studienplan) use($parameter_studienplan){ + return $studienplan->studienplan_id == $parameter_studienplan->studienplan_id; + }))){ + $aktuelles_studienplan = $parameter_studienplan ; + } + + // fetch studienplan lehrveranstaltungen + if($aktuelles_studienplan){ + $lehrveranstaltungen = $this->computeStudienplanLehrveranstaltungen($aktuelles_studienplan->studienplan_id, $aktuelles_semester); + foreach($lehrveranstaltungen as $lehrv){ + foreach($lehrv->lehrveranstaltungen as $lv){ + $lvLektoren =$this->computeLektorenFromLehrveranstaltung($lv->lehrveranstaltung_id,$aktuelles_semester, $aktuelles_studiengang->studiengang_kz, $aktuelles_studiensemester->studiensemester_kurzbz); + $lv->lektoren = $lvLektoren; + } + + } + $aktuelles_lehrveranstaltungen = $lehrveranstaltungen; + }else{ + $aktuelles_lehrveranstaltungen = []; + } + + // result object + $result = new stdClass(); + $result->studienSemester = []; + $result->studienSemester["all"]= $allStudienSemester; + $result->studienSemester["preselected"]=$aktuelles_studiensemester; + $result->studiengang["all"]=$studiengaenge; + $result->studiengang["preselected"]=$aktuelles_studiengang; + $result->semester["all"] =$semester; + $result->semester["preselected"] =$aktuelles_semester; + $result->studienplan["all"]=$semester_studienplan; + $result->studienplan["preselected"]=$aktuelles_studienplan; + $result->lehrveranstaltungen=$aktuelles_lehrveranstaltungen; + + + $this->terminateWithSuccess($result); + } + + public function getLvEvaluierungInfo($studiensemester_kurzbz, $lehrveranstaltung_id){ + $result = []; + Events::trigger('lvEvaluierungsInfo', function & () use (&$result) { + return $result; + },$lehrveranstaltung_id, $studiensemester_kurzbz); + $this->terminateWithSuccess($result); + } + + public function getStudiengaengeForStudienSemester($studiensemester){ + $studiengaenge = $this->computeStudiengaenge($studiensemester); + $this->terminateWithSuccess($studiengaenge); + } + + public function getStudienplaeneBySemester(){ + $this->load->library('form_validation'); + $this->form_validation->set_data($this->input->get()); + $this->form_validation->set_rules('studiengang', 'studiengang', 'required'); + $this->form_validation->set_rules('studiensemester', 'studiensemester', 'required'); + if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); + + $studiengang = $this->input->get('studiengang',true); + $studiensemester = $this->input->get('studiensemester',true); + $studienplaene = $this->computeStudienplaene($studiengang, $studiensemester); + $this->terminateWithSuccess($studienplaene); + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + private function computeStudienplaene($studiengang, $studiensemester){ + $studienplaene = $this->StudienplanModel->getStudienplaeneBySemester($studiengang, $studiensemester); + $studienplaene = $this->getDataOrTerminateWithError($studienplaene); + $studienplaene = array_map(function($studienplan){ + $orgform = current($this->getDataOrTerminateWithError($this->OrgformModel->loadWhere(["orgform_kurzbz" => $studienplan->orgform_kurzbz]))); + $studienplan->orgform_bezeichnung = $orgform->bezeichnung; + return $studienplan; + },$studienplaene); + return $studienplaene; + } + + private function computeStudienplanLehrveranstaltungen($studienplan_id, $semester){ + +/* +SELECT tbl_lehrveranstaltung.*, + tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id, + tbl_studienplan_lehrveranstaltung.semester as stpllv_semester, + tbl_studienplan_lehrveranstaltung.pflicht as stpllv_pflicht, + tbl_studienplan_lehrveranstaltung.koordinator as stpllv_koordinator, + tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent, + tbl_studienplan_lehrveranstaltung.sort stpllv_sort, + tbl_studienplan_lehrveranstaltung.curriculum, + tbl_studienplan_lehrveranstaltung.export, + tbl_studienplan_lehrveranstaltung.genehmigung + FROM lehre.tbl_lehrveranstaltung + JOIN lehre.tbl_studienplan_lehrveranstaltung + USING(lehrveranstaltung_id) + WHERE tbl_studienplan_lehrveranstaltung.studienplan_id=" . $this->db_add_param($studienplan_id, FHC_INTEGER); + if (defined("CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN") && CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN) + $qry .= " AND tbl_lehrveranstaltung.lehrtyp_kurzbz != 'modul'"; + if (!is_null($semester)) + { + $qry.=" AND tbl_studienplan_lehrveranstaltung.semester=" . $this->db_add_param($semester, FHC_INTEGER); + } */ + $this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $query = " + SELECT tbl_lehrveranstaltung.*, + tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id, + tbl_studienplan_lehrveranstaltung.semester as stpllv_semester, + tbl_studienplan_lehrveranstaltung.pflicht as stpllv_pflicht, + tbl_studienplan_lehrveranstaltung.koordinator as stpllv_koordinator, + tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent, + tbl_studienplan_lehrveranstaltung.sort stpllv_sort, + tbl_studienplan_lehrveranstaltung.curriculum, + tbl_studienplan_lehrveranstaltung.export, + tbl_studienplan_lehrveranstaltung.genehmigung + FROM lehre.tbl_lehrveranstaltung + JOIN lehre.tbl_studienplan_lehrveranstaltung + USING(lehrveranstaltung_id) + WHERE + tbl_lehrveranstaltung.lehre = true AND + tbl_studienplan_lehrveranstaltung.studienplan_id=? AND tbl_studienplan_lehrveranstaltung.semester=?"; + + if (defined("CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN") && CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN) + $query .= " AND tbl_lehrveranstaltung.lehrtyp_kurzbz != 'modul'"; + + $lehrveranstaltungen = $this->LehrveranstaltungModel->execReadOnlyQuery($query,[$studienplan_id, $semester]); + + $lehrveranstaltungen = $this->getDataOrTerminateWithError($lehrveranstaltungen); + usort($lehrveranstaltungen, function($a, $b){ + if($a->lehrtyp_kurzbz == "modul"){ + return -1; + } + else if($b->lehrtyp_kurzbz == "modul"){ + return 1; + } + return 0; + }); + $lehrveranstaltungen= array_reduce($lehrveranstaltungen,function($carry, $lehrv){ + if($lehrv->lehrtyp_kurzbz == "modul"){ + $lehrv->lehrveranstaltungen = []; + array_push($carry, $lehrv); + } + else{ + $parent =array_filter($carry, function($item)use($lehrv){ + return $item->studienplan_lehrveranstaltung_id == $lehrv->studienplan_lehrveranstaltung_id_parent; + }); + $parent = current($parent); + if($parent){ + $parent->lehrveranstaltungen[] = $lehrv; + } + } + return $carry; + }, []); + return $lehrveranstaltungen; + } + + private function computeStudiengaenge($studiensemester){ + $studiengang_studiensemester_result = $this->StudiengangModel->getStudiengaengeByStudiensemester($studiensemester); + $studiengang_studiensemester_result = $this->getDataOrTerminateWithError($studiengang_studiensemester_result); + return $studiengang_studiensemester_result; + } + + private function getStudienPlanFromPrestudentStatus($person_id){ + $studienplan_id = current($this->getDataOrTerminateWithError($this->PrestudentstatusModel->getLastStatusPerson($person_id)))->studienplan_id; + $studienplan =current($this->getDataOrTerminateWithError($this->StudienplanModel->loadWhere(["studienplan_id"=>$studienplan_id]))); + return $studienplan; + } + + private function computeLektorenFromLehrveranstaltung($lehreinheit_id, $semester, $studiengang, $studiensemester){ + $this->load->library('StundenplanLib'); + $lektoren = $this->stundenplanlib->getLektorenFromLehrveranstaltung($lehreinheit_id,$semester, $studiengang,$studiensemester); + $lektoren = $this->getDataOrTerminateWithError($lektoren) ?? []; + + $lektoren = array_map(function($lektor){ + return ["name"=>$this->getDataOrTerminateWithError($this->PersonModel->getFullName($lektor)), "email"=>$lektor."@".DOMAIN]; + },$lektoren); + + return $lektoren; + } + + + + +} + diff --git a/application/controllers/api/frontend/v1/Stundenplan.php b/application/controllers/api/frontend/v1/Stundenplan.php deleted file mode 100644 index 2ec02fea9..000000000 --- a/application/controllers/api/frontend/v1/Stundenplan.php +++ /dev/null @@ -1,618 +0,0 @@ -. - */ - -if (! defined('BASEPATH')) exit('No direct script access allowed'); - -class Stundenplan extends FHCAPI_Controller -{ - - /** - * Object initialization - */ - public function __construct() - { - - parent::__construct([ - 'getRoomplan' => self::PERM_LOGGED, - 'Stunden' => self::PERM_LOGGED, - 'Reservierungen' => self::PERM_LOGGED, - 'getStundenplan' => self::PERM_LOGGED, - 'getLehreinheitStudiensemester' => self::PERM_LOGGED, - 'studiensemesterDateInterval' => self::PERM_LOGGED, - ]); - - $this->load->library('LogLib'); - $this->loglib->setConfigs(array( - 'classIndex' => 5, - 'functionIndex' => 5, - 'lineIndex' => 4, - 'dbLogType' => 'API', // required - 'dbExecuteUser' => 'RESTful API' - )); - - $this->load->library('form_validation'); - - //load models - $this->load->model('ressource/Stundenplan_model', 'StundenplanModel'); - $this->load->model('ressource/Reservierung_model', 'ReservierungModel'); - - - } - - //------------------------------------------------------------------------------------------------------------------ - // Public methods - - //TODO: delete this function if we don't use the old calendar export endpoints anymore - public function studiensemesterDateInterval($date){ - $this->load->model('organisation/Studiensemester_model','StudiensemesterModel'); - $studiensemester =$this->StudiensemesterModel->getByDate(date_format(date_create($date),'Y-m-d')); - $studiensemester =current($this->getDataOrTerminateWithError($studiensemester)); - $this->terminateWithSuccess($studiensemester); - } - - - /** - * fetches Stunden layout from database - * @access public - * - */ - public function Stunden() - { - $this->load->model('ressource/Stunde_model', 'StundeModel'); - - $stunden = $this->StundeModel->load(); - - $stunden = $this->getDataOrTerminateWithError($stunden); - - $this->terminateWithSuccess($stunden); - } - - /** - * fetches room events from a certain date - * @access public - * - */ - public function getRoomplan() - { - // form validation - $this->load->library('form_validation'); - $this->form_validation->set_data($_GET); - $this->form_validation->set_rules('ort_kurzbz',"Ort","required"); - $this->form_validation->set_rules('start_date',"start_date","required"); - $this->form_validation->set_rules('end_date',"end_date","required"); - if($this->form_validation->run() === FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); - - // storing the get parameter in local variables - $ort_kurzbz = $this->input->get('ort_kurzbz', TRUE); - $start_date = $this->input->get('start_date', TRUE); - $end_date = $this->input->get('end_date', TRUE); - - $roomplan_data = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getRoomQuery($ort_kurzbz, $start_date, $end_date)); - - $roomplan_data = $this->getDataOrTerminateWithError($roomplan_data); - - $this->expand_object_information($roomplan_data); - - $this->terminateWithSuccess($roomplan_data); - - } - - /** - * fetches stundenplan events from a UID and start/end date - * @access public - * - */ - - public function getStundenplan(){ - - $this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel'); - $this->load->model('organisation/Studiensemester_model','StudiensemesterModel'); - $this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel'); - $this->load->model('person/Benutzergruppe_model','BenutzergruppeModel'); - - // form validation - $this->load->library('form_validation'); - $this->form_validation->set_data($_GET); - $this->form_validation->set_rules('start_date', "start_date", "required"); - $this->form_validation->set_rules('end_date', "end_date", "required"); - if ($this->form_validation->run() === FALSE) - $this->terminateWithValidationErrors($this->form_validation->error_array()); - - // storing the get parameter in local variables - $start_date = $this->input->get('start_date', TRUE); - $end_date = $this->input->get('end_date', TRUE); - $lv_id = $this->input->get('lv_id', TRUE); - - $student_uid = getAuthUID(); - if(is_null($student_uid)) - { - $this->terminateWithError("No UID"); - } - - $semester_range = $this->studienSemesterErmitteln($start_date,$end_date); - $this->sortStudienSemester($semester_range); - $this->applyLoadUeberSemesterHaelfte($semester_range); - - if($lv_id) { // fetch Stundenplan for lva, irrelevant of who is requesting it (for now) - - $stundenplan_data = $this->StundenplanModel->getStundenplanLVA($start_date, $end_date, $lv_id); - $stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? []; - $this->expand_object_information($stundenplan_data); - - // query lv itself in case its Stundenplan is being queried and it has no entries - $this->load->model('education/Lehrveranstaltung_model','LehrveranstaltungModel'); - $lv = getData($this->LehrveranstaltungModel->load($lv_id))[0]; - $this->addMeta('lv', $lv); - $this->terminateWithSuccess($stundenplan_data); - - } - - $is_mitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter($student_uid)); - if($is_mitarbeiter) - { - - $stundenplan_data = $this->StundenplanModel->getStundenplanMitarbeiter($start_date, $end_date, $student_uid); - $stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? []; - $this->expand_object_information($stundenplan_data); - $this->terminateWithSuccess($stundenplan_data); - } else { - // getting the gruppen_kurzbz of the student in the different studiensemester - $benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($semester_range); - - // getting the student_lehrverbaende of the student in the different studiensemester - $student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($semester_range); - - $stundenplan_query = $this->StundenplanModel->getStundenplanQuery($start_date, $end_date, $semester_range, $benutzer_gruppen, $student_lehrverband); - if(!$stundenplan_query) - { - $this->terminateWithSuccess([]); - } - $stundenplan_data = $this->StundenplanModel->stundenplanGruppierung($stundenplan_query); - $stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? []; - - $this->expand_object_information($stundenplan_data); - - $this->returnObj['$stundenplan_query'] = $stundenplan_query; - $this->returnObj['$student_lehrverband'] = $student_lehrverband; - $this->returnObj['$benutzer_gruppen'] = $benutzer_gruppen; - $this->terminateWithSuccess($stundenplan_data); - } - - } - - // gets the reservierungen of a room if the ort_kurzbz parameter is supplied otherwise gets the reservierungen of the stundenplan of a student - public function Reservierungen($ort_kurzbz = null) - { - //form validation - $this->load->library('form_validation'); - $this->form_validation->set_data($_GET); - $this->form_validation->set_rules('start_date', "StartDate", "required"); - $this->form_validation->set_rules('end_date', "EndDate", "required"); - if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array()); - - $this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel'); - - // storing the get parameter in local variables - $start_date = $this->input->get('start_date', TRUE); - $end_date = $this->input->get('end_date', TRUE); - - $is_mitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter(getAuthUID())); - if($is_mitarbeiter) - { - $reservierungen = $this->ReservierungModel->getReservierungenMitarbeiter($start_date, $end_date, $ort_kurzbz); - } else { - // querying the reservierungen - $reservierungen = $this->ReservierungModel->getReservierungen($start_date, $end_date, $ort_kurzbz); - } - - $reservierungen = $this->getDataOrTerminateWithError($reservierungen) ?? []; - $this->expand_object_information($reservierungen); - $this->terminateWithSuccess($reservierungen); - - } - - public function getLehreinheitStudiensemester($lehreinheit_id){ - $this->load->model('education/Lehreinheit_model', 'LehreinheitModel'); - $this->LehreinheitModel->addSelect(["studiensemester_kurzbz"]); - $result = $this->LehreinheitModel->load($lehreinheit_id); - $result = current($this->getDataOrTerminateWithError($result))->studiensemester_kurzbz; - $this->terminateWithSuccess($result); - } - - // ################# Private Functions - - private function expand_object_information($data){ - - foreach ($data as $item) - { - - $lektor_obj_array = array(); - $gruppe_obj_array = array(); - - // load lektor object - foreach ($item->lektor as $lv_lektor) - { - $this->StundenplanModel->addLimit(1); - $lektor_object = $this->StundenplanModel->execReadOnlyQuery(" - SELECT mitarbeiter_uid, vorname, nachname, kurzbz - FROM public.tbl_mitarbeiter - JOIN public.tbl_benutzer benutzer ON benutzer.uid = mitarbeiter_uid - JOIN public.tbl_person person ON person.person_id = benutzer.person_id - WHERE kurzbz = ?", [$lv_lektor]); - if (isError($lektor_object)) { - $this->show_error(getError($lektor_object)); - } - $lektor_object = $this->getDataOrTerminateWithError($lektor_object); - if(count($lektor_object) == 0) - { - $this->terminateWithError("No lektor object"); - } - $lektor_object = current($lektor_object); - // only provide needed information of the mitarbeiter object - $lektor_obj_array[] = $lektor_object; - } - - // load gruppe object - foreach ($item->gruppe as $lv_gruppe) - { - $lv_gruppe = strtr($lv_gruppe, ['(' => '', ')' => '', '"' => '']); - $lv_gruppe_array = explode(",", $lv_gruppe); - list($gruppe, $verband, $semester, $studiengang_kz, $gruppen_kuerzel) = $lv_gruppe_array; - - $lv_gruppe_object = new stdClass(); - $lv_gruppe_object->gruppe = $gruppe; - $lv_gruppe_object->verband = $verband; - $lv_gruppe_object->semester = $semester; - $lv_gruppe_object->studiengang_kz = $studiengang_kz; - $lv_gruppe_object->kuerzel = $gruppen_kuerzel; - - $gruppe_obj_array[] = $lv_gruppe_object; - } - - if($item->ort_kurzbz) { - - $ort_content_object = $this->StundenplanModel->execReadOnlyQuery(" - SELECT content_id - FROM public.tbl_ort - WHERE ort_kurzbz = ?", [$item->ort_kurzbz]); - if (isError($ort_content_object)) { - $this->show_error(getError($ort_content_object)); - } - $ort_content_object = getData($ort_content_object)[0]; - if($ort_content_object) { - $item->ort_content_id = $ort_content_object->content_id; - } - - - } - - $item->gruppe = $gruppe_obj_array; - $item->lektor = $lektor_obj_array; - - } - } - - // function used to sort an array of studiensemester strings - private function sortStudienSemester(&$semester_range){ - usort( - $semester_range, - function($first,$second) - { - $sem_first = null; - $year_first = null; - $match_first = null; - - $sem_second = null; - $year_second = null; - $match_second = null; - - preg_match('/([WS]+)([0-9]+)/',$first,$match_first); - preg_match('/([WS]+)([0-9]+)/',$second,$match_second); - - $sem_first = $match_first[1]; - $year_first = intval($match_first[2]); - - $sem_second = $match_second[1]; - $year_second = intval($match_second[2]); - - if($year_first < $year_second) - { - return -1; - } - else if($year_first > $year_second) - { - return 1; - } - else if($year_first == $year_second && $sem_first > $sem_second) - { - return 1; - } - else if($year_first == $year_second && $sem_first < $sem_second) - { - return -1; - } - return 0; - } - ); - } - - - - private function fetchBenutzerGruppenFromStudiensemester($semester_range){ - $student_uid = getAuthUID(); - $benutzer_gruppen = []; - // for each studiensemester fetch the benutzer gruppen and add them to an associate $bentuzer_gruppen array - /* - [ - ['WS2023'] => [['gruppe1_SS2023','gruppe2_SS2023'],['gruppe1_WS2023','gruppe2_WS2023']], - ['SS2024'] => [['gruppe1_WS2023','gruppe2_WS2023'],['gruppe1_SS2024','gruppe2_SS2024']], - ['WS2024'] => [['gruppe1_SS2024','gruppe2_SS2024'],['gruppe1_WS2024','gruppe2_WS2024']], - ] - */ - foreach($semester_range as $semester_key => $semester_array) - { - $benutzer_gruppen[$semester_key] = []; - // each semester could have ajoint semesters that need to be checked - foreach($semester_array as $semester=>$semester_date_range) - { - // for each active semester query the benutzer_gruppen associated to the semester - $benutzer_query = $this->BenutzergruppeModel->execReadOnlyQuery(" - SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz = ?",[$student_uid, $semester]); - $benutzer_query_result = $this->getDataOrTerminateWithError($benutzer_query); - array_push( - $benutzer_gruppen[$semester_key], - array_map( - function($item) - { - return "'".$item->gruppe_kurzbz. "'"; - }, - $benutzer_query_result - ) - ); - } - } - - // merge the gruppen of each studiensemester together for the original studiensemester - /* - [ - ['WS2023'] => ['gruppe1_SS2023','gruppe2_SS2023','gruppe1_WS2023','gruppe2_WS2023'], - ['SS2024'] => ['gruppe1_WS2023','gruppe2_WS2023','gruppe1_SS2024','gruppe2_SS2024'], - ['WS2024'] => ['gruppe1_SS2024','gruppe2_SS2024','gruppe1_WS2024','gruppe2_WS2024'], - ] - */ - $benutzer_gruppen = array_map( - function($gruppe) - { - $merged_gruppe = []; - foreach($gruppe as $gruppen_array) - { - $merged_gruppe = array_merge($merged_gruppe, $gruppen_array); - } - return $merged_gruppe; - }, - $benutzer_gruppen - ); - - return $benutzer_gruppen; - } - - private function fetchStudentlehrverbandFromStudiensemester($semester_range){ - $student_uid = getAuthUID(); - $student_lehrverband = []; - // for each studiensemester fetch the studentlehrverbaende and add them to an associate $student_lehrverband array - /* - [ - ['WS2023'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ] ], - ['SS2024'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ] ], - ['WS2024'] => [ [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ] ], - ] - */ - foreach($semester_range as $semester_key => $semester_array) - { - $student_lehrverband[$semester_key] = []; - foreach($semester_array as $semester=>$semester_date_range) - { - // for each active semester query the student_lehrverband associated to the semester - $lehrverband_query = $this->BenutzergruppeModel->execReadOnlyQuery(" - SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]); - $lehrverband_query_result = $this->getDataOrTerminateWithError($lehrverband_query); - array_push($student_lehrverband[$semester_key], array_map( - function ($item) - { - $result = new stdClass(); - $result->studiengang_kz = $item->studiengang_kz; - $result->semester = $item->semester; - $result->verband = $item->verband; - $result->gruppe = $item->gruppe; - return $result; - }, - $lehrverband_query_result)); - } - } - - // merge the studentlehrverband of each studiensemester together for the original studiensemester - /* - [ - ['WS2023'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], - ['SS2024'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], - ['WS2024'] => [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ], - ] - */ - $student_lehrverband = array_map( - function($studentlehrverband) - { - $merged_studentlehrverband = []; - foreach($studentlehrverband as $studentlehrverband_array) - { - $merged_studentlehrverband = array_merge($merged_studentlehrverband, $studentlehrverband_array); - } - return $merged_studentlehrverband; - }, - $student_lehrverband - ); - - return $student_lehrverband; - } - - private function applyLoadUeberSemesterHaelfte(&$semester_range){ - /* - @var($semester_collection) - convert the array of studiensemester into an associative array with the studiensemester as the key - and the values of each key are the studiensemester needed for the query associated to that studiensemester - example: - - #INPUT: - ['WS2023','SS2024','WS2024'] - #OUTPUT: - [ - 'WS2023' => ['SS2023','WS2023'] - 'SS2024' => ['WS2023','SS2024'] - 'WS2024' => ['SS2024','WS2024'] - ] - */ - $semester_collection = []; - foreach($semester_range as $studiensemester) - { - $previous_studiensemester = $this->StudiensemesterModel->getPreviousFrom($studiensemester); - $previous_studiensemester = $this->getDataOrTerminateWithError($previous_studiensemester); - if (count($previous_studiensemester) == 0) { - $this->terminateWithError("No previous semester"); - } - $previous_studiensemester = current($previous_studiensemester)->studiensemester_kurzbz; - $semester_collection[$studiensemester] = [$previous_studiensemester, $studiensemester]; - } - - /* - @var($studienSemesterDateRanges) - fetches for each studiensemester the start and end date, (SS) summer studiensemester are extended by 1 month to cover the summerbreak - based on the LVPLAN_LOAD_UEBER_SEMESTERHAELFTE constant it will load both the semester and the previous semester with the full date range - or the semester with the full date range and the previous semester with the half date range: - - #INPUT: - [ - 'WS2023' => ['SS2023','WS2023'] - 'SS2024' => ['WS2023','SS2024'] - 'WS2024' => ['SS2024','WS2024'] - ] - #OUTPUT: depends whether LVPLAN_LOAD_UEBER_SEMESTERHAELFTE is true or false - ~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == true - [ - "SS2024": [ - "WS2023": [ - "start"=> "2024-02-03", - "ende"=> "2024-08-31" - ], - "SS2024": [ - "start"=> "2024-02-03", - "ende"=> "2024-08-31" - ] - ] - ] - ~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == false - [ - "SS2024": [ - "WS2023": [ - "start"=> "2024-02-03", - "ende"=> "2024-05-17" - ], - "SS2024": [ - "start"=> "2024-02-03", - "ende"=> "2024-08-31" - ] - ] - ] - */ - $studienSemesterDateRanges=[]; - foreach($semester_collection as $semester_original => $semester_adjoint) - { - $semester_start_ende = $this->StudiensemesterModel->getStartEndeFromStudiensemester($semester_original); - $semester_start_ende = current($this->getDataOrTerminateWithError($semester_start_ende)); - - // initialize empty arrays to add key value pairs - $studienSemesterDateRanges[$semester_original] = []; - - // check if the studiensemester is a summer semester and add 1 month to bridge the school summer break - $match = null; - preg_match("/^(SS)([0-9]+)/",$semester_original,$match); - if(count($match) >0) - { - $one_month = new DateInterval('P1M'); - $one_day = DateInterval::createFromDateString('1 days'); - $summer_studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende); - $summer_studiensemester_end_date->add($one_month); - $summer_studiensemester_end_date->sub($one_day); - $semester_start_ende->ende = date_format($summer_studiensemester_end_date,'Y-m-d'); - } - if (defined('LVPLAN_LOAD_UEBER_SEMESTERHAELFTE') && LVPLAN_LOAD_UEBER_SEMESTERHAELFTE === true) - { - foreach($semester_adjoint as $adjoint) - { - $studienSemesterDateRanges[$semester_original][$adjoint]=$semester_start_ende; - } - } - else - { - //TODO: half of a DateInterval might not be correctly calculated - // calculate the half of the studiensemester - $studiensemester_start_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->start); - $studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende); - $studiensemester_time_difference = $studiensemester_start_date->diff($studiensemester_end_date); - $half_dateNumber = ceil($studiensemester_time_difference->d/2)+ceil(($studiensemester_time_difference->m*30)/2); - $half_dateInterval = new DateInterval('P'.strval($half_dateNumber) .'D'); - $studiensemester_half = date_format($studiensemester_start_date->add($half_dateInterval),'Y-m-d'); - - $first_half = new stdClass(); - $first_half->start = $semester_start_ende->start; - $first_half->ende = $studiensemester_half; - - $studienSemesterDateRanges[$semester_original][$semester_adjoint[0]] = $first_half; - $studienSemesterDateRanges[$semester_original][$semester_adjoint[1]] = $semester_start_ende; - } - $semester_range = $studienSemesterDateRanges; - } - } - - private function studienSemesterErmitteln($start_date,$end_date){ - - // gets all studiensemester from the student from start_date to end_date - $semester_range = $this->StudiensemesterModel->getByDateRange($start_date,$end_date); - $semester_range = array_map( - function($sem) - { - return $sem->studiensemester_kurzbz; - }, - $this->getDataOrTerminateWithError($semester_range) - ); - - // if no studiensemester is found for the given timespan, get the nearest studiensemester - if(count($semester_range) == 0) - { - $aktuelle_studiensemester = $this->StudiensemesterModel->getNearest(); - $aktuelle_studiensemester = $this->getDataOrTerminateWithError($aktuelle_studiensemester); - if (count($aktuelle_studiensemester) == 0) { - $this->terminateWithError("No aktuelles semester"); - } - $aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz; - // push aktuelles semester in active semester array - array_push($semester_range, $aktuelle_studiensemester); - - } - return $semester_range; - } - -} diff --git a/application/controllers/api/frontend/v1/betriebsmittel/BetriebsmittelP.php b/application/controllers/api/frontend/v1/betriebsmittel/BetriebsmittelP.php index 4405952a4..05d7c66c2 100644 --- a/application/controllers/api/frontend/v1/betriebsmittel/BetriebsmittelP.php +++ b/application/controllers/api/frontend/v1/betriebsmittel/BetriebsmittelP.php @@ -75,8 +75,9 @@ class BetriebsmittelP extends FHCAPI_Controller 'required' => $this->p->t('ui', 'error_fieldRequired') ]); - $this->form_validation->set_rules('kaution', 'Kaution', 'numeric|less_than_equal_to[9999.99]', [ - 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric') + $this->form_validation->set_rules('kaution', 'Kaution', 'callback_valid_number|callback_not_less_than_equal', [ + 'valid_number' => $this->p->t('ui', 'error_fieldNoValidNumber'), + 'not_less_than_equal' => $this->p->t('ui', 'error_fieldLessThan1000'), ]); $this->form_validation->set_rules('ausgegebenam', 'Ausgegeben am', 'required|is_valid_date', [ @@ -159,10 +160,6 @@ class BetriebsmittelP extends FHCAPI_Controller 'uid_in_person' => $this->p->t('person', 'error_uidNotInPerson') ]); - $this->form_validation->set_rules('kaution', 'Kaution', 'numeric', [ - 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Kaution']) - ]); - $this->validateNewOrUpdate(); $betriebsmitteltyp = $this->input->post('betriebsmitteltyp'); @@ -172,6 +169,7 @@ class BetriebsmittelP extends FHCAPI_Controller $betriebsmittel_id = $this->input->post('betriebsmittel_id'); $anmerkung = $this->input->post('anmerkung'); $kaution = $this->input->post('kaution'); + if($kaution) $kaution = str_replace(',', '.', $kaution); $ausgegebenam = $this->input->post('ausgegebenam'); $retouram = $this->input->post('retouram'); $uid = $this->input->post('uid'); @@ -246,10 +244,6 @@ class BetriebsmittelP extends FHCAPI_Controller public function updateBetriebsmittel($betriebsmittelperson_id) { - $this->form_validation->set_rules('kaution', 'Kaution', 'numeric', [ - 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Kaution']) - ]); - $this->validateNewOrUpdate(); $betriebsmitteltyp = $this->input->post('betriebsmitteltyp'); @@ -259,6 +253,7 @@ class BetriebsmittelP extends FHCAPI_Controller $betriebsmittel_id = $this->input->post('betriebsmittel_id'); $anmerkung = $this->input->post('anmerkung'); $kaution = $this->input->post('kaution'); + if($kaution) $kaution = str_replace(',', '.', $kaution); $ausgegebenam = $this->input->post('ausgegebenam'); $retouram = $this->input->post('retouram'); @@ -391,6 +386,26 @@ class BetriebsmittelP extends FHCAPI_Controller $this->terminateWithSuccess($data); } + + public function valid_number($number) + { + if(is_null($number)) return true; + $number = str_replace(',', '.', $number); + if (!is_numeric($number)) + { + return false; + } + return true; + } + + public function not_less_than_equal($number) + { + $number = str_replace(',', '.', $number); + if ($number < 1000) + return true; + return false; + + } } diff --git a/application/controllers/api/frontend/v1/lv/DirektGruppe.php b/application/controllers/api/frontend/v1/lv/DirektGruppe.php index fe1737f6a..2dcf7d3cb 100644 --- a/application/controllers/api/frontend/v1/lv/DirektGruppe.php +++ b/application/controllers/api/frontend/v1/lv/DirektGruppe.php @@ -99,7 +99,9 @@ class DirektGruppe extends FHCAPI_Controller if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - $oe_array = $result; + $oe_array = []; + if (hasData($result)) + $oe_array = getData($result); if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') && !$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid')) diff --git a/application/controllers/api/frontend/v1/lv/Gruppe.php b/application/controllers/api/frontend/v1/lv/Gruppe.php index 01c11f98f..4a1e68656 100644 --- a/application/controllers/api/frontend/v1/lv/Gruppe.php +++ b/application/controllers/api/frontend/v1/lv/Gruppe.php @@ -19,6 +19,13 @@ class Gruppe extends FHCAPI_Controller $this->_ci = &get_instance(); $this->_setAuthUID(); + $this->_ci->load->library('PhrasesLib'); + $this->loadPhrases( + array( + 'ui' + ) + ); + $this->_ci->load->model('organisation/Gruppe_model', 'GruppeModel'); $this->_ci->load->model('organisation/Lehrverband_model', 'LehrverbandModel'); $this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel'); @@ -57,10 +64,6 @@ class Gruppe extends FHCAPI_Controller if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($gid) || !ctype_digit((string)$gid) || is_null($lehrverband)) $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); - $gruppe_result = $this->_ci->GruppeModel->loadWhere(array('gid' => $gid)); - if (!hasData($gruppe_result) || isError($gruppe_result)) - $this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL); - $this->checkPermission($lehreinheit_id); $result = $this->_ci->LehreinheitgruppeModel->addGroup($lehreinheit_id, $gid, !($lehrverband === 'false')); @@ -178,7 +181,10 @@ class Gruppe extends FHCAPI_Controller if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - $oe_array = $result; + + $oe_array = []; + if (hasData($result)) + $oe_array = getData($result); if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') && !$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') && diff --git a/application/controllers/api/frontend/v1/lv/Lehreinheit.php b/application/controllers/api/frontend/v1/lv/Lehreinheit.php index 84ee66d5d..b851f8c22 100644 --- a/application/controllers/api/frontend/v1/lv/Lehreinheit.php +++ b/application/controllers/api/frontend/v1/lv/Lehreinheit.php @@ -80,7 +80,7 @@ class Lehreinheit extends FHCAPI_Controller $lehrveranstaltung = getData($lehrveranstaltung_result)[0]; - $oe_result = $this->_ci->LehrveranstaltungModel->getAllOe($lehrveranstaltung->lehrveranstaltung_id, $lehrveranstaltung->studiengang_kz); + $oe_result = $this->_ci->LehrveranstaltungModel->getAllOe($lehrveranstaltung->lehrveranstaltung_id); $oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array(); if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') && @@ -164,7 +164,6 @@ class Lehreinheit extends FHCAPI_Controller $this->terminateWithValidationErrors($this->form_validation->error_array()); } - $updateData = array(); foreach ($updatableFields as $field) { @@ -183,6 +182,12 @@ class Lehreinheit extends FHCAPI_Controller $updateData ); + if (!isset($updateData['unr'])) + { + $unr = getData($result); + $this->_ci->LehreinheitModel->update($unr, array('unr' => $unr)); + } + $this->terminateWithSuccess($result); } @@ -210,6 +215,7 @@ class Lehreinheit extends FHCAPI_Controller $lehreinheit_id_new = getData($insert_result); + $this->_ci->LehreinheitModel->update(array('lehreinheit_id' => $lehreinheit_id_new), array('unr' => $lehreinheit_id_new)); if (in_array($art, array('gruppen', 'alle'))) { $gruppen_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); @@ -408,7 +414,9 @@ class Lehreinheit extends FHCAPI_Controller if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - $oe_array = $result; + $oe_array = []; + if (hasData($result)) + $oe_array = getData($result); if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') && !$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') && diff --git a/application/controllers/api/frontend/v1/lv/Lektor.php b/application/controllers/api/frontend/v1/lv/Lektor.php index 332bc47b6..4a244c1a1 100644 --- a/application/controllers/api/frontend/v1/lv/Lektor.php +++ b/application/controllers/api/frontend/v1/lv/Lektor.php @@ -284,7 +284,9 @@ class Lektor extends FHCAPI_Controller if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL); - $oe_array = $result; + $oe_array = []; + if (hasData($result)) + $oe_array = getData($result); return $this->checkPermissionGenerel($permissions, $oe_array); } diff --git a/application/controllers/api/frontend/v1/lv/StgTree.php b/application/controllers/api/frontend/v1/lv/StgTree.php index fe3047902..8272da978 100644 --- a/application/controllers/api/frontend/v1/lv/StgTree.php +++ b/application/controllers/api/frontend/v1/lv/StgTree.php @@ -86,6 +86,32 @@ class StgTree extends FHCAPI_Controller ]); $list = $this->getDataOrTerminateWithError($result); + $result = $this->StudiengangModel->load($studiengang_kz); + $result = $this->getDataOrTerminateWithError($result); + if ($result) + { + if (current($result)->mischform) + { + $this->load->model('organisation/Studienordnung_model', 'StudienordnungModel'); + + $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("TRUE as leaf", false); + + $this->StudienordnungModel->addJoin('lehre.tbl_studienplan p', 'studienordnung_id'); + + $result = $this->StudienordnungModel->loadWhere([ + 'aktiv' => true, + 'studiengang_kz' => $studiengang_kz, + 'p.orgform_kurzbz !=' => 'DDP' + ]); + $result = $this->getDataOrTerminateWithError($result); + + $list = array_merge($list, $result); + } + } + $this->terminateWithSuccess($list); } } diff --git a/application/controllers/api/frontend/v1/stv/Address.php b/application/controllers/api/frontend/v1/stv/Address.php index 324e306f3..d14111e99 100644 --- a/application/controllers/api/frontend/v1/stv/Address.php +++ b/application/controllers/api/frontend/v1/stv/Address.php @@ -31,6 +31,11 @@ class Address extends FHCAPI_Controller 'getNations' => self::PERM_LOGGED, 'getPlaces' => self::PERM_LOGGED ]); + + // Load language phrases + $this->loadPhrases([ + 'ui' + ]); } public function getNations() @@ -53,7 +58,11 @@ class Address extends FHCAPI_Controller $this->form_validation->set_data(['address.plz' => $plz]); - $this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric|less_than[10000]'); + $this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric|less_than[10000]', [ + 'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']), + 'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ']), + 'less_than' => $this->p->t('ui', 'error_fieldLessThan10000', ['field' => 'PLZ']) + ]); if (!$this->form_validation->run()) $this->terminateWithValidationErrors($this->form_validation->error_array()); diff --git a/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php b/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php index 153079789..86b739c90 100644 --- a/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php +++ b/application/controllers/api/frontend/v1/stv/Aufnahmetermine.php @@ -175,7 +175,6 @@ class Aufnahmetermine extends FHCAPI_Controller $result = $this->RtPersonModel->update( [ 'rt_person_id' => $rt_person_id, - 'person_id' => $person_id, ], [ 'rt_id' => $rt_id, diff --git a/application/controllers/api/frontend/v1/stv/Dokumente.php b/application/controllers/api/frontend/v1/stv/Dokumente.php index 686094620..18c976eb6 100644 --- a/application/controllers/api/frontend/v1/stv/Dokumente.php +++ b/application/controllers/api/frontend/v1/stv/Dokumente.php @@ -101,22 +101,29 @@ class Dokumente extends FHCAPI_Controller } } - //Array for total list of accepted documents - $newDataMap = []; - foreach ($arrayAccepted as $item) { - $newDataMap[] = (array)$item; + //Mapping with document_kurzbz + $preDocMap = []; + foreach ($resultPreDoc as $pre) { + $preDocMap[$pre->dokument_kurzbz] = $pre; } - $listExistingKurzbz = array_column($newDataMap, 'dokument_kurzbz'); + $mergedArray = []; + foreach ($arrayAccepted as $doc) { + $merged = clone $doc; - foreach ($resultPreDoc as $item) - { - if (!in_array($item->dokument_kurzbz, $listExistingKurzbz)) - { - $newDataMap[] = (array)$item; + if (isset($preDocMap[$doc->dokument_kurzbz])) { + $merged->docdatum = $preDocMap[$doc->dokument_kurzbz]->docdatum; + $merged->insertvonma = $preDocMap[$doc->dokument_kurzbz]->insertvonma; + $merged->bezeichnung = $preDocMap[$doc->dokument_kurzbz]->bezeichnung; + } else { + $merged->akzeptiertdatum = null; + $merged->akzeptiertvon = null; } + + $mergedArray[] = $merged; } - $this->terminateWithSuccess($newDataMap); + + $this->terminateWithSuccess($mergedArray); } public function deleteZuordnung($prestudent_id, $dokument_kurzbz) diff --git a/application/controllers/api/frontend/v1/stv/Grades.php b/application/controllers/api/frontend/v1/stv/Grades.php index 61d797495..dd8f53a27 100644 --- a/application/controllers/api/frontend/v1/stv/Grades.php +++ b/application/controllers/api/frontend/v1/stv/Grades.php @@ -74,14 +74,15 @@ class Grades extends FHCAPI_Controller * (Entries in lehre.tbl_zeugnisnote) * * @param string $prestudent_id - * @param string|null $all (optional) If null only the current semesters grades will be loaded, otherwise all semesters grades will be loaded. + * @param string|null $studiensemester_kurzbz If studiensemester_kurzbz only this semesters grades will be loaded, otherwise all semesters grades will be loaded. * * @return void */ - public function getCertificate($prestudent_id, $all = null) + public function getCertificate($prestudent_id, $studiensemester_kurzbz = null) { $this->load->model('crm/Student_model', 'StudentModel'); $this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); $result = $this->StudentModel->loadWhere([ 'prestudent_id' => $prestudent_id @@ -91,12 +92,13 @@ class Grades extends FHCAPI_Controller if (!$student) $this->terminateWithSuccess([]); - $student_uid = current($student)->student_uid; - $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null; + if ($studiensemester_kurzbz !== null && !$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } - $result = $this->ZeugnisnoteModel->getZeugnisnoten($student_uid, $studiensemester_kurzbz); $grades = $this->getDataOrTerminateWithError($result); @@ -109,14 +111,15 @@ class Grades extends FHCAPI_Controller * (Entries in campus.tbl_lvgesamtnote) * * @param string $prestudent_id - * @param string|null $all (optional) If null only the current semesters grades will be loaded, otherwise all semesters grades will be loaded. + * @param string|null $studiensemester_kurzbz If studiensemester_kurzbz only this semesters grades will be loaded, otherwise all semesters grades will be loaded. * * @return void */ - public function getTeacherProposal($prestudent_id, $all = null) + public function getTeacherProposal($prestudent_id, $studiensemester_kurzbz = null) { $this->load->model('crm/Student_model', 'StudentModel'); $this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); $result = $this->StudentModel->loadWhere([ 'prestudent_id' => $prestudent_id @@ -129,9 +132,11 @@ class Grades extends FHCAPI_Controller $student_uid = current($student)->student_uid; - $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null; + if ($studiensemester_kurzbz !== null && !$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } - $result = $this->LvgesamtnoteModel->getLvGesamtNoten(null, $student_uid, $studiensemester_kurzbz); $grades = $this->getDataOrTerminateWithError($result); @@ -144,17 +149,20 @@ class Grades extends FHCAPI_Controller * or as not allowed because of the repeating of a semester. * * @param string $prestudent_id - * @param string|null $all (optional) If null only the current semesters grades will be loaded, otherwise all semesters grades will be loaded. + * @param string|false $studiensemester_kurzbz If studiensemester_kurzbz only this semesters grades will be loaded, otherwise all semesters grades will be loaded. * * @return void */ - public function getRepeaterGrades($prestudent_id, $all = null) + public function getRepeaterGrades($prestudent_id, $studiensemester_kurzbz = false) { + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); $this->load->library('AntragLib'); - $studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : false; + if ($studiensemester_kurzbz !== false && !$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } - $result = $this->antraglib->getLvsForPrestudent($prestudent_id, $studiensemester_kurzbz); $grades = $this->getDataOrTerminateWithError($result); @@ -456,13 +464,19 @@ class Grades extends FHCAPI_Controller $this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer"); $this->form_validation->set_rules("points", $this->p->t("stv", "grades_points"), "required|numeric"); + $this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t("lehre", "studiensemester"), "required|regex_match[/^[WS]S[0-9]{4}$/]"); if (!$this->form_validation->run()) $this->terminateWithValidationErrors($this->form_validation->error_array()); - - $this->load->model('education/Notenschluesselaufteilung_model', 'NotenschluesselaufteilungModel'); - $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + $studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz'); + if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } + + $this->load->model('education/Notenschluesselaufteilung_model', 'NotenschluesselaufteilungModel'); $result = $this->NotenschluesselaufteilungModel->getNote( $this->input->post('points'), diff --git a/application/controllers/api/frontend/v1/stv/Prestudent.php b/application/controllers/api/frontend/v1/stv/Prestudent.php index 0b06b9667..4d0aa5fe1 100644 --- a/application/controllers/api/frontend/v1/stv/Prestudent.php +++ b/application/controllers/api/frontend/v1/stv/Prestudent.php @@ -136,10 +136,21 @@ class Prestudent extends FHCAPI_Controller $update_prestudent = array(); foreach ($array_allowed_props_prestudent as $prop) { - $val = $this->input->post($prop); - if ($val !== null || $prop == 'foerderrelevant') { + $val = $this->input->post($prop, true); + + if ($val !== null || $prop === 'foerderrelevant') { $update_prestudent[$prop] = $val; } + + // allowed to be null, but has to be in postparameter + if ( + in_array($prop, ['zgvdatum', 'zgvmadatum', 'zgvdoktordatum', 'zgv_code', 'zgvmas_code', 'zgvdoktor_code']) + && !isset($update_prestudent[$prop]) + && array_key_exists($prop, $_POST) + ) + { + $update_prestudent[$prop] = null; + } } $update_prestudent['updateamum'] = date('c'); @@ -174,7 +185,11 @@ class Prestudent extends FHCAPI_Controller { $this->load->model('codex/Zgv_model', 'ZgvModel'); - $this->ZgvModel->addOrder('zgv_code'); + $this->ZgvModel->addSelect('zgv_code'); + $this->ZgvModel->addSelect('zgv_bez'); + $this->ZgvModel->addSelect('aktiv'); + $this->ZgvModel->addSelect('zgv_bez as label'); + $this->ZgvModel->addOrder('zgv_bez'); $result = $this->ZgvModel->load(); if (isError($result)) @@ -188,7 +203,11 @@ class Prestudent extends FHCAPI_Controller { $this->load->model('codex/Zgvdoktor_model', 'ZgvdoktorModel'); - $this->ZgvdoktorModel->addOrder('zgvdoktor_code'); + $this->ZgvdoktorModel->addSelect('zgvdoktor_code'); + $this->ZgvdoktorModel->addSelect('zgvdoktor_bez'); + $this->ZgvdoktorModel->addSelect('aktiv'); + $this->ZgvdoktorModel->addSelect('zgvdoktor_bez as label'); + $this->ZgvdoktorModel->addOrder('zgvdoktor_bez'); $result = $this->ZgvdoktorModel->load(); if (isError($result)) @@ -202,7 +221,11 @@ class Prestudent extends FHCAPI_Controller { $this->load->model('codex/Zgvmaster_model', 'ZgvmasterModel'); - $this->ZgvmasterModel->addOrder('zgvmas_code'); + $this->ZgvmasterModel->addSelect('zgvmas_code'); + $this->ZgvmasterModel->addSelect('zgvmas_bez'); + $this->ZgvmasterModel->addSelect('aktiv'); + $this->ZgvmasterModel->addSelect('zgvmas_bez as label'); + $this->ZgvmasterModel->addOrder('zgvmas_bez'); $result = $this->ZgvmasterModel->load(); if (isError($result)) diff --git a/application/controllers/api/frontend/v1/stv/Status.php b/application/controllers/api/frontend/v1/stv/Status.php index fcc8007cd..629d5512a 100644 --- a/application/controllers/api/frontend/v1/stv/Status.php +++ b/application/controllers/api/frontend/v1/stv/Status.php @@ -30,6 +30,7 @@ class Status extends FHCAPI_Controller //Load Models $this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel'); $this->load->model('person/Person_model', 'PersonModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); // Load Libraries $this->load->library('VariableLib', ['uid' => getAuthUID()]); @@ -189,9 +190,13 @@ class Status extends FHCAPI_Controller $studiensemester_kurzbz = $lastStatusData->studiensemester_kurzbz; if ($status_kurzbz == Prestudentstatus_model::STATUS_ABSOLVENT || $status_kurzbz == Prestudentstatus_model::STATUS_DIPLOMAND - ) { - $this->load->library('VariableLib', ['uid' => getAuthUID()]); - $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); + ) + { + $studiensemester_kurzbz = $this->input->post('currentSemester'); + if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } } $ausbildungssemester = $lastStatusData->ausbildungssemester; diff --git a/application/controllers/api/frontend/v1/stv/Student.php b/application/controllers/api/frontend/v1/stv/Student.php index 009e1f013..cca0fa853 100644 --- a/application/controllers/api/frontend/v1/stv/Student.php +++ b/application/controllers/api/frontend/v1/stv/Student.php @@ -68,11 +68,14 @@ class Student extends FHCAPI_Controller * @param string $prestudent_id * @return void */ - public function get($prestudent_id) + public function get($prestudent_id, $studiensemester_kurzbz) { - $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); - $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } $this->PrestudentModel->addSelect('p.person_id'); $this->PrestudentModel->addSelect('p.titelpre'); @@ -94,6 +97,15 @@ class Student extends FHCAPI_Controller $this->PrestudentModel->addSelect('v.verband'); $this->PrestudentModel->addSelect('v.gruppe'); $this->PrestudentModel->addSelect('b.alias'); + $this->PrestudentModel->addSelect('p.geburtsnation'); + $this->PrestudentModel->addSelect('p.sprache'); + $this->PrestudentModel->addSelect('p.gebort'); + $this->PrestudentModel->addSelect('p.homepage'); + $this->PrestudentModel->addSelect('p.anmerkung'); + $this->PrestudentModel->addSelect('p.familienstand'); + $this->PrestudentModel->addSelect('p.staatsbuergerschaft'); + $this->PrestudentModel->addSelect('p.matr_nr'); + $this->PrestudentModel->addSelect('p.anrede'); if (defined('ACTIVE_ADDONS') && strpos(ACTIVE_ADDONS, 'bewerbung') !== false) { $this->PrestudentModel->addSelect( @@ -109,6 +121,16 @@ class Student extends FHCAPI_Controller false ); } + $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" + ); $this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT'); $this->PrestudentModel->addJoin('public.tbl_benutzer b', 'student_uid = uid', 'LEFT'); @@ -118,14 +140,18 @@ class Student extends FHCAPI_Controller 'LEFT' ); $this->PrestudentModel->addJoin('public.tbl_person p', 'p.person_id = tbl_prestudent.person_id'); +/* $this->PrestudentModel->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id = tbl_prestudent.prestudent_id + AND pss.studiensemester_kurzbz = ' . $this->PrestudentModel->escape($studiensemester_kurzbz), + 'LEFT');*/ - $result = $this->PrestudentModel->loadWhere(['prestudent_id' => $prestudent_id]); + $result = $this->PrestudentModel->loadWhere(['tbl_prestudent.prestudent_id' => $prestudent_id]); $student = $this->getDataOrTerminateWithError($result); if (!$student) return show_404(); + $this->terminateWithSuccess(current($student)); } @@ -133,7 +159,7 @@ class Student extends FHCAPI_Controller { $laufendesStudiensemester = ''; $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); - $result = $this->StudiensemesterModel->getNearest(); + $result = $this->StudiensemesterModel->getAktOrNextSemester(); if(hasData($result)) { $laufendesStudiensemester = (getData($result))[0]->studiensemester_kurzbz; } @@ -148,24 +174,37 @@ class Student extends FHCAPI_Controller * @param string $prestudent_id * @return void */ - public function save($prestudent_id) + public function save($prestudent_id, $studiensemester_kurzbz) { $this->load->model('person/Person_model', 'PersonModel'); $this->load->model('person/Benutzer_model', 'BenutzerModel'); $this->load->model('crm/Student_model', 'StudentModel'); $this->load->model('crm/Prestudent_model', 'PrestudentModel'); $this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel'); + $this->load->model('organisation/Lehrverband_model', 'LehrverbandModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); $this->load->library('form_validation'); + if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } + $authuid = getAuthUID(); $now = date('c'); - $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); - $this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'is_valid_date'); - $this->form_validation->set_rules('semester', 'Semester', 'integer'); + $this->form_validation->set_rules('semester', 'Semester', 'integer', [ + 'integer' => $this->p->t('ui', 'error_fieldNotInteger') + ] + ); + + $this->form_validation->set_rules('alias', 'Alias', 'regex_match[/^[-a-z0-9\_\.]*[a-z0-9]{1,}\.[-a-z0-9\_]{1,}$/]', + [ + 'regex_match' => $this->p->t('ui', 'error_fieldInvalidAlias') + ]); $this->load->library('UDFLib'); @@ -277,11 +316,37 @@ class Student extends FHCAPI_Controller // Do Updates if (count($update_lehrverband)) { + $curstudlvb = $this->StudentlehrverbandModel->load([ 'studiensemester_kurzbz' => $studiensemester_kurzbz, 'student_uid' => $uid ]); + $data = $this->getDataOrTerminateWithError($curstudlvb); + $data = current($data); + + $verbandCurrent = $data->verband; + $studiengang_kz = $data->studiengang_kz; + $semesterCurrent = $data->semester; + $gruppeCurrent = $data->gruppe; + + $verband = isset($update_lehrverband['verband']) ? $update_lehrverband['verband'] : $verbandCurrent; + $gruppe = isset($update_lehrverband['gruppe']) ? $update_lehrverband['gruppe'] : $gruppeCurrent; + $semester = isset($update_lehrverband['semester']) ? $update_lehrverband['semester'] : $semesterCurrent; + + //check if existing Lehrverband of new data to avoid Error + $result = $this->LehrverbandModel->loadWhere([ + 'verband' => $verband, + 'gruppe' => $gruppe, + 'semester' => $semester, + 'studiengang_kz' => $studiengang_kz, + ]); + + if(!hasData($result)) + { + $this->terminateWithError($this->p->t('lehre', 'error_noLehrverband'), self::ERROR_TYPE_GENERAL); + } + if(hasData($curstudlvb) && count(getData($curstudlvb)) > 0 ) { $update_lehrverband['updatevon'] = $authuid; diff --git a/application/controllers/api/frontend/v1/stv/Students.php b/application/controllers/api/frontend/v1/stv/Students.php index f9ceabc3d..26b5000bb 100644 --- a/application/controllers/api/frontend/v1/stv/Students.php +++ b/application/controllers/api/frontend/v1/stv/Students.php @@ -45,142 +45,118 @@ class Students extends FHCAPI_Controller // Load Libraries $this->load->library('VariableLib', ['uid' => getAuthUID()]); + $this->load->library('PhrasesLib'); + $this->loadPhrases( + array( + 'lehre' + ) + ); + } /** - * Remap calls: - * / => return [] - * /inout => return [] - * /inout/incoming => getIncoming - * /inout/outgoing => getOutgoing - * /inout/gemeinsamestudien => getGemeinsamestudien - * /(studiengang_kz) => getStudents - * /(studiengang_kz)/prestudent => getPrestudents - * /(studiengang_kz)/prestudent/* => getPrestudents - * /(studiengang_kz)/(semester) => getStudents - * /(studiengang_kz)/(semester)/grp/(gruppe_kurzbz) => getStudents - * /(studiengang_kz)/(semester)/(verband) => getStudents - * /(studiengang_kz)/(semester)/(verband)/(gruppe) => getStudents - * /(studiengang_kz)/(org_form) => getStudents - * /(studiengang_kz)/(org_form)/prestudent => getPrestudents - * /(studiengang_kz)/(org_form)/prestudent/* => getPrestudents - * /(studiengang_kz)/(org_form)/(semester) => getStudents - * /(studiengang_kz)/(org_form)/(semester)/grp/(gruppe_kurzbz) - * => getStudents - * /(studiengang_kz)/(org_form)/(semester)/(verband) => getStudents - * /(studiengang_kz)/(org_form)/(semester)/(verband)/(gruppe) - * => getStudents - * /uid/(student_uid) => getStudent - * /prestudent/(prestudent_id) => getPrestudent - * /person/(person_id) => getPerson + * Routing * - * @param string $method - * @param array $params (optional) + * /inout => index + * /(studiensemester_kurzbz) => index + * /(studiensemester_kurzbz)/inout => index * + * /(studiensemester_kurzbz)/inout/incoming => getIncoming + * /(studiensemester_kurzbz)/inout/outgoing => getOutgoing + * /(studiensemester_kurzbz)/inout/gemeinsamestudien => getGemeinsamestudien + * + * /(studiengang_kz)/prestudent => getPrestudents + * /(studiengang_kz)/prestudent/(studiensemester_kurzbz) => getPrestudents + * /(studiengang_kz)/prestudent/(studiensemester_kurzbz)/(filter) => getPrestudents + * /(studiengang_kz)/prestudent/(studiensemester_kurzbz)/(filter)/(otherfilter) => getPrestudents + * + * /(studiengang_kz)/(orgform)/prestudent => getPrestudentsOrgform + * /(studiengang_kz)/(orgform)/prestudent/(studiensemester_kurzbz) => getPrestudentsOrgform + * /(studiengang_kz)/(orgform)/prestudent/(studiensemester_kurzbz)/(filter) => getPrestudentsOrgform + * /(studiengang_kz)/(orgform)/prestudent/(studiensemester_kurzbz)/(filter)/(otherfilter) => getPrestudentsOrgform + * + * /(studiensemester_kurzbz)/(studiengang_kz)/(semester)/grp/(gruppe) => getStudentsSpezialguppe + * + * /(studiensemester_kurzbz)/(studiengang_kz) => getStudents + * /(studiensemester_kurzbz)/(studiengang_kz)/(semester) => getStudents + * /(studiensemester_kurzbz)/(studiengang_kz)/(semester)/(verband) => getStudents + * /(studiensemester_kurzbz)/(studiengang_kz)/(semester)/(verband)/(gruppe) => getStudents + * + * /(studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester)/grp/(gruppe) => getStudentsOrgformSpezialgruppe + * + * /(studiensemester_kurzbz)/(studiengang_kz)/(orgform) => getStudentsOrgform + * /(studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester) => getStudentsOrgform + * /(studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester)/(verband) => getStudentsOrgform + * /(studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester)/(verband)/(gruppe) => getStudentsOrgform + * + * /(studiensemester_kurzbz)/uid/(student_uid) => getStudent + * /(studiensemester_kurzbz)/prestudent/(prestudent_id) => getPrestudent + * /(studiensemester_kurzbz)/person/(person_id) => getPerson + */ + + public function index() + { + $this->addMeta('ci_method', __FUNCTION__); + $this->terminateWithSuccess([]); + } + + /** * @return void */ - public function _remap($method, $params = []) + public function getIncoming() { - if ($method == '' || $method == 'index') - return $this->terminateWithSuccess([]); + $this->addMeta('ci_method', __FUNCTION__); + // TODO(chris): IMPLEMENT! + $this->terminateWithSuccess([]); + } - if ($method == 'inout') { - if (!count($params)) - return $this->terminateWithSuccess([]); - switch ($params[0]) { - case 'incoming': - return $this->getIncoming(); - case 'outgoing': - return $this->getOutgoing(); - case 'gemeinsamestudien': - return $this->getGemeinsamestudien(); - default: - return show_404(); - } - } + /** + * @return void + */ + public function getOutgoing() + { + $this->addMeta('ci_method', __FUNCTION__); + // TODO(chris): IMPLEMENT! + $this->terminateWithSuccess([]); + } - $count = count($params); - if (!$count) - return $this->getStudents($method); + /** + * @return void + */ + public function getGemeinsamestudien() + { + $this->addMeta('ci_method', __FUNCTION__); + // TODO(chris): IMPLEMENT! + $this->terminateWithSuccess([]); + } - if ($method == 'uid' && $count == 1) - return $this->getStudent($params[0]); - - if ($method == 'prestudent' && $count == 1) - return $this->getPrestudent($params[0]); - - if ($method == 'person' && $count == 1) - return $this->getPerson($params[0]); - - if (is_numeric($params[0])) { - $sem = $params[0]; - if ($count == 3 && $params[1] == 'grp') { - $g = $params[2]; - $ver = null; - $grp = null; - } else { - $g = null; - $ver = $count > 1 ? $params[1] : null; - $grp = $count > 2 ? $params[2] : null; - } - return $this->getStudents($method, $sem, $ver, $grp, $g); - } elseif ($params[0] == 'prestudent') { - if ($count == 1) - return $this->getPrestudents($method); - if ($count == 2) - return $this->getPrestudents($method, $params[1]); - return $this->getPrestudents($method, $params[1], $params[$count-1]); - } else { - $org = $params[0]; - if ($count > 1 && $params[1] == 'prestudent') { - if ($count == 2) - return $this->getPrestudents($method, null, null, $org); - if ($count == 3) - return $this->getPrestudents($method, $params[2], null, $org); - return $this->getPrestudents($method, $params[2], $params[$count-1], $org); - } - $sem = $count > 1 ? $params[1] : null; - if ($count == 4 && $params[2] == 'grp') { - $g = $params[3]; - $ver = null; - $grp = null; - } else { - $g = null; - $ver = $count > 2 ? $params[2] : null; - $grp = $count > 3 ? $params[3] : null; - } - - return $this->getStudents($method, $sem, $ver, $grp, $g, $org); - } + public function getPrestudents($studiengang_kz, + $studiensemester_kurzbz = null, $filter = null + ) + { + $this->addMeta('ci_method', __FUNCTION__); + $this->addMeta('ci_params', array( + 'studiengang_kz' => $studiengang_kz, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'filter' => $filter + )); - show_404(); + $this->fetchPrestudents($studiengang_kz, $studiensemester_kurzbz, $filter); } - /** - * @return void - */ - protected function getIncoming() + public function getPrestudentsOrgform($studiengang_kz, $orgform_kurzbz, + $studiensemester_kurzbz = null, $filter = null + ) { - // TODO(chris): IMPLEMENT! - $this->terminateWithSuccess([]); - } - - /** - * @return void - */ - protected function getOutgoing() - { - // TODO(chris): IMPLEMENT! - $this->terminateWithSuccess([]); - } - - /** - * @return void - */ - protected function getGemeinsamestudien() - { - // TODO(chris): IMPLEMENT! - $this->terminateWithSuccess([]); + $this->addMeta('ci_method', __FUNCTION__); + $this->addMeta('ci_params', array( + 'studiengang_kz' => $studiengang_kz, + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'filter' => $filter, + 'orgform_kurzbz' => $orgform_kurzbz + )); + + $this->fetchPrestudents($studiengang_kz, $studiensemester_kurzbz, $filter, $orgform_kurzbz); } /** @@ -191,7 +167,7 @@ class Students extends FHCAPI_Controller * * @return void */ - protected function getPrestudents($studiengang_kz, $studiensemester_kurzbz = null, $filter = null, $orgform_kurzbz = null) + protected function fetchPrestudents($studiengang_kz, $studiensemester_kurzbz = null, $filter = null, $orgform_kurzbz = null) { $this->load->model('crm/Prestudent_model', 'PrestudentModel'); @@ -358,6 +334,18 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect("'' AS gruppe"); $this->addSelectPrioRel(); + //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" + ); + $this->addFilter($studiensemester_kurzbz); $result = $this->PrestudentModel->loadWhere($where); @@ -367,8 +355,73 @@ class Students extends FHCAPI_Controller $this->terminateWithSuccess($data); } + public function getStudents($studiensemester_kurzbz, + $studiengang_kz, $semester = null, $verband = null, $gruppe = null + ) + { + $this->addMeta('ci_method', __FUNCTION__); + $this->addMeta('ci_params', array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiengang_kz' => $studiengang_kz, + 'semester' => $semester, + 'verband' => $verband, + 'gruppe' => $gruppe + )); + + $this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, $verband, $gruppe, null, null); + } + + public function getStudentsOrgform($studiensemester_kurzbz, + $studiengang_kz, $orgform_kurzbz, $semester = null, $verband = null, $gruppe = null + ) + { + $this->addMeta('ci_method', __FUNCTION__); + $this->addMeta('ci_params', array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiengang_kz' => $studiengang_kz, + 'orgform_kurzbz' => $orgform_kurzbz, + 'semester' => $semester, + 'verband' => $verband, + 'gruppe' => $gruppe + )); + + $this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, $verband, $gruppe, null, $orgform_kurzbz); + } + + public function getStudentsSpezialgruppe($studiensemester_kurzbz, + $studiengang_kz, $semester, $gruppe_kurzbz, + $orgform_kurzbz = null) + { + $this->addMeta('ci_method', __FUNCTION__); + $this->addMeta('ci_params', array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'studiengang_kz' => $studiengang_kz, + 'semester' => $semester, + 'gruppe_kurzbz' => $gruppe_kurzbz + )); + + $this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, null, null, $gruppe_kurzbz, null); + } + + public function getStudentsOrgformSpezialgruppe($studiensemester_kurzbz, + $orgform_kurzbz, $studiengang_kz, $semester, $gruppe_kurzbz + ) + { + $this->addMeta('ci_method', __FUNCTION__); + $this->addMeta('ci_params', array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'orgform_kurzbz' => $orgform_kurzbz, + 'studiengang_kz' => $studiengang_kz, + 'semester' => $semester, + 'gruppe_kurzbz' => $gruppe_kurzbz + )); + + $this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, null, null, $gruppe_kurzbz, $orgform_kurzbz); + } + /** * @param integer $studiengang_kz + * @param string $studiensemester_kurzbz * @param integer $semester (optional) * @param string $verband (optional) * @param integer $gruppe (optional) @@ -377,12 +430,15 @@ class Students extends FHCAPI_Controller * * @return void */ - protected function getStudents($studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null) + protected function fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null) { - $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); - - $this->load->model('crm/Prestudent_model', 'PrestudentModel'); + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } /* $this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT'); @@ -406,6 +462,18 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect('v.gruppe'); $this->PrestudentModel->addSelect("'' AS priorisierung_relativ"); + //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" + ); + $where = []; @@ -455,9 +523,20 @@ class Students extends FHCAPI_Controller * * @return void */ - protected function getPrestudent($prestudent_id) + public function getPrestudent($studiensemester_kurzbz, $prestudent_id) { - $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); + $this->addMeta('ci_method', __FUNCTION__); + $this->addMeta('ci_params', array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'prestudent_id' => $prestudent_id, + )); + + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } $this->load->model('crm/Prestudent_model', 'PrestudentModel'); @@ -482,6 +561,19 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect("COALESCE(v.semester::text, CASE WHEN public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent') THEN public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)::text ELSE ''::text END) AS semester", false); $this->PrestudentModel->addSelect('v.verband'); $this->PrestudentModel->addSelect('v.gruppe'); + + //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" + ); + $this->addSelectPrioRel(); $this->addFilter($studiensemester_kurzbz); @@ -500,9 +592,20 @@ class Students extends FHCAPI_Controller * * @return void */ - protected function getStudent($student_uid) + public function getStudent($studiensemester_kurzbz, $student_uid) { - $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); + $this->addMeta('ci_method', __FUNCTION__); + $this->addMeta('ci_params', array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'student_uid' => $student_uid, + )); + + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } $this->load->model('crm/Prestudent_model', 'PrestudentModel'); @@ -527,8 +630,23 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect('v.semester'); $this->PrestudentModel->addSelect('v.verband'); $this->PrestudentModel->addSelect('v.gruppe'); + + //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" + ); + $this->addSelectPrioRel(); + + $this->addFilter($studiensemester_kurzbz); $result = $this->PrestudentModel->loadWhere([ @@ -541,13 +659,25 @@ class Students extends FHCAPI_Controller } /** + * @param string $studiensemester_kurzbz * @param integer $person_id * * @return void */ - protected function getPerson($person_id) + public function getPerson($studiensemester_kurzbz, $person_id) { - $studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell'); + $this->addMeta('ci_method', __FUNCTION__); + $this->addMeta('ci_params', array( + 'studiensemester_kurzbz' => $studiensemester_kurzbz, + 'person_id' => $person_id, + )); + + $this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz)) + { + $this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester')); + } $this->load->model('crm/Prestudent_model', 'PrestudentModel'); @@ -565,6 +695,19 @@ class Students extends FHCAPI_Controller $this->PrestudentModel->addSelect('v.semester'); $this->PrestudentModel->addSelect('v.verband'); $this->PrestudentModel->addSelect('v.gruppe'); + + //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" + ); + $this->addSelectPrioRel(); $this->addFilter($studiensemester_kurzbz); diff --git a/application/controllers/api/frontend/v1/stv/Verband.php b/application/controllers/api/frontend/v1/stv/Verband.php index e8c532652..4060704de 100644 --- a/application/controllers/api/frontend/v1/stv/Verband.php +++ b/application/controllers/api/frontend/v1/stv/Verband.php @@ -355,7 +355,11 @@ class Verband extends FHCAPI_Controller $this->load->model('system/Variable_model', 'VariableModel'); $result = $this->VariableModel->getVariables(getAuthUID(), ['number_displayed_past_studiensemester']); $data = $this->getDataOrTerminateWithError($result); - $number_displayed_past_studiensemester = $data['number_displayed_past_studiensemester'] ?? null; + + $this->load->config('stv'); + $number_displayed_past_studiensemester_default = $this->config->item('number_displayed_past_studiensemester_default'); + + $number_displayed_past_studiensemester = $data['number_displayed_past_studiensemester'] ?? $number_displayed_past_studiensemester_default; $this->StudiensemesterModel->addPlusMinus(null, $number_displayed_past_studiensemester); $this->StudiensemesterModel->addOrder('ende'); diff --git a/application/controllers/components/Cis/Stundenplan.php b/application/controllers/components/Cis/LvPlan.php similarity index 97% rename from application/controllers/components/Cis/Stundenplan.php rename to application/controllers/components/Cis/LvPlan.php index a9f35c651..d4cf63520 100644 --- a/application/controllers/components/Cis/Stundenplan.php +++ b/application/controllers/components/Cis/LvPlan.php @@ -5,7 +5,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed'); /** * */ -class Stundenplan extends Auth_Controller +class LvPlan extends Auth_Controller { /** diff --git a/application/controllers/dashboard/Config.php b/application/controllers/dashboard/Config.php index 2c0cf5fca..f6db9509f 100644 --- a/application/controllers/dashboard/Config.php +++ b/application/controllers/dashboard/Config.php @@ -65,7 +65,7 @@ class Config extends Auth_Controller $preset_decoded = json_decode($preset->preset, true); - $this->DashboardLib->addWidgetsToWidgets($preset_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets); + $this->DashboardLib->addWidgetsToWidgets($preset_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets); $preset->preset = json_encode($preset_decoded); @@ -92,7 +92,7 @@ class Config extends Auth_Controller } $preset_decoded = json_decode($preset->preset, true); - if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded['widgets'], $funktion_kurzbz, $widgetid)) + if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded, $funktion_kurzbz, $widgetid)) { http_response_code(404); $this->terminateWithJsonError('widgetid ' . $widgetid . ' not found'); @@ -119,7 +119,7 @@ class Config extends Auth_Controller $override_decoded = json_decode($override->override, true); - $this->DashboardLib->addWidgetsToWidgets($override_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets); + $this->DashboardLib->addWidgetsToWidgets($override_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets); $override->override = json_encode($override_decoded); @@ -148,7 +148,7 @@ class Config extends Auth_Controller $override_decoded = json_decode($override->override, true); - if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded['widgets'], $funktion_kurzbz, $widgetid)) + if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded, $funktion_kurzbz, $widgetid)) { http_response_code(404); $this->terminateWithJsonError('widgetid ' . $widgetid . ' not found'); @@ -202,10 +202,10 @@ class Config extends Auth_Controller if ($conf) { $preset = json_decode($conf->preset, true); - if (!isset($preset['widgets']) || !isset($preset['widgets'][$funktion])) + if (!isset($preset[$funktion]) || !isset($preset[$funktion]['widgets'])) $result[$funktion] = []; else - $result[$funktion] = $preset['widgets'][$funktion]; + $result[$funktion] = $preset[$funktion]['widgets']; } else $result[$funktion] = []; diff --git a/application/core/FHCAPI_Controller.php b/application/core/FHCAPI_Controller.php index 6697953bc..dad56334d 100644 --- a/application/core/FHCAPI_Controller.php +++ b/application/core/FHCAPI_Controller.php @@ -109,10 +109,15 @@ class FHCAPI_Controller extends Auth_Controller $error = []; if (is_array($data)) { - if ($type == self::ERROR_TYPE_VALIDATION) + if ($type == self::ERROR_TYPE_VALIDATION) { $error['messages'] = $data; - else + } elseif (array_is_list($data)) { + foreach ($data as $d) + $this->addError($d, $type); + return; + } else { $error = $data; + } } elseif (is_object($data)) { $error = (array)$data; } else { diff --git a/application/helpers/hlp_common_helper.php b/application/helpers/hlp_common_helper.php index 40aed007c..00c0a1b93 100644 --- a/application/helpers/hlp_common_helper.php +++ b/application/helpers/hlp_common_helper.php @@ -424,6 +424,23 @@ function isValidDate($dateString) } +// ------------------------------------------------------------------------ +// PHP functions that don't exist in older versions +// ------------------------------------------------------------------------ + +/** + * Returns true if the given array is sequential + */ +if (!function_exists('array_is_list')) { + function array_is_list(array $arr) + { + if ($arr === []) { + return true; + } + return array_keys($arr) === range(0, count($arr) - 1); + } +} + // ------------------------------------------------------------------------ // Collection of utility functions for form validation purposes // ------------------------------------------------------------------------ diff --git a/application/helpers/hlp_header_helper.php b/application/helpers/hlp_header_helper.php index de7e866f4..24c02eac5 100644 --- a/application/helpers/hlp_header_helper.php +++ b/application/helpers/hlp_header_helper.php @@ -88,6 +88,7 @@ function generateCSSsInclude($CSSs) function generateJSDataStorageObject($indexPage, $calledPath, $calledMethod) { $ci =& get_instance(); + $ci->load->config('theme'); $ci->load->model('system/Sprache_model','SpracheModel'); $server_language = getData($ci->SpracheModel->loadWhere(['content' => true])); $server_language = array_map(function($language){ @@ -107,6 +108,10 @@ function generateJSDataStorageObject($indexPage, $calledPath, $calledMethod) 'user_language' => $user_language, 'timezone' => date_default_timezone_get(), 'systemerror_mailto' => $systemerror_mailto, + 'theme' => [ + 'name'=>$ci->config->item('theme_name'), + 'modes'=>$ci->config->item('theme_modes'), + ] ); $toPrint = "\n"; @@ -231,3 +236,13 @@ function generateBackwardCompatibleJSMsIe($js) echo "\n"; } +/** + * Constructs an accessibility skipLink https://www.w3schools.com/accessibility/accessibility_skip_links.php + */ +function generateSkipLink($skipID) +{ + $toPrint = ''; + echo $toPrint; +} diff --git a/application/libraries/DocumentExportLib.php b/application/libraries/DocumentExportLib.php index 595ac461a..a75047cf9 100644 --- a/application/libraries/DocumentExportLib.php +++ b/application/libraries/DocumentExportLib.php @@ -55,7 +55,7 @@ use SimpleXMLElement as SimpleXMLElement; * $doc->create($outputformat); * $doc->output(true); * $doc->close(); - * + * * New: * $xml_data = $this->documentexportlib->getDataXML($data); * $images = [[ @@ -397,20 +397,24 @@ class DocumentExportLib $vorlage_stg = current(getData($result)); foreach ($vorlage_stg as $k => $v) $vorlage->$k = $v; - + + if ($sign_user) + { + $this->addSignToData($xml_data); + } + $result = $this->create($temp_folder, $outputformat, $vorlage, $xml_data, $images); if (isError($result)) return $result; - + $temp_filename = getData($result); - if ($sign_user) { - $this->addSignToData($xml_data); - + if ($sign_user) + { $result = $this->sign($temp_folder, $temp_filename, $outputformat, $sign_user, $sign_profile); if (isError($result)) return $result; - + $temp_filename = getData($result); } @@ -445,6 +449,7 @@ class DocumentExportLib if ($xml_data->firstChild->tagName == 'error') return error($xml_data->firstChild->textContent); + $styles_xsl = null; // styles.xml erstellen if ($vorlage->style) { $styles_xsl = new DOMDocument(); @@ -461,7 +466,7 @@ class DocumentExportLib // Template holen $vorlage_found = false; $vorlage_filename = $vorlage->vorlage_kurzbz . ($vorlage->mimetype == 'application/vnd.oasis.opendocument.spreadsheet' ? '.ods' : '.odt'); - + $aktive_addons = array_filter(array_map('trim', explode(";", ACTIVE_ADDONS))); foreach($aktive_addons as $addon) { $zipfile = DOC_ROOT . 'addons/' . $addon . '/system/vorlage_zip/' . $vorlage_filename; @@ -652,7 +657,7 @@ class DocumentExportLib foreach ($files as $file) if (is_file($file)) unlink($file); - + chdir($source_folder); rmdir($temp_folder); } @@ -703,12 +708,12 @@ class DocumentExportLib { if ($outputformat) return $outputformat; - + if ($mimetype == 'application/vnd.oasis.opendocument.spreadsheet') return 'ods'; if ($mimetype == 'application/vnd.oasis.opendocument.text') return 'odt'; - + return 'pdf'; } } diff --git a/application/libraries/PrestudentLib.php b/application/libraries/PrestudentLib.php index ef5e2e3a9..2d795369f 100644 --- a/application/libraries/PrestudentLib.php +++ b/application/libraries/PrestudentLib.php @@ -500,11 +500,6 @@ class PrestudentLib $student = current(getData($result)); - - $this->_ci->load->library('VariableLib', ['uid' => $authUID]); - $semester_aktuell = $this->_ci->variablelib->getVar('semester_aktuell'); - - // Update Aktionen // Status updaten @@ -545,8 +540,8 @@ class PrestudentLib // Studentlehrverband updaten $result = $this->_ci->StudentlehrverbandModel->update([ 'student_uid' => $student->student_uid, - 'studiensemester_kurzbz' => $semester_aktuell - ], [ + 'studiensemester_kurzbz' => $studiensemester_kurzbz + ], [ 'semester' => $ausbildungssemester, 'verband' => '', 'gruppe' => '', diff --git a/application/libraries/ProfilLib.php b/application/libraries/ProfilLib.php new file mode 100644 index 000000000..2a130d263 --- /dev/null +++ b/application/libraries/ProfilLib.php @@ -0,0 +1,588 @@ +ci =& get_instance(); + + + } + + public function getView($uid) + { + // loading required models + $this->ci->load->model("ressource/Mitarbeiter_model","MitarbeiterModel"); + $this->ci->load->model("person/Person_model","PersonModel"); + + $res = new stdClass(); + + // checking the uid + if ($uid == getAuthUID()) { + $isMitarbeiter = $this->ci->MitarbeiterModel->isMitarbeiter(getAuthUID()); + if(isError($isMitarbeiter)) + { + return error(getData($isMitarbeiter)); + } + $isMitarbeiter = getData($isMitarbeiter); + if ($isMitarbeiter) { + $res->view = "MitarbeiterProfil"; + $res->data = $this->mitarbeiterProfil(); + $res->data->pid = getAuthPersonId(); + } else { + $res->view = "StudentProfil"; + $res->data = $this->studentProfil(); + $res->data->pid = getAuthPersonId(); + } + $res->data->fotoStatus=$this->isFotoAkzeptiert(getAuthPersonId()); + } + // UID is availabe when accessing Profil/View/:uid + else { + $isMitarbeiter = $this->ci->MitarbeiterModel->isMitarbeiter($uid); + if(isError($isMitarbeiter)) + { + return error(getData($isMitarbeiter)); + } + $isMitarbeiter = getData($isMitarbeiter); + if ($isMitarbeiter) { + $res->view = "ViewMitarbeiterProfil"; + $res->data = $this->viewMitarbeiterProfil($uid); + + } else { + $res->view = "ViewStudentProfil"; + $res->data = $this->viewStudentProfil($uid); + } + } + + return success($res); + } + + //PRIVATE METHODS ############################################### + + /** + * function that returns the data used for the student profile + * @access private + * @return stdClass student data + */ + private function studentProfil() + { + $pid = getAuthPersonId(); + $uid = getAuthUID(); + $betriebsmittelperson_res = $this->getBetriebsmittelInfo($pid); + $kontakte_res = $this->getKontaktInfo($pid); + $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($uid); + $adresse_res = $this->getAdressenInfo($pid); + $mailverteiler_res = $this->getMailverteiler($uid); + $person_res = $this->getPersonInfo($uid, true); + $zutrittsgruppe_res = $this->getZutrittsgruppen($uid); + $student_res = $this->getStudentInfo($uid); + $matr_res = $this->getMatrikelNummer($uid); + $profilUpdates = $this->getProfilUpdates($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Student Information + foreach ($student_res as $key => $value) { + $res->$key = trim($value); + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = DOMAIN? $uid . "@" . DOMAIN :""; + + $res->emails = [$intern_email]; + $res->adressen = $adresse_res; + $res->zutrittsdatum = $zutrittskarte_ausgegebenam; + $res->kontakte = $kontakte_res; + $res->mittel = $betriebsmittelperson_res; + $res->matrikelnummer = $matr_res->matr_nr; + $res->zuttritsgruppen = $zutrittsgruppe_res; + $res->mailverteiler = $mailverteiler_res; + $res->profilUpdates = $profilUpdates; + + return $res; + } + + /** + * function that returns the data used for the mitarbeiter profile + * @access private + * @return stdClass mitarbeiter data + */ + private function mitarbeiterProfil() + { + $pid = getAuthPersonId(); + $uid = getAuthUID(); + $zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($uid); + $adresse_res = $this->getAdressenInfo($pid); + $kontakte_res = $this->getKontaktInfo($pid); + $mailverteiler_res = $this->getMailverteiler($uid); + $person_res = $this->getPersonInfo($uid, true); + $benutzer_funktion_res = $this->getBenutzerFunktion($uid); + $betriebsmittelperson_res = $this->getBetriebsmittelInfo($pid); + $profilUpdates = $this->getProfilUpdates($uid); + $telefon_res = $this->getTelefonInfo($uid); + $mitarbeiter_res = $this->getMitarbeiterInfo($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Mitarbeiter Information + foreach ($mitarbeiter_res as $key => $value) { + $res->$key = $value; + } + + $res->adressen = $adresse_res; + $res->zutrittsdatum = $zutrittskarte_ausgegebenam; + $res->kontakte = $kontakte_res; + $res->mittel = $betriebsmittelperson_res; + $res->mailverteiler = $mailverteiler_res; + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = DOMAIN? $uid . "@" . DOMAIN : ""; + $extern_email = array(); + $extern_email["type"] = "alias"; + + $extern_email["email"] = $mitarbeiter_res->alias? ($mitarbeiter_res->alias . "@" . DOMAIN) : null; + $res->emails = $extern_email["email"]?[$intern_email, $extern_email]:[$intern_email]; + + $res->funktionen = $benutzer_funktion_res; + $res->standort_telefon = $telefon_res; + $res->profilUpdates = $profilUpdates; + + return $res; + } + + /** + * gets the date of issue of the FH access card corresponding to a user + * @access private + * @param integer $uid the userID used to get the date of issue of the FH access card + * @return string the date of issue of the FH access card corresponding to a userID + */ + private function getZutrittskarteDatum($uid) + { + $this->ci->load->model("ressource/Betriebsmittelperson_model","BetriebsmittelpersonModel"); + $zutrittskarte_ausgegebenam = $this->ci->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte"); + + if(isError($zutrittskarte_ausgegebenam)){ + return error(getData($zutrittskarte_ausgegebenam)); + } + $zutrittskarte_ausgegebenam = getData($zutrittskarte_ausgegebenam); + $zutrittskarte_ausgegebenam = $zutrittskarte_ausgegebenam ? current($zutrittskarte_ausgegebenam)->ausgegebenam : null; + + //? formats date from 01-01-2000 to 01.01.2000 + $zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam); + return $zutrittskarte_ausgegebenam; + } + + /** + * gets the address information corresponding to a user + * @access private + * @param integer $uid the userID used to get the address information + * @return array all the address information corresponding to a userID + */ + private function getAdressenInfo($pid) + { + $this->ci->load->model("person/Adresse_model","AdresseModel"); + $adresse_res = $this->ci->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]); + $adresse_res = $this->ci->AdresseModel->addOrder("zustelladresse", "DESC"); + $adresse_res = $this->ci->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz"); + + $adresse_res = $this->ci->AdresseModel->loadWhere(["person_id" => $pid]); + if(isError($adresse_res)){ + return error(getData($adresse_res)); + } + $adresse_res = getData($adresse_res) ?? []; + return $adresse_res; + } + + /** + * gets the kontakt information corresponding to a user + * @access private + * @param integer $uid the userID used to get the kontakt information + * @return array all the kontakt information corresponding to a userID + */ + private function getKontaktInfo($pid) + { + $this->ci->load->model("person/Kontakt_model","KontaktModel"); + $this->ci->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']); + $this->ci->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT'); + $this->ci->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT'); + $this->ci->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum'); + + $kontakte_res = $this->ci->KontaktModel->loadWhere(['person_id' => $pid]); + if(isError($kontakte_res)){ + return error(getData($kontakte_res)); + } + $kontakte_res = getData($kontakte_res); + return $kontakte_res; + } + + /** + * gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe + * @access private + * @param integer $uid the userID used to retrieve the mailverteiler + * @return array returns the mailvertailer corresponding to a userID + */ + private function getMailverteiler($uid) + { + $this->ci->load->model("person/Person_model","PersonModel"); + $this->ci->PersonModel->addSelect('gruppe_kurzbz, beschreibung'); + $this->ci->PersonModel->addJoin('tbl_benutzer', 'person_id'); + $this->ci->PersonModel->addJoin('tbl_benutzergruppe', 'uid'); + $this->ci->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); + + $mailverteiler_res = $this->ci->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid)); + if(isError($mailverteiler_res)){ + return error(getData($mailverteiler_res)); + } + $mailverteiler_res = getData($mailverteiler_res) ?? []; + $mailverteiler_res = gettype($mailverteiler_res) === 'array' ? $mailverteiler_res : []; + $mailverteiler_res = array_map(function ($element) { + $element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN; + return $element; + }, $mailverteiler_res); + return $mailverteiler_res; + } + + /** + * gets the person information corresponding to a user + * @access private + * @param integer $uid the userID used to get the person information + * @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not + * @return array all the person informaion corresponding to a userID + */ + private function getPersonInfo($uid, $geburtsInfo = null) + { + $this->ci->load->model("person/Benutzer_model","BenutzerModel"); + $selectClause = ["foto", "foto_sperre", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"]; + /** @param integer $geburtsInfo */ + if ($geburtsInfo) { + array_push($selectClause, "gebort"); + array_push($selectClause, "TO_CHAR(gebdatum, 'DD.MM.YYYY') as gebdatum"); + } + $this->ci->BenutzerModel->addSelect($selectClause); + $this->ci->BenutzerModel->addJoin("tbl_person", "person_id"); + + $person_res = $this->ci->BenutzerModel->load([$uid]); + if(isError($person_res)){ + return error(getData($person_res)); + } + $person_res = getData($person_res); + $person_res = $person_res ? current($person_res) : null; + + if(isset($person_res)){ + if( ($person_res->foto === null) || ((getAuthUID() !== $uid) && ($person_res->foto_sperre !== false)) ) + { + $dummy_foto = base64_encode(file_get_contents(DOC_ROOT.'skin/images/profilbild_dummy.jpg')); + $person_res->foto = $dummy_foto; + } + } + + return $person_res; + } + + /** + * gets all the Benutzerfunktionen of a corresponding user + * @access private + * @param integer $uid the userID used to retrieve the Benutzerfunktionen + * @return array returns the Benutzerfunktionen corresponding to a userID + */ + private function getBenutzerFunktion($uid) + { + $this->ci->load->model("person/Benutzerfunktion_model","BenutzerfunktionModel"); + $this->ci->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]); + $this->ci->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz"); + + $benutzer_funktion_res = $this->ci->BenutzerfunktionModel->loadWhere(array('uid' => $uid)); + if(isError($benutzer_funktion_res)){ + return error(getData($benutzer_funktion_res)); + } + $benutzer_funktion_res = getData($benutzer_funktion_res); + return $benutzer_funktion_res; + } + + /** + * gets all the Betriebsmittel of a corresponding user + * @access private + * @param integer $uid the userID used to retrieve the Betriebsmittel + * @return array returns the Betriebsmittel corresponding to a userID + */ + private function getBetriebsmittelInfo($pid) + { + $this->ci->load->model("ressource/Betriebsmittelperson_model","BetriebsmittelpersonModel"); + $this->ci->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]); + + //? betriebsmittel are not needed in a view + $betriebsmittelperson_res = $this->ci->BetriebsmittelpersonModel->getBetriebsmittel($pid); + if(isError($betriebsmittelperson_res)){ + return error(getData($betriebsmittelperson_res)); + } + $betriebsmittelperson_res = getData($betriebsmittelperson_res); + return $betriebsmittelperson_res; + } + + /** + * gets the profil updates corresponding to a user + * @access private + * @param integer $uid the userID used to get the profil updates + * @return array all the profil updates corresponding to a userID + */ + private function getProfilUpdates($uid) + { + $this->ci->load->model("person/Profil_update_model","ProfilUpdateModel"); + $profilUpdates = $this->ci->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]); + if(isError($profilUpdates)){ + return error(getData($profilUpdates)); + } + $profilUpdates = getData($profilUpdates); + return $profilUpdates; + } + + /** + * gets the telefon information corresponding to a user + * @access private + * @param integer $uid the userID used to get the telefon information + * @return array all the telefon informaion corresponding to a userID + */ + private function getTelefonInfo($uid) + { + $this->ci->load->model("ressource/Mitarbeiter_model","MitarbeiterModel"); + $this->ci->MitarbeiterModel->addSelect(["kontakt"]); + $this->ci->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id"); + $this->ci->MitarbeiterModel->addLimit(1); + $telefon_res = $this->ci->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]); + if(isError($telefon_res)){ + return error(getData($telefon_res)); + } + $telefon_res = getData($telefon_res); + $telefon_res = $telefon_res ? current($telefon_res) : null; + return $telefon_res; + } + + /** + * gets the mitarbeiter information corresponding to a user + * @access private + * @param integer $uid the userID used to get the mitarbeiter information + * @return array all the mitarbeiter informaion corresponding to a userID + */ + private function getMitarbeiterInfo($uid) + { + $this->ci->load->model("ressource/Mitarbeiter_model","MitarbeiterModel"); + $this->ci->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]); + $this->ci->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid"); + $mitarbeiter_res = $this->ci->MitarbeiterModel->load($uid); + if(isError($mitarbeiter_res)){ + return error(getData($mitarbeiter_res)); + } + $mitarbeiter_res = getData($mitarbeiter_res); + $mitarbeiter_res = $mitarbeiter_res ? current($mitarbeiter_res) : null; + + return $mitarbeiter_res; + } + + /** + * gets the Zutrittsgruppen corresponding to a user + * @access private + * @param integer $uid the userID used to get the Zutrittsgruppen + * @return array all the Zutrittsgruppen corresponding to a userID + */ + private function getZutrittsgruppen($uid) + { + $this->ci->load->model("person/Benutzergruppe_model","BenutzergruppeModel"); + $this->ci->BenutzergruppeModel->addSelect(['bezeichnung']); + $this->ci->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz'); + + $zutrittsgruppe_res = $this->ci->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true)); + if(isError($zutrittsgruppe_res)){ + return error(getData($zutrittsgruppe_res)); + } + $zutrittsgruppe_res = getData($zutrittsgruppe_res); + return $zutrittsgruppe_res; + } + + /** + * gets the student information corresponding to a user + * @access private + * @param integer $uid the userID used to get the student information + * @return array all the student informaion corresponding to a userID + */ + private function getStudentInfo($uid) + { + $this->ci->load->model("crm/Student_model","StudentModel"); + $this->ci->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_studiengang.studiengang_kz as studiengang_kz', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']); + $this->ci->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz"); + + $student_res = $this->ci->StudentModel->load([$uid]); + + if(isError($student_res)){ + return error(getData($student_res)); + } + $student_res = getData($student_res); + $student_res = $student_res ? current($student_res) : null; + return $student_res; + } + + /** + * gets the Matrikelnummer corresponding to a user + * @access private + * @param integer $uid the userID used to get the Matrikelnummer + * @return object the Matrikelnummer corresponding to a userID + */ + private function getMatrikelNummer($uid) + { + $this->ci->load->model("person/Benutzer_model","BenutzerModel"); + $this->ci->BenutzerModel->addSelect(["matr_nr"]); + $this->ci->BenutzerModel->addJoin("tbl_person", "person_id"); + + $matr_res = $this->ci->BenutzerModel->load([$uid]); + + if(isError($matr_res)){ + return error(getData($matr_res)); + } + $matr_res = getData($matr_res); + $matr_res = $matr_res ? current($matr_res) : []; + return $matr_res; + } + + /** + * checks whether the foto of a user is accepted or not + * @access private + * @param integer $pid the personId of the student or mitarbeiter + * @return bool whether the foto is accepted or not + */ + private function isFotoAkzeptiert($pid) + { + $this->ci->load->model('person/Fotostatusperson_model','FotostatusModel'); + $fotostatus = $this->ci->FotostatusModel->execReadOnlyQuery(" + select distinct on (person_id) person_id, insertamum, fotostatus_kurzbz + from public.tbl_person_fotostatus + where person_id = ? + order by person_id, insertamum desc",[$pid]); + if(isError($fotostatus)){ + return error(getData($fotostatus)); + } + $fotostatus = getData($fotostatus); + if(is_array($fotostatus) && count($fotostatus) > 0){ + $fotostatus = current($fotostatus)->fotostatus_kurzbz == 'akzeptiert'; + } + else + $fotostatus = false; + return $fotostatus; + } + + /** + * function that returns the data used for viewing another mitarbeiter profile + * @access private + * @param integer $uid the userID to retrieve the mitarbeiter data + * @return stdClass restricted mitarbeiter data + */ + private function viewMitarbeiterProfil($uid) + { + $mailverteiler_res = $this->getMailverteiler($uid); + $benutzer_funktion_res = $this->getBenutzerFunktion($uid); + $benutzer_res = $this->getBenutzerAlias($uid); + $person_res = $this->getPersonInfo($uid); + $mitarbeiter_res = $this->getMitarbeiterInfo($uid); + $telefon_res = $this->getTelefonInfo($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Info + foreach ($person_res as $key => $val) { + $res->$key = $val; + } + + //? Mitarbeiter Info + foreach ($mitarbeiter_res as $key => $val) { + $res->$key = $val; + + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = DOMAIN? $uid . "@" . DOMAIN:""; + $extern_email = array(); + $extern_email["type"] = "alias"; + + $extern_email["email"] = $benutzer_res->alias ? ($benutzer_res->alias . "@" . DOMAIN) : null; + $res->emails = $extern_email?[$intern_email, $extern_email]:[$intern_email]; + + $res->funktionen = $benutzer_funktion_res; + $res->mailverteiler = $mailverteiler_res; + $res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null; + + return $res; + } + + /** + * gets the alias of a corresponding user + * @access private + * @param integer $uid the userID used to get the alias + * @return string the alias of the userID + */ + private function getBenutzerAlias($uid) + { + $this->ci->load->model("person/Benutzer_model","BenutzerModel"); + $this->ci->BenutzerModel->addSelect(["alias"]); + $benutzer_res = $this->ci->BenutzerModel->load([$uid]); + if(isError($benutzer_res)){ + return error(getData($benutzer_res)); + } + + $benutzer_res = getData($benutzer_res); + $benutzer_res = $benutzer_res ? current($benutzer_res) : null; + + return $benutzer_res; + } + + /** + * function that returns the data used for viewing another student profile + * @access private + * @param integer $uid the userID to retrieve the student data + * @return stdClass restricted student data + */ + private function viewStudentProfil($uid) + { + $mailverteiler_res = $this->getMailverteiler($uid); + $person_res = $this->getPersonInfo($uid); + $student_res = $this->getStudentInfo($uid); + $matr_res = $this->getMatrikelNummer($uid); + + $res = new stdClass(); + $res->username = $uid; + + //? Person Information + foreach ($person_res as $key => $value) { + $res->$key = $value; + } + + //? Student Information + foreach ($student_res as $key => $value) { + $res->$key = $value; + } + + $intern_email = array(); + $intern_email["type"] = "intern"; + $intern_email["email"] = DOMAIN? $uid . "@" . DOMAIN:""; + + $res->emails = [$intern_email]; + $res->matrikelnummer = $matr_res->matr_nr; + $res->mailverteiler = $mailverteiler_res; + + return $res; + } +} \ No newline at end of file diff --git a/application/libraries/SearchBarLib.php b/application/libraries/SearchBarLib.php index 13b0efdbb..f19365c02 100644 --- a/application/libraries/SearchBarLib.php +++ b/application/libraries/SearchBarLib.php @@ -115,6 +115,7 @@ class SearchBarLib $sql = ' SELECT + \'employee\' AS renderer, \''.$type.'\' AS type, b.uid AS uid, p.person_id AS person_id, @@ -205,6 +206,7 @@ EOSC; $employees = $dbModel->execReadOnlyQuery(' SELECT + \'employee\' AS renderer, \''.$type.'\' AS type, b.uid AS uid, p.person_id AS person_id, @@ -268,6 +270,7 @@ EOSC; $ous = $dbModel->execReadOnlyQuery(' SELECT + \'' . $type . '\' AS renderer, \''.$type.'\' AS type, o.oe_kurzbz AS oe_kurzbz, \'[\' || ot.bezeichnung || \'] \' || o.bezeichnung AS name, @@ -365,6 +368,7 @@ EOSC; $gesperrtes_foto = base64_encode(file_get_contents(DOC_ROOT.'skin/images/profilbild_dummy.jpg')); $students = $dbModel->execReadOnlyQuery(' SELECT + \'' . $type . '\' AS renderer, \''.$type.'\' AS type, s.student_uid AS uid, CONCAT(s.student_uid,\'@'.DOMAIN.'\') AS email, @@ -413,6 +417,7 @@ EOSC; $students = $dbModel->execReadOnlyQuery(' SELECT + \'student\' AS renderer, \''.$type.'\' AS type, s.student_uid AS uid, s.matrikelnr, @@ -458,6 +463,7 @@ EOSC; $prestudent = $dbModel->execReadOnlyQuery(' SELECT + \'' . $type . '\' AS renderer, \''.$type.'\' AS type, ps.prestudent_id, ps.studiengang_kz, @@ -517,6 +523,7 @@ EOSC; $rooms = $dbModel->execReadOnlyQuery(' SELECT + \'room\' AS renderer, \''.$type.'\' AS type, COALESCE(ort.ort_kurzbz, \'N/A\') as ort_kurzbz, COALESCE(ort.gebteil, \'N/A\') as building, diff --git a/application/libraries/SearchLib.php b/application/libraries/SearchLib.php new file mode 100644 index 000000000..24894eab5 --- /dev/null +++ b/application/libraries/SearchLib.php @@ -0,0 +1,1091 @@ +. + */ + +if (! defined('BASEPATH')) exit('No direct script access allowed'); + +use \stdClass as stdClass; + +/** + * This is a alternative for SearchBarLib for advanced searches + */ +class SearchLib +{ + // Error constats + const ERROR_WRONG_JSON = 'ERR001'; + const ERROR_WRONG_SEARCHSTR = 'ERR002'; + const ERROR_NO_TYPES = 'ERR003'; + const ERROR_WRONG_TYPES = 'ERR004'; + const ERROR_NOT_AUTH = 'ERR005'; + + private $_ci; // Code igniter instance + + private $_searchfunction_priorities = []; + private $_numeric_searchfunctions = []; + private $_allowed_searchfunctions = []; + + /** + * Gets the CI instance and loads model + * + * @param array $params + * @return void + */ + public function __construct($params = null) + { + $this->_ci =& get_instance(); // get code igniter instance + + $config = $params['config'] ?? null; + // It is loaded only to have the DB functions available + $this->_ci->load->model('person/Benutzer_model', 'BenutzerModel'); + + // Load Config + $this->_ci->load->config('search', true, (boolean)$config); + $this->_ci->load->config('searchfunctions', true); + if ($config) { + $this->_ci->load->config($config, true); + $this->_ci->config->set_item('search', $this->_ci->config->item($config)); + } + + $this->_ci->load->library('PhrasesLib', [['search'], null], 'search_phrases'); + + // Precompute helper arrays + foreach ($this->_ci->config->item('searchfunctions') as $key => $arr) { + $this->_searchfunction_priorities[$key] = $arr['priority']; + if ($arr['force_integer'] ?? false) + $this->_numeric_searchfunctions[] = $key; + $this->_allowed_searchfunctions[] = $key; + } + } + + //------------------------------------------------------------------------------------------------------------------ + // Public methods + + /** + * It performes the search of the given search string using the specified search types + * + * @param string $searchstring + * @param array $types (optional) + * + * @return stdClass containing an array with the result on index 0 + * and the overall query time on index 1. + */ + public function search($searchstring, $types = []) + { + if (!$types) { + $types = $this->_ci->config->item('search'); + } else { + $tmp = []; + $missing = []; + foreach ($types as $type) { + $typeconfig = $this->_ci->config->item($type, 'search'); + if (!$typeconfig) { + $missing[] = $type; + } else { + $tmp[$type] = $typeconfig; + } + } + if ($missing) { + $p = $this->_ci->search_phrases; + return error(array_map(function ($type) use ($p) { + return $p->t('search', 'error_missing_config', [ + 'type' => $type + ]); + }, $missing)); + } + $types = $tmp; + } + + + // Convert searchstring into array + list($searchArray, $searchstring) = $this->_convertQuery($searchstring, $types); + + + $sql = $this->getDynamicSearchSqls($searchArray, array_keys($types)); + if (isError($sql)) + return $sql; + if (!hasData($sql)) { + $retval = success([]); + $retval->meta = ['time' => 0, 'searchstring' => $searchstring]; + return $retval; + } + + $msc = microtime(true); + $result = $this->_ci->BenutzerModel->execReadOnlyQuery(getData($sql)); + $msc = microtime(true) - $msc; + + if (isError($result)) + return $result; + + $retval = success($result->retval); + $retval->meta = [ + 'time' => $msc, + 'searchstring' => $searchstring + ]; + + return $retval; + } + + /** + * Generates the search query for the given search string and the + * specified search type. + * + * @param array $searchArray + * @param string $table + * + * @return stdClass containing the query string. + */ + public function getDynamicSearchSql($searchArray, $table) + { + $res = $this->checkConfig($table); + if (isError($res)) + return $res; + $table_config = getData($res); + + $sql_with = []; + + $sql_select = $this->prepareDynamicSearchSql($sql_with, $searchArray, $table); + + if (!$sql_select) + return success(""); + + $lang = getUserLanguage(); + + $output = "WITH"; + if ($sql_with && $sql_with[0] === 'RECURSIVE') { + $output .= " RECURSIVE"; + array_shift($sql_with); + } + + $output .= " + lang (index) AS ( + SELECT index + FROM public.tbl_sprache + WHERE sprache=" . $this->_ci->db->escape($lang) . " + LIMIT 1 + ), + auth (uid) AS ( + SELECT " . $this->_ci->db->escape(getAuthUID()) . " AS uid + )"; + + if ($sql_with) { + $sql_with = array_unique($sql_with); + $output .= ", " . implode(", ", $sql_with); + } + + $other_selects = ""; + if (isset($table_config['resultfields'])) + $other_selects = implode(", ", $table_config['resultfields']); + if ($other_selects) + $other_selects = ", " . $other_selects; + + $output .= " + , q (" . $this->_formatPrimarykeys($table_config['primarykey']) . ", rank) AS ( + SELECT " . $this->_formatPrimarykeys($table_config['primarykey']) . ", MAX(rank) + FROM (" . implode(" UNION ", $sql_select) . ") q + GROUP BY " . $this->_formatPrimarykeys($table_config['primarykey']) . " + ) + SELECT + " . $this->_ci->db->escape($table) . " AS type, + q.rank + " . $other_selects . " + FROM q + " . ($table_config['resultjoin'] ?? "") . " + ORDER BY rank DESC + "; + + return success($output); + } + + /** + * Generates the search query for the given search string and the + * specified search types. + * + * @param array $searchArray + * @param array $types + * + * @return stdClass containing the query string. + */ + public function getDynamicSearchSqls($searchArray, $types) + { + $with = []; + $selects = []; + foreach ($types as $type) { + $res = $this->checkConfig($type); + if (isError($res)) + return $res; + $table_config = getData($res); + + $select = $this->prepareDynamicSearchSql($with, $searchArray, $type); + if (!$select) + continue; + + $with[] = "final_" . $type . " (" . $this->_formatPrimarykeys($table_config['primarykey']) . ", rank) AS ( + SELECT " . $this->_formatPrimarykeys($table_config['primarykey']) . ", MAX(rank) + FROM (" . implode(" UNION ", $select) . ") q + GROUP BY " . $this->_formatPrimarykeys($table_config['primarykey']) . " + )"; + + $renderer = $table_config['renderer'] ?? $type; + $selects[] = " + SELECT + " . $this->_ci->db->escape($renderer) . " AS renderer, + " . $this->_ci->db->escape($type) . " AS type, + rank, + TO_JSONB((SELECT x FROM (SELECT " . implode(", ", $table_config['resultfields'] ?? ['*']) . ") x)) AS data + FROM final_" . $type . " + " . ($table_config['resultjoin'] ?? ""); + } + + if (!$selects) + return success(""); + + $recursive = ""; + if ($with && $with[0] === "RECURSIVE") { + $recursive = "RECURSIVE "; + array_shift($with); + } + + $with = array_unique($with); + + $lang = getUserLanguage(); + array_unshift($with, "lang (index) AS ( + SELECT index + FROM public.tbl_sprache + WHERE sprache=" . $this->_ci->db->escape($lang) . " + LIMIT 1 + )"); + array_unshift($with, "auth (uid) AS ( + SELECT " . $this->_ci->db->escape(getAuthUID()) . " AS uid + )"); + + return success(" + WITH " . $recursive . implode(", ", $with) . " + SELECT * + FROM (" . implode(" UNION ", $selects) . ") q + ORDER BY rank DESC + LIMIT 100 + "); + } + + //------------------------------------------------------------------------------------------------------------------ + // Protected methods + + /** + * Check config + * + * @param string $name + * + * @return stdClass + */ + protected function checkConfig($name) + { + $table_config = $this->_ci->config->item($name, 'search'); + + if (!$table_config) + return error($this->_ci->search_phrases->t('search', 'error_missing_config', [ + 'type' => $name + ])); + + $errors = []; + if (!isset($table_config['table']) + || !is_string($table_config['table']) + || !$table_config['table'] + ) { + $errors[] = $this->_ci->search_phrases->t('search', 'error_invalid_config', [ + 'type' => $name, + 'field' => 'table' + ]); + } + if (!isset($table_config['primarykey']) + || !is_string($table_config['primarykey']) + || !$table_config['primarykey'] + ) { + $errors[] = $this->_ci->search_phrases->t('search', 'error_invalid_config', [ + 'type' => $name, + 'field' => 'primarykey' + ]); + } + if (!isset($table_config['resultfields']) + || !is_array($table_config['resultfields']) + || !$table_config['resultfields'] + ) { + $errors[] = $this->_ci->search_phrases->t('search', 'error_invalid_config', [ + 'type' => $name, + 'field' => 'resultfields' + ]); + } + if (!isset($table_config['searchfields']) + || !is_array($table_config['searchfields']) + || !$table_config['searchfields'] + ) { + $errors[] = $this->_ci->search_phrases->t('search', 'error_invalid_config', [ + 'type' => $name, + 'field' => 'searchfields' + ]); + } else { + foreach ($table_config['searchfields'] as $searchfield => $config) { + if (!isset($config['field']) + || !is_string($config['field']) + || !$config['field'] + ) { + $errors[] = $this->_ci->search_phrases->t('search', 'error_invalid_config_searchfield', [ + 'type' => $name, + 'searchfield' => $searchfield, + 'field' => 'field' + ]); + } + if (!isset($config['comparison']) + || !is_string($config['comparison']) + || !in_array($config['comparison'], $this->_allowed_searchfunctions) + ) { + $errors[] = $this->_ci->search_phrases->t('search', 'error_invalid_config_searchfield', [ + 'type' => $name, + 'searchfield' => $searchfield, + 'field' => 'comparison' + ]); + } + } + } + + if ($errors) + return error($errors); + + return success($table_config); + } + + /** + * Generates the with statements for the given search string and the + * specified search type. + * + * @param array &$sqlWith + * @param array $searchArray + * @param string $table + * + * @return string a query string or the name of the prepared select. + */ + protected function prepareDynamicSearchSql(&$sqlWith, $searchArray, $table) + { + $table_config = $this->_ci->config->item($table, 'search'); + + $id_offset = count($sqlWith); + + + $allowed_codes_w_order = ['' => 0, '!' => -1]; + $max = max($this->_searchfunction_priorities); + foreach ($table_config['searchfields'] as $code => $config) { + $allowed_codes_w_order[$code] = $this->_searchfunction_priorities[$config['comparison']]; + $allowed_codes_w_order['!' . $code] = $this->_searchfunction_priorities[$config['comparison']] - $max - 2; + } + + $check_order = $this->_searchfunction_priorities; + uasort($table_config['searchfields'], function ($a, $b) use ($check_order) { + return $check_order[$b['comparison']] - $check_order[$a['comparison']]; + }); + + $integer_functions = $this->_numeric_searchfunctions; + $integer_fields = array_keys(array_filter($table_config['searchfields'], function ($a) use ($integer_functions) { + return in_array($a['comparison'], $integer_functions); + })); + + $only_integer_fields = count($integer_fields) == count($table_config['searchfields']); + + $aliases = []; + foreach ($table_config['searchfields'] as $field => $config) { + if (isset($config['alias'])) { + foreach ($config['alias'] as $alias) { + $aliases[$alias] = $field; + $aliases['!' . $alias] = '!' . $field; + } + } + } + + $sql_select = []; + + if (isset($table_config['prepare'])) { + $this->_addPreparesToSqlWith($sqlWith, $table_config['prepare']); + } + + foreach ($searchArray as $or_search) { + if (isset($or_search['-filter']) && !in_array($table, $or_search['-filter'])) + continue; + unset($or_search['-filter']); + + foreach ($aliases as $alias => $field) { + if (isset($or_search[$alias])) { + $or_search[$field] = array_merge($or_search[$alias], $or_search[$field] ?? []); + unset($or_search[$alias]); + } + } + + // NOTE(chris): early out if not allowed fields are in the search array + $used_codes = array_keys($or_search); + if (count(array_intersect($used_codes, array_keys($allowed_codes_w_order))) != count($used_codes)) + continue; + + // NOTE(chris): expand general excludes to all fields + if (isset($or_search['!'])) { + $not = $or_search['!']; + unset($or_search['!']); + foreach ($table_config['searchfields'] as $code => $config) { + if (isset($or_search['!' . $code])) + $or_search['!' . $code] = array_unique(array_merge($or_search['!' . $code], $not)); + else + $or_search['!' . $code] = $not; + } + } + + // NOTE(chris): early out if all searchfields require an integer and at least one searchword is not a number + if ($only_integer_fields + && isset($or_search[""]) + && $this->_hasAtLeastOneNaN($or_search[""]) + ) { + continue; + } + + $skip = false; + foreach ($integer_fields as $code) { + // NOTE(chris): filter non integer for integer fields + if (isset($or_search['!' . $code])) { + $or_search['!' . $code] = array_filter($or_search['!' . $code], function ($a) { + return is_numeric($a); + }); + if (!$or_search['!' . $code]) + unset($or_search['!' . $code]); + } + // NOTE(chris): early out if a searchword that is not a number is compared to a searchfield that requires an integer + if (isset($or_search[$code]) + && $this->_hasAtLeastOneNaN($or_search[$code]) + ) { + $skip = true; + break; + } + } + if ($skip) + continue; + + // NOTE(chris): sort for performance reasons + uksort($or_search, function ($a, $b) use ($allowed_codes_w_order) { + return $allowed_codes_w_order[$b] - $allowed_codes_w_order[$a]; + }); + + $or_with = []; + $or_select = []; + $or_prepare = []; + + if (substr(key($or_search), 0, 1) == '!') { + // NOTE(chris): only negative searchwords + $sql = []; + foreach ($or_search as $code => $words) { + $code = substr($code, 1); + // NOTE(chris): sort for performance reasons + usort($words, function ($a, $b) { + return strlen($b) - strlen($a); + }); + $field_config = $table_config['searchfields'][$code]; + + if (isset($field_config['prepare'])) { + $this->_addPreparesToSqlWith($or_with, $field_config['prepare']); + $or_prepare[$code] = $field_config['prepare']; + unset($table_config['searchfields'][$code]['prepare']); + unset($field_config['prepare']); + } + $field_sql = " + SELECT + " . $this->_formatPrimarykeys($table_config['primarykey'], $table_config['table']) . " + FROM " . $table_config['table'] . " + " . $this->_makeJoin($field_config['join'] ?? '') . " + WHERE "; + foreach ($words as $word) { + $sql[] = $field_sql . $this->_makeCompareBool($field_config['comparison'], $field_config['field'], $word); + } + } + + $or_select[] = " + SELECT + " . $this->_formatPrimarykeys($table_config['primarykey'], $table_config['table']) . ", + 1.0 AS rank + FROM " . $table_config['table'] . " + WHERE " . $table_config['primarykey'] . " NOT IN (" . implode(" UNION ", $sql) . ")"; + } else { + $current_select = false; + $count = 0; + $skip = false; + foreach ($or_search as $code => $words) { + // NOTE(chris): sort for performance reasons + if ($code && substr($code, 0, 1) == '!') { + usort($words, function ($a, $b) { + return strlen($a) - strlen($b); + }); + } else { + usort($words, function ($a, $b) { + return strlen($b) - strlen($a); + }); + } + if ($code == '') { + foreach ($words as $i => $word) { + $field_sql = []; + foreach ($table_config['searchfields'] as $c => $field_config) { + if (in_array($field_config['comparison'], $integer_functions) && !is_numeric($word)) + continue; + + $word_from = $table_config['table']; + $word_join = ""; + $word_rank = "0"; + if ($current_select) { + $word_from = $current_select; + if ($this->_needBasicTableJoin($field_config['field'], $table_config['primarykey'])) { + $word_join .= " " . $this->_makeJoin($table_config); + } + $word_rank = "rank"; + } + if (isset($field_config['prepare'])) { + $this->_addPreparesToSqlWith($or_with, $field_config['prepare']); + $or_prepare[$c] = $field_config['prepare']; + unset($table_config['searchfields'][$c]['prepare']); + unset($field_config['prepare']); + } + if (isset($field_config['join'])) { + $word_join .= " " . $this->_makeJoin($field_config['join']); + } + $field_sql[] = " + SELECT + " . $this->_formatPrimarykeys($table_config['primarykey'], $word_from) . ", + " . $word_rank . " AS w_rank, + " . $this->_makeRank($field_config['comparison'], $field_config['field'], $word) . " AS rank + FROM " . $word_from . " + " . $word_join . " + WHERE " . $this->_makeCompare($field_config['comparison'], $field_config['field'], $word); + } + // NOTE(chris): skip because the word is not numeric but all searchfields require integers + if (!$field_sql) { + $or_with = []; + $or_select = []; + $count = 0; + $skip = true; + foreach ($or_prepare as $k => $v) + $table_config['searchfields'][$k]['prepare'] = $v; + break; + } + + $id = "w" . ($id_offset + count($or_with)); + $or_with[] = " + " . $id . " (" . $this->_formatPrimarykeys($table_config['primarykey']) . ", rank) AS ( + SELECT + " . $this->_formatPrimarykeys($table_config['primarykey']) . ", + (w_rank + 1.0 - CASE " . + "WHEN MIN(rank) = 0 THEN 0 " . + "ELSE EXP(SUM(LN(CASE WHEN rank = 0 THEN 1 ELSE rank " . + "END))) END) AS rank + FROM (" . implode(' UNION ALL ', $field_sql) . ") " . $id . " + GROUP BY " . $this->_formatPrimarykeys($table_config['primarykey']) . ", w_rank + )"; + $current_select = $id; + } + } else { + foreach ($words as $i => $word) { + $where = ""; + $rank = ""; + $jointype = ""; + if (substr($code, 0, 1) == '!') { + $c = substr($code, 1); + $field_config = $table_config['searchfields'][$c]; + + $rank = "1"; + + $jointype = "LEFT"; + + $where = $field_config['field'] . + " IS NULL OR NOT (" . + $this->_makeCompareBool( + $field_config['comparison'], + $field_config['field'], + $word + ) . + ")"; + if ($field_config['1-n'] ?? false) { + $where = "GROUP BY " . + $this->_formatPrimarykeys($table_config['primarykey'], $current_select ?: $table_config['table']) . + ", rank HAVING MIN(CASE WHEN " . + $where . + " THEN 1 ELSE 0 END) = 1"; + } else { + $where = "WHERE " . $where; + } + } else { + $field_config = $table_config['searchfields'][$code]; + + $rank = $this->_makeRank($field_config['comparison'], $field_config['field'], $word); + + $where = $this->_makeCompare($field_config['comparison'], $field_config['field'], $word); + $where = "WHERE " . $where; + } + $word_from = $table_config['table']; + $word_join = ""; + $word_rank = ""; + if ($current_select) { + $word_from = $current_select; + if ($this->_needBasicTableJoin($field_config['field'], $table_config['primarykey'])) { + $word_join .= " " . $this->_makeJoin($table_config); + } + $word_rank = "rank + "; + } + if (isset($field_config['prepare'])) { + $this->_addPreparesToSqlWith($or_with, $field_config['prepare']); + $or_prepare[$code] = $field_config['prepare']; + unset($table_config['searchfields'][$code]['prepare']); + unset($field_config['prepare']); + } + if (isset($field_config['join'])) { + $word_join .= " " . $this->_makeJoin($field_config['join'], $jointype); + } + + $id = "w" . ($id_offset + count($or_with)); + $or_with[] = " + " . $id . " (" . $this->_formatPrimarykeys($table_config['primarykey']) . ", rank) AS ( + SELECT + " . $this->_formatPrimarykeys($table_config['primarykey'], $word_from) . ", + " . $word_rank . $rank . " AS rank + FROM " . $word_from . " + " . $word_join . " + " . $where . " + )"; + $current_select = $id; + } + } + if ($skip) + break; + $count += count($words); + } + + if (!$count || !$current_select) + continue; + + $or_select[] = " + SELECT " . $this->_formatPrimarykeys($table_config['primarykey']) . ", rank / " . $count . " AS rank FROM " . $current_select; + } + + if ($or_with[0] === "RECURSIVE") + { + if (empty($sqlWith) || $sqlWith[0] !== "RECURSIVE") + array_unshift($sqlWith, "RECURSIVE"); + array_shift($or_with); + } + + $sqlWith = array_merge($sqlWith, $or_with); + $sql_select = array_merge($sql_select, $or_select); + $id_offset += count($or_with); + } + + return $sql_select; + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Checks if the field is not one of the primarykeys. + * + * @param string $field + * @param array|string $primarykeys + * + * @return boolean + */ + private function _needBasicTableJoin($field, $primarykeys) + { + if (!is_array($primarykeys) && strpos($primarykeys, ",") !== false) { + return $field != $primarykeys; + } + if (!is_array($primarykeys)) + $primarykeys = explode(",", $primarykeys); + + foreach ($primarykeys as $key) { + if ($field == trim($key)) + return false; + } + return true; + } + + /** + * Returns comma separated primarykeys. Optionally with table prefix + * + * @param array|string $primarykeys + * @param string $prefix + * + * @return string + */ + private function _formatPrimarykeys($primarykeys, $prefix = "") + { + if (is_array($primarykeys)) { + if ($prefix) + $prefix .= "."; + return $prefix . implode(", " . $prefix, $primarykeys); + } + if (!$prefix) + return $primarykeys; + + return $prefix . "." . implode(", " . $prefix . ".", explode(",", $primarykeys)); + } + + /** + * Adds the prepare statement to the sqlWith stack and handles the + * "RECURSIVE" modifier + * + * @param array &$sqlWith + * @param array $prepares + * + * @return void + */ + private function _addPreparesToSqlWith(&$sqlWith, $prepares) + { + $recursive = $sqlWith[0] ?? "" === "RECURSIVE"; + if (!is_array($prepares)) + $prepares = [$prepares]; + + foreach ($prepares as $prep) { + $prep = trim($prep); + if (strtoupper(substr($prep, 0, 10)) === "RECURSIVE ") { + $recursive = true; + $sqlWith[] = substr($prep, 10); + } else { + $sqlWith[] = $prep; + } + } + if ($recursive && $sqlWith[0] !== "RECURSIVE") { + array_unshift($sqlWith, "RECURSIVE"); + } + } + + /** + * Checks if an array has at least on non numeric value. + * + * @param array $arr + * + * @return boolean + */ + private function _hasAtLeastOneNaN($arr) + { + foreach ($arr as $value) + if (!is_numeric($value)) + return true; + return false; + } + + /** + * Helper function for getDynamicSearchSql + * + * @param array $join + * @param string $prefix + * + * @return string + */ + private function _makeJoin($join, $prefix = "") + { + if (!is_array($join)) + return ""; + if (!isset($join['table'])) { + $output = []; + foreach ($join as $j) + $output[] = trim($this->_makeJoin($j, $prefix)); + return implode(" ", $output); + } + if (!isset($join['on']) && !isset($join['using']) && !isset($join['primarykey'])) + return ""; + $output = $prefix . " JOIN " . $join['table']; + + if (isset($join['using'])) + return $output . " USING (" . $join['using'] . ")"; + + if (isset($join['primarykey'])) + return $output . " USING (" . $join['primarykey'] . ")"; + + return $output . " ON (" . $join['on'] . ")"; + } + + /** + * Helper function for _makeRank, _makeCompare and _makeCompareBool + * + * @param string $function + * @param string $mode + * @param string $field + * @param string $word + * + * @return string + */ + private function _makeFunction($function, $mode, $field, $word) + { + $searchfunction = $this->_ci->config->item($mode, 'searchfunctions'); + + if (!$searchfunction) + return ""; + $tpl = $searchfunction[$function] ?? ""; + + if (strstr($tpl, '{field}')) + $tpl = str_replace('{field}', $field, $tpl); + + if (strstr($tpl, '{word}')) + $tpl = str_replace('{word}', $this->_ci->db->escape($word), $tpl); + if (strstr($tpl, '{like:word}')) + $tpl = str_replace('{like:word}', "'%" . $this->_ci->db->escape_like_str($word) . "%'", $tpl); + + return $tpl; + } + + /** + * Helper function for getDynamicSearchSql + * + * @param string $mode + * @param string $field + * @param string $word + * + * @return string + */ + private function _makeRank($mode, $field, $word) + { + return $this->_makeFunction('rank', $mode, $field, $word); + } + + /** + * Helper function for getDynamicSearchSql + * + * @param string $mode + * @param string $field + * @param string $word + * + * @return string + */ + private function _makeCompare($mode, $field, $word) + { + return $this->_makeFunction('compare', $mode, $field, $word); + } + + /** + * Helper function for getDynamicSearchSql + * + * @param string $mode + * @param string $field + * @param string $word + * + * @return string + */ + private function _makeCompareBool($mode, $field, $word) + { + $searchfunction = $this->_ci->config->item($mode, 'searchfunctions'); + + if (!$searchfunction) + return ""; + $function = isset($searchfunction['compare_boolean']) ? 'compare_boolean' : 'compare'; + return $this->_makeFunction($function, $mode, $field, $word); + } + + /** + * Converts the search string to an array. + * First level should be joined with an OR. + * Second level should be joined with an AND or AND NOT. + * It is an associative array where the key is a code for the field + * which the words should be compared with and the value is the array + * of words. + * Use AND NOT if the first letter in the key is "!". + * Use AND if the first letter in the key is not "!". + * E.g: + * If the key is: + * "": the words should be compared to all fields with AND. + * "!": the words should be compared to all fields with AND NOT. + * "somefield": the words should be compared to the field somefield with + * AND. + * "!somefield": the words should be compared to the field somefield with + * AND NOT. + * + * @param string $searchstring + * @param array $types + * + * @return array + */ + private function _convertQuery($searchstring, $types) + { + $searchAllTypes = count($types) == count($this->_ci->config->item('search')); + $allowedTypes = array_keys($types); + + $currentArray = []; + $outputArray = []; + $cleanStrings = []; + $cleanSearchstring = ''; + $filter = ['+' => [], '-' => []]; + $typeAliases = []; + + $tmp = explode(' ', strtolower($searchstring)); + while ($tmp) { + $chunk = trim(array_shift($tmp)); + if ($chunk == '') + continue; + + if (strpos($chunk, '"') !== false) { + $test = explode('"', $chunk); + if (count($test) > 2) { + $rest = implode('"', array_slice($test, 2)); + if ($rest) { + array_unshift($tmp, $rest); + $chunk = implode('"', array_slice($test, 0, 2)) . '"'; + } + } + if (count($test) == 2) { + while ($tmp && strpos($test[1], '"') === false) { + $test[1] .= ' ' . trim(array_shift($tmp)); + } + if (strpos($test[1], '"') === false) { + $chunk = implode('"', $test) . '"'; + } else { + $test2 = explode('"', $test[1], 2); + $chunk = $test[0] . '"' . $test2[0] . '"'; + if ($test2[1]) { + array_unshift($tmp, $test2[1]); + } + } + } + if (strpos($chunk, ' ') === false) { + $chunk = str_replace('"', '', $chunk); + } + } + + if ($chunk == 'or') { + $this->_convertQueryCleanupOr($currentArray, $cleanStrings, $filter, $searchAllTypes, $allowedTypes); + $filter = ['+' => [], '-' => []]; + if ($currentArray) { + $cleanSearchstring .= ($cleanSearchstring ? ' or ' : '') . implode(' ', $cleanStrings); + $cleanStrings = []; + $outputArray[] = $currentArray; + $currentArray = []; + } + continue; + } + + if ($chunk == ':' || $chunk == '-' || substr($chunk, -1) == ':') + continue; + + if ($chunk[0] == ':' || ($chunk[0] == '-' && $chunk[1] == ':')) { + if (!$typeAliases) { + foreach ($types as $type => $config) { + $typeAliases[$type] = $type; + if (isset($config['alias'])) { + foreach ($config['alias'] as $alias) { + if (!isset($typeAliases[$alias])) + $typeAliases[$alias] = $type; + } + } + } + } + + $test = explode(':', $chunk, 2); + if (isset($typeAliases[$test[1]])) + $chunk = $test[0] . ':' . $typeAliases[$test[1]]; + elseif ($test[0] == '-') + continue; + } + + if (in_array($chunk, $cleanStrings)) + continue; + + $cleanStrings[] = $chunk; + + $chunk = str_replace('"', '', $chunk); + $code = ''; + + if ($chunk[0] == '-') { + $code = '!'; + $chunk = substr($chunk, 1); + } + if (strpos($chunk, ':') !== false) { + $chunk = explode(':', $chunk, 2); + if (!$chunk[0]) { + $filter[$code ? '-' : '+'][] = $chunk[1]; + continue; + } + $code .= $chunk[0]; + $chunk = $chunk[1]; + } + + if (!isset($currentArray[$code])) + $currentArray[$code] = []; + + $currentArray[$code][] = $chunk; + } + + $this->_convertQueryCleanupOr($currentArray, $cleanStrings, $filter, $searchAllTypes, $allowedTypes); + if ($currentArray) { + $cleanSearchstring .= ($cleanSearchstring ? ' or ' : '') . implode(' ', $cleanStrings); + $outputArray[] = $currentArray; + } + return [$outputArray, $cleanSearchstring]; + } + + private function _convertQueryCleanupOr(&$currentArray, &$cleanStrings, $filter, $searchAllTypes, $allowedTypes) + { + if ($filter['+'] && $filter['-']) { + $double = array_intersect($filter['+'], $filter['-']); + if ($double) { + foreach ($double as $type) { + array_splice($cleanStrings, array_search(':' . $type, $cleanStrings), 1); + array_splice($cleanStrings, array_search('-:' . $type, $cleanStrings), 1); + } + $filter['+'] = array_diff($filter['+'], $double); + $filter['-'] = array_diff($filter['-'], $double); + } + if (!$filter['+'] && !$filter['-']) { + // All filters cancel each other out + $currentArray = []; + $cleanStrings = []; + return; + } + if ($filter['+']) { + foreach ($filter['-'] as $type) { + array_splice($cleanStrings, array_search('-:' . $type, $cleanStrings), 1); + } + $filter['-'] = []; + } + } + if ($filter['+']) { + $cleanFilter = array_intersect($allowedTypes, $filter['+']); + if (!$cleanFilter) { + // All filters are forbidden + $currentArray = []; + $cleanStrings = []; + return; + } + $forbiddenFilter = array_diff($cleanFilter, $filter['+']); + foreach ($forbiddenFilter as $type) { + array_splice($cleanStrings, array_search(':' . $type, $cleanStrings), 1); + } + $filter['+'] = $cleanFilter; + } elseif ($filter['-']) { + $filter['+'] = array_diff($allowedTypes, $filter['-']); + if (!$searchAllTypes) { + foreach ($filter['+'] as $type) + $cleanStrings[] = ':' . $type; + foreach ($filter['-'] as $type) + array_splice($cleanStrings, array_search('-:' . $type, $cleanStrings), 1); + } + } else { + if (!$searchAllTypes) { + foreach ($allowedTypes as $type) + $cleanStrings[] = ':' . $type; + } + } + + if ($filter['+']) { + $currentArray['-filter'] = $filter['+']; + } + } +} diff --git a/application/libraries/StundenplanLib.php b/application/libraries/StundenplanLib.php new file mode 100644 index 000000000..6d53a2e2e --- /dev/null +++ b/application/libraries/StundenplanLib.php @@ -0,0 +1,791 @@ +getEventsUser($start, $end); + + return $this->getEventsLv($lehrveranstaltung_id, $start, $end); + } + + /** + * fetches Stundenplan events for the loggedin user between start and end + * + * @param string $start + * @param string $end + * @return stdClass + * @access public + */ + public function getEventsUser($start, $end) + { + $this->_ci =& get_instance(); + + $this->_ci->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + + $uid = getAuthUID(); + if (is_null($uid)) + return error("No UID"); + + $is_mitarbeiter = getData($this->_ci->MitarbeiterModel->isMitarbeiter($uid)); + + if ($is_mitarbeiter) + return $this->getEventsEmployee($uid, $start, $end); + + return $this->getEventsStudent($uid, $start, $end); + } + + /** + * fetches Stundenplan events for a student between start and end + * + * @param string $student_uid + * @param string $start + * @param string $end + * @return stdClass + * @access public + */ + public function getEventsStudent($student_uid, $start, $end) + { + $this->_ci =& get_instance(); + + $this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + + $semester_range = $this->studienSemesterErmitteln($start, $end); + if (isError($semester_range)) + return $semester_range; + $semester_range = getData($semester_range); + + $this->sortStudienSemester($semester_range); + + $function_error = $this->applyLoadUeberSemesterHaelfte($semester_range); + if ($function_error) + return $function_error; + + // getting the gruppen_kurzbz of the student in the different studiensemester + $benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($student_uid, $semester_range); + if (isError($benutzer_gruppen)) + return $benutzer_gruppen; + $benutzer_gruppen = getData($benutzer_gruppen); + + // getting the student_lehrverbaende of the student in the different studiensemester + $student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($student_uid, $semester_range); + if (isError($student_lehrverband)) + return $student_lehrverband; + $student_lehrverband = getData($student_lehrverband); + + $stundenplan_query = $this->_ci->StundenplanModel->getStundenplanQuery( + $start, + $end, + $semester_range, + $benutzer_gruppen, + $student_lehrverband + ); + if (!$stundenplan_query) + return success([]); + + $stundenplan_data = $this->_ci->StundenplanModel->stundenplanGruppierung($stundenplan_query); + if (isError($stundenplan_data)) + return $stundenplan_data; + $stundenplan_data = getData($stundenplan_data) ?? []; + + $function_error = $this->expandObjectInformation($stundenplan_data); + if ($function_error) + return $function_error; + + return success($stundenplan_data); + } + + /** + * fetches Stundenplan events for an employee between start and end + * + * @param string $uid + * @param string $start + * @param string $end + * @return stdClass + * @access public + */ + public function getEventsEmployee($uid, $start, $end) + { + $this->_ci =& get_instance(); + + $this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + + $stundenplan_data = $this->_ci->StundenplanModel->getStundenplanMitarbeiter($start, $end, $uid); + if (isError($stundenplan_data)) + return $stundenplan_data; + $stundenplan_data = getData($stundenplan_data) ?? []; + + $function_error = $this->expandObjectInformation($stundenplan_data); + if ($function_error) + return $function_error; + + return success($stundenplan_data); + } + + /** + * fetches Stundenplan events for a LV between start and end + * + * @param integer $lehrveranstaltung_id + * @param string $start + * @param string $end + * @return stdClass + * @access public + */ + public function getEventsLv($lehrveranstaltung_id, $start, $end) + { + $this->_ci =& get_instance(); + + $this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + + $stundenplan_data = $this->_ci->StundenplanModel->getStundenplanLVA($start, $end, $lehrveranstaltung_id); + if (isError($stundenplan_data)) + return $stundenplan_data; + $stundenplan_data = getData($stundenplan_data) ?? []; + + $function_error = $this->expandObjectInformation($stundenplan_data); + if ($function_error) + return $function_error; + + // query lv itself in case its Stundenplan is being queried and it has no entries + $this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel'); + + $lv_result = $this->_ci->LehrveranstaltungModel->load($lehrveranstaltung_id); + if (isError($lv_result)) + return $lv_result; + if (!hasData($lv_result)) + return error('LV not found'); + + return success($stundenplan_data); + } + + /** + * Get stundenplan for a room + * + * @param string $ort_kurzbz + * @param string $start_date + * @param string $end_date + * @return stdClass + */ + public function getRoomplan($ort_kurzbz, $start_date, $end_date) + { + $this->_ci =& get_instance(); + + // Load Config + $this->_ci->load->config('calendar'); + // Load Models + $this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + + $query = $this->_ci->StundenplanModel->getRoomQuery($ort_kurzbz, $start_date, $end_date); + $roomplan_data = $this->_ci->StundenplanModel->stundenplanGruppierung($query); + + if (isError($roomplan_data)) + return $roomplan_data; + + $this->expandObjectInformation($roomplan_data->retval); + + return $roomplan_data; + } + + /** + * Get reservations (for a room or all) + * + * @param string $start_date + * @param string $end_date + * @param string $ort_kurzbz + * @return stdClass + */ + public function getReservierungen($start_date, $end_date, $ort_kurzbz = '') + { + $this->_ci =& get_instance(); + + // Load Config + $this->_ci->load->config('calendar'); + // Load Models + $this->_ci->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel'); + $this->_ci->load->model('ressource/Reservierung_model', 'ReservierungModel'); + $this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + + $is_mitarbeiter = getData($this->_ci->MitarbeiterModel->isMitarbeiter(getAuthUID())); + + if ($is_mitarbeiter) { + $reservierungen = $this->_ci->ReservierungModel->getReservierungenMitarbeiter($start_date, $end_date, $ort_kurzbz); + } else { + // querying the reservierungen + $reservierungen = $this->_ci->ReservierungModel->getReservierungen($start_date, $end_date, $ort_kurzbz); + } + + if (isError($reservierungen)) + return $reservierungen; + + $function_error = $this->expandObjectInformation($reservierungen->retval); + + if (!is_null($function_error)) + return $function_error; + + return $reservierungen; + } + + public function getLektorenFromLehrveranstaltung($lehrveranstaltung_id, $semester, $studiengang_kz, $studiensemester_kurzbz){ + $this->_ci =& get_instance(); + $this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + $this->_ci->load->model('organisation/Studiensemester_model','StudiensemesterModel'); + + $studiensemester = $this->_ci->StudiensemesterModel->loadWhere(["studiensemester_kurzbz"=>$studiensemester_kurzbz]); + if(isError($studiensemester)) + { + return error(getData($studiensemester)); + } + $studiensemester = current(getData($studiensemester)); + $lektoren = $this->_ci->StundenplanModel->execReadOnlyQuery(" + SELECT DISTINCT uid + FROM campus.vw_stundenplan + WHERE lehrveranstaltung_id = ? AND + studiengang_kz = ? AND + semester = ? AND + (datum BETWEEN ? AND ?) + ",[$lehrveranstaltung_id, $studiengang_kz, $semester, $studiensemester->start, $studiensemester->ende]); + + if(isError($lektoren)) + { + return error(getData($lektoren)); + } + $lektoren = getData($lektoren); + if(isset($lektoren)){ + $lektoren = array_map(function($lektor){ + return $lektor->uid; + },$lektoren); + + } + return success($lektoren); + } + + public function expandObjectInformation($data) + { + $this->_ci =& get_instance(); + + // Load Config + $this->_ci->load->config('calendar'); + // Load Model + $this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel'); + + foreach ($data as $item) + { + $tz = new DateTimeZone($this->_ci->config->item('timezone')); + $isostart = new DateTime($item->datum . ' ' . $item->beginn, $tz); + $item->isostart = $isostart->format(DateTime::ATOM); + + $isoend = new DateTime($item->datum . ' ' . $item->ende, $tz); + $item->isoend = $isoend->format(DateTime::ATOM); + + $lektor_obj_array = array(); + $gruppe_obj_array = array(); + + // load lektor object + foreach ($item->lektor as $lv_lektor) + { + $this->_ci->StundenplanModel->addLimit(1); + $lektor_object = $this->_ci->StundenplanModel->execReadOnlyQuery(" + SELECT mitarbeiter_uid, vorname, nachname, kurzbz + FROM public.tbl_mitarbeiter + JOIN public.tbl_benutzer benutzer ON benutzer.uid = mitarbeiter_uid + JOIN public.tbl_person person ON person.person_id = benutzer.person_id + WHERE kurzbz = ?", [$lv_lektor]); + if (isError($lektor_object)) { + $this->_ci->show_error(getError($lektor_object)); + } + if(isError($lektor_object)) + { + return error(getData($lektor_object)); + } + $lektor_object = getData($lektor_object); + if(count($lektor_object) == 0) + { + return error("No lektor object"); + } + $lektor_object = current($lektor_object); + // only provide needed information of the mitarbeiter object + $lektor_obj_array[] = $lektor_object; + } + + // load gruppe object + foreach ($item->gruppe as $lv_gruppe) + { + $lv_gruppe = strtr($lv_gruppe, ['(' => '', ')' => '', '"' => '']); + $lv_gruppe_array = explode(",", $lv_gruppe); + list($gruppe, $verband, $semester, $studiengang_kz, $gruppen_kuerzel) = $lv_gruppe_array; + + $lv_gruppe_object = new stdClass(); + $lv_gruppe_object->gruppe = $gruppe; + $lv_gruppe_object->verband = $verband; + $lv_gruppe_object->semester = $semester; + $lv_gruppe_object->studiengang_kz = $studiengang_kz; + $lv_gruppe_object->kuerzel = $gruppen_kuerzel; + + $gruppe_obj_array[] = $lv_gruppe_object; + } + + if($item->ort_kurzbz) { + + $ort_content_object = $this->_ci->StundenplanModel->execReadOnlyQuery(" + SELECT content_id + FROM public.tbl_ort + WHERE ort_kurzbz = ?", [$item->ort_kurzbz]); + if (isError($ort_content_object)) { + return error(getData($ort_content_object)); + } + $ort_content_object = getData($ort_content_object)[0]; + if($ort_content_object) { + $item->ort_content_id = $ort_content_object->content_id; + } + + + } + + $item->gruppe = $gruppe_obj_array; + $item->lektor = $lektor_obj_array; + + } + } + + public function fetchFerienTageEvents($start_date, $end_date, $studiengang_kz) + { + $this->_ci =& get_instance(); + + // Load Config + $this->_ci->load->config('calendar'); + + $this->_ci->load->model('organisation/Ferien_model', 'FerienModel'); + + $tz = new DateTimeZone($this->_ci->config->item('timezone')); + + $ferienEvents = $this->_ci->FerienModel->execReadOnlyQuery(" + SELECT * + FROM lehre.tbl_ferien + WHERE (bisdatum >= ? AND vondatum < ?) AND (studiengang_kz = 0 OR studiengang_kz = ?) + ", [$start_date, $end_date, $studiengang_kz]); + + if (isError($ferienEvents)) + return $ferienEvents; + + $ferienEvents = getData($ferienEvents); + + if (!$ferienEvents) + return success([]); + + $ferienEvents = array_map(function ($event) { + $event_start = new DateTime($event->vondatum); + $event_end = new DateTime($event->bisdatum); + $event_end->modify('+1 day'); + + $interval = new DateInterval('P1D'); + $period = new DatePeriod($event_start, $interval, $event_end); + $event->dates = iterator_to_array($period); + return $event; + }, $ferienEvents); + + $start_date = new DateTime($start_date); + $start_date->setTime(0, 0, 0); + $end_date = new DateTime($end_date); + $end_date->setTime(23, 59, 59); + + $ferienEventsFlattened = []; + foreach ($ferienEvents as $ferien_event) { + foreach ($ferien_event->dates as $date) { + if ($date < $start_date || $date > $end_date) + continue; + $event = new stdClass(); + $event->bezeichnung = $ferien_event->bezeichnung; + $event->datum = $date->format('Y-m-d'); + $event->type = 'ferien'; + $ferienEventsFlattened[] = $event; + } + }; + + $today = new DateTime(); + $ferienEventsFlattened = array_map(function ($event) use ($today, $tz) { + $ferien_event = (object)array( + 'type' => 'ferien', + 'beginn' => $today->format('H:i:s'), + 'ende' => $today->format('H:i:s'), + 'isostart' => (new DateTime($event->datum . ' 00:00:00', $tz))->format('c'), + 'isoend' => (new DateTime($event->datum . ' 23:59:59', $tz))->format('c'), + 'allDayEvent' => true, + 'datum' => $event->datum, + 'topic' => $event->bezeichnung, + 'titel' => $event->bezeichnung, + 'farbe' => '00689E' + ); + return $ferien_event; + }, $ferienEventsFlattened); + + return success($ferienEventsFlattened); + } + + // start of the private functions ######################################################################################################## + + // function used to sort an array of studiensemester strings + private function sortStudienSemester(&$semester_range){ + usort( + $semester_range, + function($first,$second) + { + $sem_first = null; + $year_first = null; + $match_first = null; + + $sem_second = null; + $year_second = null; + $match_second = null; + + preg_match('/([WS]+)([0-9]+)/',$first,$match_first); + preg_match('/([WS]+)([0-9]+)/',$second,$match_second); + + $sem_first = $match_first[1]; + $year_first = intval($match_first[2]); + + $sem_second = $match_second[1]; + $year_second = intval($match_second[2]); + + if($year_first < $year_second) + { + return -1; + } + else if($year_first > $year_second) + { + return 1; + } + else if($year_first == $year_second && $sem_first > $sem_second) + { + return 1; + } + else if($year_first == $year_second && $sem_first < $sem_second) + { + return -1; + } + return 0; + } + ); + } + + + + private function fetchBenutzerGruppenFromStudiensemester($student_uid, $semester_range) + { + $this->_ci->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel'); + + $benutzer_gruppen = []; + // for each studiensemester fetch the benutzer gruppen and add them to an associate $bentuzer_gruppen array + /* + [ + ['WS2023'] => [['gruppe1_SS2023','gruppe2_SS2023'],['gruppe1_WS2023','gruppe2_WS2023']], + ['SS2024'] => [['gruppe1_WS2023','gruppe2_WS2023'],['gruppe1_SS2024','gruppe2_SS2024']], + ['WS2024'] => [['gruppe1_SS2024','gruppe2_SS2024'],['gruppe1_WS2024','gruppe2_WS2024']], + ] + */ + foreach($semester_range as $semester_key => $semester_array) + { + $benutzer_gruppen[$semester_key] = []; + // each semester could have ajoint semesters that need to be checked + foreach($semester_array as $semester=>$semester_date_range) + { + // for each active semester query the benutzer_gruppen associated to the semester + $benutzer_query = $this->_ci->BenutzergruppeModel->execReadOnlyQuery(" + SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz = ?",[$student_uid, $semester]); + if(isError($benutzer_query)){ + return error(getData($benutzer_query)); + } + $benutzer_query_result = getData($benutzer_query)??[]; + + array_push( + $benutzer_gruppen[$semester_key], + array_map( + function($item) + { + return "'".$item->gruppe_kurzbz. "'"; + }, + $benutzer_query_result + ) + ); + } + } + + // merge the gruppen of each studiensemester together for the original studiensemester + /* + [ + ['WS2023'] => ['gruppe1_SS2023','gruppe2_SS2023','gruppe1_WS2023','gruppe2_WS2023'], + ['SS2024'] => ['gruppe1_WS2023','gruppe2_WS2023','gruppe1_SS2024','gruppe2_SS2024'], + ['WS2024'] => ['gruppe1_SS2024','gruppe2_SS2024','gruppe1_WS2024','gruppe2_WS2024'], + ] + */ + $benutzer_gruppen = array_map( + function($gruppe) + { + $merged_gruppe = []; + foreach($gruppe as $gruppen_array) + { + $merged_gruppe = array_merge($merged_gruppe, $gruppen_array); + } + return $merged_gruppe; + }, + $benutzer_gruppen + ); + + return success($benutzer_gruppen); + } + + private function fetchStudentlehrverbandFromStudiensemester($student_uid, $semester_range) + { + $this->_ci->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel'); + + $student_lehrverband = []; + // for each studiensemester fetch the studentlehrverbaende and add them to an associate $student_lehrverband array + /* + [ + ['WS2023'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ] ], + ['SS2024'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ] ], + ['WS2024'] => [ [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ] ], + ] + */ + foreach($semester_range as $semester_key => $semester_array) + { + $student_lehrverband[$semester_key] = []; + foreach($semester_array as $semester=>$semester_date_range) + { + // for each active semester query the student_lehrverband associated to the semester + $lehrverband_query = $this->_ci->BenutzergruppeModel->execReadOnlyQuery(" + SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]); + if(isError($lehrverband_query)){ + return error(getData($lehrverband_query)); + } + $lehrverband_query_result = getData($lehrverband_query)??[]; + + $converted_studentLehrverband= array_map( + function ($item) + { + $result = new stdClass(); + $result->studiengang_kz = $item->studiengang_kz; + $result->semester = $item->semester; + $result->verband = $item->verband; + $result->gruppe = $item->gruppe; + return $result; + }, + $lehrverband_query_result); + + array_push($student_lehrverband[$semester_key], $converted_studentLehrverband); + + } + + } + + // merge the studentlehrverband of each studiensemester together for the original studiensemester + /* + [ + ['WS2023'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], + ['SS2024'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], + ['WS2024'] => [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ], + ] + */ + + $student_lehrverband = array_map( + function($studentlehrverband) + { + $merged_studentlehrverband = []; + foreach($studentlehrverband as $studentlehrverband_array) + { + $merged_studentlehrverband = array_merge($merged_studentlehrverband, $studentlehrverband_array); + } + return $merged_studentlehrverband; + }, + $student_lehrverband + ); + + return success($student_lehrverband); + } + + private function applyLoadUeberSemesterHaelfte(&$semester_range) + { + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + /* + @var($semester_collection) + convert the array of studiensemester into an associative array with the studiensemester as the key + and the values of each key are the studiensemester needed for the query associated to that studiensemester + example: + + #INPUT: + ['WS2023','SS2024','WS2024'] + #OUTPUT: + [ + 'WS2023' => ['SS2023','WS2023'] + 'SS2024' => ['WS2023','SS2024'] + 'WS2024' => ['SS2024','WS2024'] + ] + */ + $semester_collection = []; + foreach($semester_range as $studiensemester) + { + $previous_studiensemester = $this->_ci->StudiensemesterModel->getPreviousFrom($studiensemester); + if(isError($previous_studiensemester)) + { + return error(getData($previous_studiensemester)); + } + $previous_studiensemester = getData($previous_studiensemester); + if (count($previous_studiensemester) == 0) { + return error('no previous semester'); + } + $previous_studiensemester = current($previous_studiensemester)->studiensemester_kurzbz; + $semester_collection[$studiensemester] = [$previous_studiensemester, $studiensemester]; + } + + /* + @var($studienSemesterDateRanges) + fetches for each studiensemester the start and end date, (SS) summer studiensemester are extended by 1 month to cover the summerbreak + based on the LVPLAN_LOAD_UEBER_SEMESTERHAELFTE constant it will load both the semester and the previous semester with the full date range + or the semester with the full date range and the previous semester with the half date range: + + #INPUT: + [ + 'WS2023' => ['SS2023','WS2023'] + 'SS2024' => ['WS2023','SS2024'] + 'WS2024' => ['SS2024','WS2024'] + ] + #OUTPUT: depends whether LVPLAN_LOAD_UEBER_SEMESTERHAELFTE is true or false + ~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == true + [ + "SS2024": [ + "WS2023": [ + "start"=> "2024-02-03", + "ende"=> "2024-08-31" + ], + "SS2024": [ + "start"=> "2024-02-03", + "ende"=> "2024-08-31" + ] + ] + ] + ~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == false + [ + "SS2024": [ + "WS2023": [ + "start"=> "2024-02-03", + "ende"=> "2024-05-17" + ], + "SS2024": [ + "start"=> "2024-02-03", + "ende"=> "2024-08-31" + ] + ] + ] + */ + $studienSemesterDateRanges=[]; + foreach($semester_collection as $semester_original => $semester_adjoint) + { + $semester_start_ende = $this->_ci->StudiensemesterModel->getStartEndeFromStudiensemester($semester_original); + if(isError($semester_start_ende)) + { + return error(getData($semester_start_ende)); + } + $semester_start_ende = current(getData($semester_start_ende)); + + // initialize empty arrays to add key value pairs + $studienSemesterDateRanges[$semester_original] = []; + + // check if the studiensemester is a summer semester and add 1 month to bridge the school summer break + $match = null; + preg_match("/^(SS)([0-9]+)/",$semester_original,$match); + if(count($match) >0) + { + $one_month = new DateInterval('P1M'); + $one_day = DateInterval::createFromDateString('1 days'); + $summer_studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende); + $summer_studiensemester_end_date->add($one_month); + $summer_studiensemester_end_date->sub($one_day); + $semester_start_ende->ende = date_format($summer_studiensemester_end_date,'Y-m-d'); + } + if (defined('LVPLAN_LOAD_UEBER_SEMESTERHAELFTE') && LVPLAN_LOAD_UEBER_SEMESTERHAELFTE === true) + { + foreach($semester_adjoint as $adjoint) + { + $studienSemesterDateRanges[$semester_original][$adjoint]=$semester_start_ende; + } + } + else + { + //TODO: half of a DateInterval might not be correctly calculated + // calculate the half of the studiensemester + $studiensemester_start_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->start); + $studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende); + $studiensemester_time_difference = $studiensemester_start_date->diff($studiensemester_end_date); + $half_dateNumber = ceil($studiensemester_time_difference->d/2)+ceil(($studiensemester_time_difference->m*30)/2); + $half_dateInterval = new DateInterval('P'.strval($half_dateNumber) .'D'); + $studiensemester_half = date_format($studiensemester_start_date->add($half_dateInterval),'Y-m-d'); + + $first_half = new stdClass(); + $first_half->start = $semester_start_ende->start; + $first_half->ende = $studiensemester_half; + + $studienSemesterDateRanges[$semester_original][$semester_adjoint[0]] = $first_half; + $studienSemesterDateRanges[$semester_original][$semester_adjoint[1]] = $semester_start_ende; + } + $semester_range = $studienSemesterDateRanges; + } + } + + private function studienSemesterErmitteln($start_date, $end_date) + { + $this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel'); + + // gets all studiensemester from the student from start_date to end_date + $semester_range = $this->_ci->StudiensemesterModel->getByDateRange($start_date, $end_date); + if (isError($semester_range)) + return $semester_range; + + $semester_range = array_map( + function ($sem) { + return $sem->studiensemester_kurzbz; + }, + getData($semester_range) ?: [] + ); + + // if no studiensemester is found for the given timespan, get the nearest studiensemester + if (count($semester_range) == 0) + { + $aktuelle_studiensemester = $this->_ci->StudiensemesterModel->getNearest(); + if (isError($aktuelle_studiensemester)) + return $aktuelle_studiensemester; + + $aktuelle_studiensemester = getData($aktuelle_studiensemester); + if (count($aktuelle_studiensemester) == 0) { + return error("No aktuelles semester"); + } + $aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz; + // push aktuelles semester in active semester array + array_push($semester_range, $aktuelle_studiensemester); + } + + return success($semester_range); + } +} diff --git a/application/libraries/dashboard/DashboardLib.php b/application/libraries/dashboard/DashboardLib.php index edea7c310..f6d7d6599 100644 --- a/application/libraries/dashboard/DashboardLib.php +++ b/application/libraries/dashboard/DashboardLib.php @@ -107,7 +107,7 @@ class DashboardLib $emptyoverride = new stdClass(); $emptyoverride->dashboard_id = $dashboard->dashboard_id; $emptyoverride->uid = $uid; - $emptyoverride->override = '{"widgets": {"' . self::USEROVERRIDE_SECTION . '": {}}}'; + $emptyoverride->override = '{"' . self::USEROVERRIDE_SECTION . '": {"widgets":{}}, "custom": { "widgets" : {}}}'; return $emptyoverride; } @@ -127,7 +127,7 @@ class DashboardLib $emptypreset->dashboard_id = $dashboard->dashboard_id; $emptypreset->funktion_kurzbz = $funktion_kurzbz; $section = ($funktion_kurzbz !== null) ? $funktion_kurzbz : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL; - $emptypreset->preset = '{"widgets": {"' . $section . '": {}}}'; + $emptypreset->preset = '{"' . $section . '": { "widgets" : {}},"custom": { "widgets" : {}}}'; return $emptypreset; } @@ -206,21 +206,22 @@ class DashboardLib public function addWidgetToWidgets(&$widgets, $section, $widget, $widgetid) { $section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL; - if (!isset($widgets[$section]) || !is_array($widgets[$section])) + if (!isset($widgets[$section]) || !isset($widgets[$section]["widgets"]) || !is_array($widgets[$section])) { $widgets[$section] = array(); + $widgets[$section]["widgets"] = array(); } - $widgets[$section][$widgetid] = $widget; + $widgets[$section]["widgets"][$widgetid] = $widget; } public function removeWidgetFromWidgets(&$widgets, $section, $widgetid) { $section = ($section !== null) ? $section : self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL; - if (isset($widgets[$section]) && isset($widgets[$section][$widgetid])) + if (isset($widgets[$section]) && isset($widgets[$section]["widgets"][$widgetid])) { - unset($widgets[$section][$widgetid]); - if(empty($widgets[$section]) && $section !== self::USEROVERRIDE_SECTION) { + unset($widgets[$section]["widgets"][$widgetid]); + if(empty($widgets[$section]["widgets"]) && $section !== self::USEROVERRIDE_SECTION) { unset($widgets[$section]); } return true; diff --git a/application/models/crm/Akte_model.php b/application/models/crm/Akte_model.php index 601019d3a..b945f414a 100644 --- a/application/models/crm/Akte_model.php +++ b/application/models/crm/Akte_model.php @@ -298,6 +298,7 @@ class Akte_model extends DB_Model $this->db->where('person_id', $person_id); $this->addOrder('erstelltam', 'DESC'); + $this->addOrder('akte_id', 'DESC'); return $this->loadWhere([ 'archiv' => true diff --git a/application/models/crm/Dokumentprestudent_model.php b/application/models/crm/Dokumentprestudent_model.php index 2415ee483..6b1c222a8 100644 --- a/application/models/crm/Dokumentprestudent_model.php +++ b/application/models/crm/Dokumentprestudent_model.php @@ -102,6 +102,8 @@ class Dokumentprestudent_model extends DB_Model $qry.=" AND (v.archivierbar = FALSE OR v.archivierbar IS NULL)"; } + $qry.=" ORDER BY d.bezeichnung ASC"; + return $this->execQuery($qry, $parametersArray); } } diff --git a/application/models/education/Abgabe_model.php b/application/models/education/Abgabe_model.php index c68bc55f4..5a18c4fe3 100644 --- a/application/models/education/Abgabe_model.php +++ b/application/models/education/Abgabe_model.php @@ -11,4 +11,5 @@ class Abgabe_model extends DB_Model $this->dbTable = 'campus.tbl_abgabe'; $this->pk = 'abgabe_id'; } + } diff --git a/application/models/education/Lehreinheit_model.php b/application/models/education/Lehreinheit_model.php index ba9e82c64..c373f5449 100644 --- a/application/models/education/Lehreinheit_model.php +++ b/application/models/education/Lehreinheit_model.php @@ -322,7 +322,7 @@ EOSQL; if (hasData($result)) { $lehrveranstaltung = getData($result)[0]; - $oe_result = $this->LehrveranstaltungModel->getAllOe($lehrveranstaltung->lehrveranstaltung_id, $lehrveranstaltung->studiengang_kz); + $oe_result = $this->LehrveranstaltungModel->getAllOe($lehrveranstaltung->lehrveranstaltung_id); return success(hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array('')); } } @@ -335,7 +335,7 @@ EOSQL; } - public function getByLvidStudiensemester($lv_id, $studiensemester_kurzbz) + public function getByLvidStudiensemester($lv_id, $studiensemester_kurzbz, $mitarbeiter_uid = null, $fachbereich_kurzbz = null) { $qry = "WITH lehreinheiten AS ( SELECT * @@ -343,98 +343,66 @@ EOSQL; WHERE lehrveranstaltung_id = ? AND studiensemester_kurzbz = ? ), - gruppen AS ( - SELECT - COALESCE( - string_agg( - tbl_lehreinheitgruppe.gruppe_kurzbz, ' ' - ) FILTER (WHERE NOT direktinskription), - string_agg( - COALESCE( - upper(tbl_studiengang.typ::varchar(1) ||tbl_studiengang.kurzbz) || - '-'|| - COALESCE(tbl_lehreinheitgruppe.semester::varchar, '') || - COALESCE(tbl_lehreinheitgruppe.verband::varchar, '')|| - COALESCE(tbl_lehreinheitgruppe.gruppe, '')), ', ' - ) - ) AS gruppe, - lehreinheit_id - FROM - lehre.tbl_lehreinheitgruppe - LEFT JOIN public.tbl_studiengang USING(studiengang_kz) - LEFT JOIN public.tbl_gruppe USING(gruppe_kurzbz) - GROUP BY lehreinheit_id - ), - mitarbeiter AS ( - SELECT kurzbz, semesterstunden, planstunden, lehreinheit_id - FROM lehre.tbl_lehreinheitmitarbeiter - JOIN public.tbl_mitarbeiter USING(mitarbeiter_uid) - ), - fachbereich AS ( - SELECT - tbl_organisationseinheit.bezeichnung, - tbl_organisationseinheit.organisationseinheittyp_kurzbz, - lehreinheit_id - FROM - public.tbl_organisationseinheit, - lehre.tbl_lehrveranstaltung as lehrfach, - lehre.tbl_lehreinheit - WHERE tbl_organisationseinheit.oe_kurzbz = lehrfach.oe_kurzbz - AND lehrfach.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id - ), - tag_data_agg AS ( - SELECT - lehreinheit_id, - COALESCE(json_agg(tag ORDER BY id), '[]'::json) AS tags - FROM ( - SELECT DISTINCT ON (public.tbl_notiz.notiz_id) - tbl_notiz.notiz_id AS id, - typ_kurzbz, - array_to_json(tbl_notiz_typ.bezeichnung_mehrsprachig)->>0 AS beschreibung, - text AS notiz, - style, - erledigt AS done, - lehreinheit_id - FROM public.tbl_notizzuordnung - JOIN public.tbl_notiz ON tbl_notizzuordnung.notiz_id = tbl_notiz.notiz_id - JOIN public.tbl_notiz_typ ON tbl_notiz.typ = tbl_notiz_typ.typ_kurzbz - WHERE lehreinheit_id IN (SELECT lehreinheit_id FROM lehreinheiten) - ) AS tag - GROUP BY lehreinheit_id - ) + ". $this->_getGruppenCTE() . ", + ". $this->_getLektorenCTE() . ", + ". $this->_getFachbereichCTE() . ", + ". $this->_getTagsCTE() . " + SELECT lehreinheiten.*, lehreinheiten.lehrform_kurzbz as lv_lehrform_kurzbz, tbl_lehrveranstaltung.kurzbz as lv_kurzbz, tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, COALESCE(tag_data_agg.tags, '[]'::json) AS tags, - ( - SELECT string_agg(gr.gruppe, ' ') - FROM gruppen gr - WHERE gr.lehreinheit_id = lehreinheiten.lehreinheit_id - ) AS gruppen, - ( - SELECT string_agg(ma.kurzbz, ' ') - FROM mitarbeiter ma - WHERE ma.lehreinheit_id = lehreinheiten.lehreinheit_id - ) AS lektoren, - ( - SELECT string_agg(fachbereich.bezeichnung, ' ') - FROM fachbereich - WHERE fachbereich.lehreinheit_id = lehreinheiten.lehreinheit_id - ) AS fachbereich + gruppen.gruppen, + mitarbeiter.lektoren, + mitarbeiter.le_planstunden, + mitarbeiter.vorname, + mitarbeiter.nachname, + mitarbeiter.semesterstunden, + fachbereich.bezeichnung as fachbereich, + UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang, + semester FROM lehreinheiten LEFT JOIN lehre.tbl_lehrveranstaltung ON tbl_lehrveranstaltung.lehrveranstaltung_id = lehreinheiten.lehrfach_id - LEFT JOIN tag_data_agg ON tag_data_agg.lehreinheit_id = lehreinheiten.lehreinheit_id"; + LEFT JOIN public.tbl_studiengang USING(studiengang_kz) + LEFT JOIN tag_data_agg ON tag_data_agg.lehreinheit_id = lehreinheiten.lehreinheit_id + LEFT JOIN mitarbeiter ON lehreinheiten.lehreinheit_id = mitarbeiter.lehreinheit_id + LEFT JOIN fachbereich ON lehreinheiten.lehreinheit_id = fachbereich.lehreinheit_id + LEFT JOIN gruppen ON lehreinheiten.lehreinheit_id = gruppen.lehreinheit_id + WHERE true + "; - return $this->execReadOnlyQuery($qry, array($lv_id, $studiensemester_kurzbz)); + $params = array($lv_id, $studiensemester_kurzbz); + + if ($mitarbeiter_uid !== null) + { + $qry .= " AND lehreinheiten.lehreinheit_id IN ( SELECT lehreinheit_id FROM lehre.tbl_lehreinheitmitarbeiter WHERE mitarbeiter_uid = ?) "; + $params[] = $mitarbeiter_uid; + } + + if($fachbereich_kurzbz !== null) + { + $qry .= " AND EXISTS ( SELECT 1 FROM lehre.tbl_lehrveranstaltung JOIN public.tbl_fachbereich USING(oe_kurzbz) WHERE fachbereich_kurzbz= ? AND lehrveranstaltung_id=lehreinheiten.lehrfach_id)"; + $params[] = $fachbereich_kurzbz; + } + $qry .= " ORDER BY lehrveranstaltung_id;"; + + return $this->execReadOnlyQuery($qry, $params); } private function getLVTmp($stg_kz = null) { $qry = "SELECT DISTINCT ON(lehrveranstaltung_id) *, - '' as studienplan_id, '' as studienplan_beeichnung, - CONCAT(vw_lehreinheit.stg_typ, vw_lehreinheit.stg_kurzbz) as studiengang - FROM campus.vw_lehreinheit + '' as stundenblockung, + '' as lehreinheit_id, + '' as wochenrythmus, + '' as raumtyp, + '' as raumtypalternativ, + '' as gruppen, + '' as studienplan_id, + '' as studienplan_beeichnung, + UPPER(CONCAT(vw_lehreinheit.stg_typ, vw_lehreinheit.stg_kurzbz)) as studiengang + FROM campus.vw_lehreinheit WHERE mitarbeiter_uid = ? AND studiensemester_kurzbz = ?"; @@ -460,89 +428,6 @@ EOSQL; return $this->execReadOnlyQuery($qry, $params); } - - - public function getLEByLV($lv_id, $studiensemester_kurzbz, $mitarbeiter_uid = null, $fachbereich_kurzbz = null) - { - $qry = " - WITH gruppen AS ( - SELECT - COALESCE( - string_agg( - tbl_lehreinheitgruppe.gruppe_kurzbz, ', ' - ) FILTER (WHERE NOT direktinskription), - string_agg( - COALESCE( - upper(tbl_studiengang.typ::varchar(1) ||tbl_studiengang.kurzbz) || - '-'|| - COALESCE(tbl_lehreinheitgruppe.semester::varchar, '') || - COALESCE(tbl_lehreinheitgruppe.verband::varchar, '')|| - COALESCE(tbl_lehreinheitgruppe.gruppe, '')), ', ' - ) - ) AS gruppen, - lehreinheit_id - FROM - lehre.tbl_lehreinheitgruppe - LEFT JOIN public.tbl_studiengang USING(studiengang_kz) - LEFT JOIN public.tbl_gruppe USING(gruppe_kurzbz) - GROUP BY lehreinheit_id - ), - lektoren AS ( - SELECT string_agg(kurzbz, ' ') as lektoren, - string_agg(semesterstunden::text, ' ') as semesterstunden, - string_agg(planstunden::text, ' ') as planstunden, - lehreinheit_id - FROM lehre.tbl_lehreinheitmitarbeiter - JOIN public.tbl_mitarbeiter USING(mitarbeiter_uid) - GROUP BY lehreinheit_id - ), - fachbereich AS ( - SELECT - string_agg(CONCAT(tbl_organisationseinheit.bezeichnung, ' (', tbl_organisationseinheit.organisationseinheittyp_kurzbz, ')'),' ') as fachbereich, - lehreinheit_id - FROM - public.tbl_organisationseinheit, - lehre.tbl_lehrveranstaltung as lehrfach, - lehre.tbl_lehreinheit - WHERE - tbl_organisationseinheit.oe_kurzbz = lehrfach.oe_kurzbz - AND lehrfach.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id - GROUP BY lehreinheit_id - ) - SELECT tbl_lehreinheit.*, - tbl_lehrveranstaltung.*, - tbl_lehrveranstaltung.kurzbz as lv_kurzbz, - tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, - lektoren.lektoren, - lektoren.semesterstunden, - lektoren.planstunden, - fachbereich.fachbereich - FROM lehre.tbl_lehreinheit - LEFT JOIN lehre.tbl_lehrveranstaltung ON tbl_lehrveranstaltung.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id - LEFT JOIN gruppen ON tbl_lehreinheit.lehreinheit_id = gruppen.lehreinheit_id - LEFT JOIN lektoren ON tbl_lehreinheit.lehreinheit_id = lektoren.lehreinheit_id - LEFT JOIN fachbereich ON tbl_lehreinheit.lehreinheit_id = fachbereich.lehreinheit_id - WHERE tbl_lehreinheit.lehrveranstaltung_id = ? - AND studiensemester_kurzbz = ? - "; - - $params = array($lv_id, $studiensemester_kurzbz); - if ($mitarbeiter_uid !== null) - { - $qry .= " AND tbl_lehreinheit.lehreinheit_id IN ( SELECT lehreinheit_id FROM lehre.tbl_lehreinheitmitarbeiter WHERE mitarbeiter_uid = ?) "; - $params[] = $mitarbeiter_uid; - } - - if($fachbereich_kurzbz !== null) - { - $qry .= " AND EXISTS ( SELECT 1 FROM lehre.tbl_lehrveranstaltung JOIN public.tbl_fachbereich USING(oe_kurzbz) WHERE fachbereich_kurzbz= ? AND lehrveranstaltung_id=tbl_lehreinheit.lehrfach_id)"; - $params[] = $fachbereich_kurzbz; - } - $qry .= " ORDER BY lehreinheit_id;"; - - return $this->execReadOnlyQuery($qry, $params); - } - public function deleteLehreinheit($lehreinheit_id) { $lehreinheit = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); @@ -741,4 +626,89 @@ EOSQL; $this->db->trans_commit(); return success('Contract successfully updated.'); } + + private function _getGruppenCTE() + { + return "gruppen AS ( + SELECT + lehreinheit_id, + STRING_AGG( + CASE + WHEN (tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL OR tbl_lehreinheitgruppe.gruppe_kurzbz = '') + THEN + UPPER(tbl_studiengang.typ::varchar(1) || tbl_studiengang.kurzbz) || + COALESCE(TRIM(tbl_lehreinheitgruppe.semester::text), '') || + COALESCE(TRIM(tbl_lehreinheitgruppe.verband), '') || + COALESCE(TRIM(tbl_lehreinheitgruppe.gruppe), '') + ELSE + CASE + WHEN NOT tbl_gruppe.direktinskription THEN tbl_lehreinheitgruppe.gruppe_kurzbz + ELSE NULL + END + END, + ' ' + ) AS gruppen + FROM lehre.tbl_lehreinheitgruppe + LEFT JOIN public.tbl_studiengang USING (studiengang_kz) + LEFT JOIN public.tbl_gruppe USING (gruppe_kurzbz) + JOIN lehreinheiten USING(lehreinheit_id) + GROUP BY lehreinheit_id + )"; + } + private function _getLektorenCTE() + { + return "mitarbeiter AS ( + SELECT + tbl_lehreinheitmitarbeiter.lehreinheit_id, + STRING_AGG(m.kurzbz, ' ') AS lektoren, + STRING_AGG(tbl_person.vorname, ' ') AS vorname, + STRING_AGG(tbl_person.nachname, ' ') AS nachname, + STRING_AGG(tbl_lehreinheitmitarbeiter.semesterstunden::text, ' ') AS semesterstunden, + STRING_AGG(tbl_lehreinheitmitarbeiter.planstunden::text, ' ') AS le_planstunden + FROM lehre.tbl_lehreinheitmitarbeiter + JOIN public.tbl_mitarbeiter m USING (mitarbeiter_uid) + JOIN lehreinheiten USING(lehreinheit_id) + JOIN public.tbl_benutzer ON mitarbeiter_uid = uid + JOIN public.tbl_person ON tbl_benutzer.person_id = tbl_person.person_id + GROUP BY tbl_lehreinheitmitarbeiter.lehreinheit_id + )"; + } + + private function _getFachbereichCTE() + { + return "fachbereich AS ( + SELECT + CONCAT(tbl_organisationseinheit.bezeichnung, ' (', tbl_organisationseinheit.organisationseinheittyp_kurzbz, ')') as bezeichnung, + lehreinheiten.lehreinheit_id + FROM public.tbl_organisationseinheit + JOIN lehre.tbl_lehrveranstaltung AS lehrfach ON tbl_organisationseinheit.oe_kurzbz = lehrfach.oe_kurzbz + JOIN lehre.tbl_lehreinheit ON lehrfach.lehrveranstaltung_id = tbl_lehreinheit.lehrfach_id + JOIN lehreinheiten ON tbl_lehreinheit.lehreinheit_id = lehreinheiten.lehreinheit_id + )"; + } + + private function _getTagsCTE() + { + return "tag_data_agg AS ( + SELECT + lehreinheit_id, + COALESCE(json_agg(tag ORDER BY id), '[]'::json) AS tags + FROM ( + SELECT DISTINCT ON (public.tbl_notiz.notiz_id) + tbl_notiz.notiz_id AS id, + typ_kurzbz, + array_to_json(tbl_notiz_typ.bezeichnung_mehrsprachig)->>0 AS beschreibung, + text AS notiz, + style, + erledigt AS done, + lehreinheit_id + FROM public.tbl_notizzuordnung + JOIN public.tbl_notiz ON tbl_notizzuordnung.notiz_id = tbl_notiz.notiz_id + JOIN public.tbl_notiz_typ ON tbl_notiz.typ = tbl_notiz_typ.typ_kurzbz + WHERE lehreinheit_id IN (SELECT lehreinheit_id FROM lehreinheiten) + ) AS tag + GROUP BY lehreinheit_id + )"; + } + } diff --git a/application/models/education/Lehreinheitgruppe_model.php b/application/models/education/Lehreinheitgruppe_model.php index 5dd2fa66c..bca395f31 100644 --- a/application/models/education/Lehreinheitgruppe_model.php +++ b/application/models/education/Lehreinheitgruppe_model.php @@ -304,7 +304,7 @@ class Lehreinheitgruppe_model extends DB_Model } else if ($verband === true) { - $gruppen_result = $this->_ci->LehrverbandModel->loadWhere(array('gid' => $gid)); + $gruppen_result = $this->LehrverbandModel->loadWhere(array('gid' => $gid)); if (!hasData($gruppen_result)) return error('No group found for gid ' . $gid); @@ -470,6 +470,12 @@ class Lehreinheitgruppe_model extends DB_Model END AS verplant"); $this->addJoin('tbl_studiengang', 'studiengang_kz', 'LEFT'); $this->addJoin('public.tbl_gruppe', 'gruppe_kurzbz', 'LEFT'); - return $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'tbl_gruppe.direktinskription' => false)); + + $this->db->where('lehreinheit_id', $lehreinheit_id); + $this->db->group_start() + ->where('tbl_gruppe.direktinskription !=', true) + ->or_where('tbl_gruppe.direktinskription IS NULL') + ->group_end(); + return $this->load(); } } diff --git a/application/models/education/Lehrveranstaltung_model.php b/application/models/education/Lehrveranstaltung_model.php index 7db9e78bd..1b3b9e9d7 100644 --- a/application/models/education/Lehrveranstaltung_model.php +++ b/application/models/education/Lehrveranstaltung_model.php @@ -452,16 +452,6 @@ class Lehrveranstaltung_model extends DB_Model */ public function getLvsByStudentWithGrades($student_uid, $studiensemester_kurzbz, $sprache = null, $lvid=null) { - if ($sprache) { - $sprache_qry = $this->db->compile_binds('SELECT index FROM public.tbl_sprache WHERE sprache = ?', [$sprache]); - $bezeichnung = 'bezeichnung_mehrsprachig[(' . $sprache_qry . ')]'; - $sgbezeichnung = $sprache == 'English' ? 'COALESCE(sg.english, sg.bezeichnung)' : 'sg.bezeichnung'; - $lvbezeichnung = $sprache == 'English' ? 'COALESCE(v.bezeichnung_english, v.bezeichnung)' : 'v.bezeichnung'; - } else { - $bezeichnung = 'bezeichnung'; - $sgbezeichnung = 'sg.bezeichnung'; - $lvbezeichnung = 'v.bezeichnung'; - } $this->addDistinct(); // TODO(chris): selects @@ -501,16 +491,20 @@ class Lehrveranstaltung_model extends DB_Model $this->addSelect('znn.positiv'); #$this->addSelect('splv.module'); - $this->addSelect($lvbezeichnung . ' AS bezeichnung'); - $this->addSelect($sgbezeichnung . ' AS sg_bezeichnung'); + $this->addSelect('v.bezeichnung AS bezeichnung'); + $this->addSelect('v.bezeichnung_english AS bezeichnung_eng'); + $this->addSelect('sg.bezeichnung AS sg_bezeichnung'); + $this->addSelect('sg.english AS sg_bezeichnung_eng'); $this->addSelect('UPPER(sg.typ::VARCHAR(1) || sg.kurzbz) AS studiengang_kuerzel'); //also adds returns the index of the grade //TODO: ist zeugnissnote immer gleich wie die lvgesamtnote $this->addSelect('COALESCE(zn.note::numeric,gn.note::numeric) as note_index'); $this->addSelect('COALESCE(znn.positiv,gnn.positiv) as positiv'); - $this->addSelect('COALESCE(gnn.' . $bezeichnung . ', gnn.bezeichnung, gn.note::text) AS lvnote'); - $this->addSelect('COALESCE(znn.' . $bezeichnung . ', znn.bezeichnung, zn.note::text) AS znote'); + $this->addSelect('gnn.bezeichnung_mehrsprachig AS lvnotebez'); + $this->addSelect('gnn.note AS lvnote'); + $this->addSelect('znn.bezeichnung_mehrsprachig AS znotebez'); + $this->addSelect('znn.note AS znote'); // TODO(chris): Potentielle Anpassung "Eine UID" $this->addJoin('campus.vw_student_lehrveranstaltung v', 'lehrveranstaltung_id'); @@ -989,6 +983,43 @@ class Lehrveranstaltung_model extends DB_Model return $this->execQuery($qry, $params); } + /** + * Gets lehrveranstaltungen of Studienplan + * @param $studienplan_id ID des Studienplans + * @param $semester Semester optional + * @return array|null + */ + public function getLvsByStudienplanId($studienplan_id, $semester = null) + { + $params = array($studienplan_id); + + $qry = "SELECT tbl_lehrveranstaltung.*, + tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id, + tbl_studienplan_lehrveranstaltung.semester as stpllv_semester, + tbl_studienplan_lehrveranstaltung.pflicht as stpllv_pflicht, + tbl_studienplan_lehrveranstaltung.koordinator as stpllv_koordinator, + tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent, + tbl_studienplan_lehrveranstaltung.sort stpllv_sort, + tbl_studienplan_lehrveranstaltung.curriculum, + tbl_studienplan_lehrveranstaltung.export, + tbl_studienplan_lehrveranstaltung.genehmigung + FROM lehre.tbl_lehrveranstaltung + JOIN lehre.tbl_studienplan_lehrveranstaltung + USING(lehrveranstaltung_id) + WHERE tbl_studienplan_lehrveranstaltung.studienplan_id = ? + "; + + if ($semester !== null) + { + $qry.= " AND tbl_studienplan_lehrveranstaltung.semester = ?"; + $params[] = $semester; + } + + $qry .= " ORDER BY stpllv_sort, semester, sort"; + + return $this->execQuery($qry, $params); + } + public function getLvsByOrganization($oe_kurzbz) { $qry=" @@ -1122,9 +1153,9 @@ class Lehrveranstaltung_model extends DB_Model $qry .= " SELECT DISTINCT on(lehrveranstaltung_id) lehrveranstaltung_id, - kurzbz as lv_kurzbz, - bezeichnung as lv_bezeichnung, - bezeichnung_english as lv_bezeichnung_english, + tbl_lehrveranstaltung.kurzbz as lv_kurzbz, + tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, + tbl_lehrveranstaltung.bezeichnung_english as lv_bezeichnung_english, studiengang_kz, semester, tbl_lehrveranstaltung.sprache, @@ -1133,7 +1164,7 @@ class Lehrveranstaltung_model extends DB_Model tbl_lehrveranstaltung.anmerkung, tbl_lehrveranstaltung.lehre, lehreverzeichnis as lv_lehreverzeichnis, - aktiv, + tbl_lehrveranstaltung.aktiv, planfaktor as lv_planfaktor, planlektoren as lv_planlektoren, planpersonalkosten as lv_planpersonalkosten, @@ -1143,9 +1174,11 @@ class Lehrveranstaltung_model extends DB_Model ''::text as studienplan_id, '' as studienplan_bezeichnung, '' as studienplan_lehrveranstaltung_id_parent, - tbl_lehrveranstaltung.lehrtyp_kurzbz + tbl_lehrveranstaltung.lehrtyp_kurzbz, + UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang FROM lehre.tbl_lehrveranstaltung JOIN lehre.tbl_lehreinheit USING (lehrveranstaltung_id) + JOIN public.tbl_studiengang USING(studiengang_kz) WHERE studiengang_kz = ? AND studiensemester_kurzbz = ? "; @@ -1159,7 +1192,7 @@ class Lehrveranstaltung_model extends DB_Model } if (!is_null($verband)) { - $qry .= ' AND (orgform_kurzbz = ? OR orgform_kurzbz IS NULL)'; + $qry .= ' AND (tbl_lehrveranstaltung.orgform_kurzbz = ? OR tbl_lehrveranstaltung.orgform_kurzbz IS NULL)'; $params[] = $verband; } @@ -1178,133 +1211,48 @@ class Lehrveranstaltung_model extends DB_Model { return " SELECT - lehrveranstaltung_id, kurzbz as lv_kurzbz, tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, bezeichnung_english as lv_bezeichnung_english, studiengang_kz, + lehrveranstaltung_id, tbl_lehrveranstaltung.kurzbz as lv_kurzbz, tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, bezeichnung_english as lv_bezeichnung_english, studiengang_kz, tbl_studienplan_lehrveranstaltung.semester, tbl_lehrveranstaltung.sprache, ects as lv_ects, semesterstunden, anmerkung, lehre, lehreverzeichnis as lv_lehreverzeichnis, tbl_lehrveranstaltung.aktiv, planfaktor as lv_planfaktor, planlektoren as lv_planlektoren, planpersonalkosten as lv_planpersonalkosten, plankostenprolektor as lv_plankostenprolektor, lehrform_kurzbz as lv_lehrform_kurzbz, tbl_lehrveranstaltung.orgform_kurzbz, tbl_studienplan_lehrveranstaltung.studienplan_id::text as studienplan_id, tbl_studienplan.bezeichnung as studienplan_bezeichnung, tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent::text, - tbl_lehrveranstaltung.lehrtyp_kurzbz + tbl_lehrveranstaltung.lehrtyp_kurzbz, UPPER(CONCAT(tbl_studiengang.typ,tbl_studiengang.kurzbz)) as studiengang FROM lehre.tbl_lehrveranstaltung JOIN lehre.tbl_studienplan_lehrveranstaltung USING(lehrveranstaltung_id) JOIN lehre.tbl_studienplan USING(studienplan_id) + JOIN tbl_studiengang USING(studiengang_kz) WHERE tbl_lehrveranstaltung.aktiv AND ((studienplan_id, tbl_studienplan_lehrveranstaltung.semester) IN ( " . implode(',', $placeholders) . ")) UNION "; } - public function getAllOe($lv_id, $stg_kz = null) + public function getAllOe($lv_id) { $qry = "SELECT DISTINCT oe_kurzbz - FROM lehre.tbl_studienplan_lehrveranstaltung - JOIN lehre.tbl_studienplan USING(studienplan_id) - JOIN lehre.tbl_studienordnung USING(studienordnung_id) - JOIN public.tbl_studiengang USING(studiengang_kz) - WHERE lehrveranstaltung_id = ? "; + FROM lehre.tbl_studienplan_lehrveranstaltung + JOIN lehre.tbl_studienplan USING(studienplan_id) + JOIN lehre.tbl_studienordnung USING(studienordnung_id) + JOIN public.tbl_studiengang USING(studiengang_kz) + WHERE lehrveranstaltung_id = ? - $params = array($lv_id); - if (!is_null($stg_kz)) - { - $qry .= ' OR studiengang_kz = ?'; - $params[] = $stg_kz; - } + UNION + + ( + SELECT oe_kurzbz + FROM public.tbl_studiengang + WHERE studiengang_kz = ( + SELECT tbl_lehrveranstaltung.studiengang_kz + FROM lehre.tbl_lehrveranstaltung + WHERE lehrveranstaltung_id = ? + ) + ) + "; + + $params = array($lv_id, $lv_id); return $this->execReadOnlyQuery($qry, $params); } - - /** - * Gets Lehrveranstaltungen for a student, as needed for a Projektarbeit. - * @param student_uid - * @param studiengang_kz optional, all Lvs of this Studiengang will be included - * @param additional_lehrveranstaltung_id optional, this lv will be added to result - * @return object success or error - */ - public function getLvsForProjektarbeit($student_uid, $studiengang_kz = null, $additional_lehrveranstaltung_id = null) - { - $params = array($student_uid, $student_uid); - - $qry = " - SELECT * - FROM - lehre.tbl_lehrveranstaltung - WHERE - ( - lehrveranstaltung_id IN ( - - SELECT - lehrveranstaltung_id - FROM - campus.vw_student_lehrveranstaltung - WHERE - uid=? - - UNION - - SELECT - lehrveranstaltung_id - FROM - lehre.tbl_zeugnisnote - WHERE - student_uid=? - )"; - - if (isset($studiengang_kz)) - { - $params[] = $studiengang_kz; - $qry .= " OR (studiengang_kz = ? AND semester IS NOT NULL)"; - } - - if (isset($additional_lehrveranstaltung_id)) - { - $params[] = $additional_lehrveranstaltung_id; - $qry .= " OR lehrveranstaltung_id = ?"; - } - - $qry .= " - ) - AND projektarbeit = TRUE - ORDER BY - semester, bezeichnung"; - - return $this->execQuery($qry, $params); - } - - /** - * Gets lehrveranstaltungen of Studienplan - * @param $studienplan_id ID des Studienplans - * @param $semester Semester optional - * @return array|null - */ - public function getLvsByStudienplanId($studienplan_id, $semester = null) - { - $params = array($studienplan_id); - - $qry = "SELECT tbl_lehrveranstaltung.*, - tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id, - tbl_studienplan_lehrveranstaltung.semester as stpllv_semester, - tbl_studienplan_lehrveranstaltung.pflicht as stpllv_pflicht, - tbl_studienplan_lehrveranstaltung.koordinator as stpllv_koordinator, - tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent, - tbl_studienplan_lehrveranstaltung.sort stpllv_sort, - tbl_studienplan_lehrveranstaltung.curriculum, - tbl_studienplan_lehrveranstaltung.export, - tbl_studienplan_lehrveranstaltung.genehmigung - FROM lehre.tbl_lehrveranstaltung - JOIN lehre.tbl_studienplan_lehrveranstaltung - USING(lehrveranstaltung_id) - WHERE tbl_studienplan_lehrveranstaltung.studienplan_id = ? - "; - - if ($semester !== null) - { - $qry.= " AND tbl_studienplan_lehrveranstaltung.semester = ?"; - $params[] = $semester; - } - - $qry .= " ORDER BY stpllv_sort, semester, sort"; - - return $this->execQuery($qry, $params); - } } diff --git a/application/models/education/Paabgabe_model.php b/application/models/education/Paabgabe_model.php index 5fb58cc81..343a86706 100644 --- a/application/models/education/Paabgabe_model.php +++ b/application/models/education/Paabgabe_model.php @@ -30,4 +30,35 @@ class Paabgabe_model extends DB_Model return $this->execQuery($qry, array($projektarbeit_id)); } + + /** + * Gets all Paabgabe Termin Deadlines of zugewiesene Projektarbeiten as a Mitarbeiter for Terminübersicht Abgabetool. + * @param int $person_id + * @return object + */ + public function getDeadlines($person_id) + { + $qry = "SELECT + DISTINCT TO_CHAR(tbl_paabgabe.datum, 'DD.MM.YYYY') as datum, tbl_paabgabe.fixtermin, tbl_paabgabe.kurzbz, + person_student.vorname as stud_vorname, person_student.nachname as stud_nachname, + person_student.titelpre as stud_titelpre, person_student.titelpost as stud_titelpost, + tbl_lehrveranstaltung.semester, UPPER(tbl_studiengang.typ || tbl_studiengang.kurzbz) as stg, + tbl_paabgabetyp.bezeichnung as typ_bezeichnung + FROM + campus.tbl_paabgabe + JOIN lehre.tbl_projektarbeit USING(projektarbeit_id) + JOIN lehre.tbl_projektbetreuer USING(projektarbeit_id) + JOIN public.tbl_benutzer bn_student ON(tbl_projektarbeit.student_uid=bn_student.uid) + JOIN public.tbl_person person_student ON(bn_student.person_id=person_student.person_id) + JOIN lehre.tbl_lehreinheit ON(tbl_projektarbeit.lehreinheit_id=tbl_lehreinheit.lehreinheit_id) + JOIN lehre.tbl_lehrveranstaltung ON(tbl_lehreinheit.lehrveranstaltung_id=tbl_lehrveranstaltung.lehrveranstaltung_id) + JOIN public.tbl_studiengang ON(tbl_lehrveranstaltung.studiengang_kz=tbl_studiengang.studiengang_kz) + JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz) + WHERE + tbl_projektbetreuer.person_id= ? AND tbl_paabgabe.datum>=now() AND bn_student.aktiv + ORDER BY datum"; + + return $this->execReadOnlyQuery($qry, array($person_id)); + } + } diff --git a/application/models/education/Projektarbeit_model.php b/application/models/education/Projektarbeit_model.php index 357886de1..1ca2a18a8 100644 --- a/application/models/education/Projektarbeit_model.php +++ b/application/models/education/Projektarbeit_model.php @@ -71,6 +71,198 @@ class Projektarbeit_model extends DB_Model return $this->execQuery($qry, $params); } + /** + * Update a Projektarbeit of a student by projektarbeit_id with + * the paramenters used by the student endupload page in cis4 abgabetool. + */ + public function updateProjektarbeit($projektarbeit_id,$sprache,$abstract,$abstract_en, + $schlagwoerter, $schlagwoerter_en,$seitenanzahl) + { + $qry = "UPDATE lehre.tbl_projektarbeit SET + seitenanzahl = ?, + abgabedatum = now(), + sprache = ?, + schlagwoerter_en = ?, + schlagwoerter = ?, + abstract = ?, + abstract_en = ? + WHERE projektarbeit_id = ?"; + + return $this->execQuery($qry, array($seitenanzahl, $sprache, $schlagwoerter_en, + $schlagwoerter, $abstract, $abstract_en, $projektarbeit_id)); + } + + /** + * Get a List of Projektarbeiten of a student with betreuer + * used by the student cis4 abgabetool. + */ + public function getStudentProjektarbeitenWithBetreuer($studentUID) + { + $betreuerQuery = " + SELECT + 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 + 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 + 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) + WHERE projektarbeit_id=tbl_projektarbeit.projektarbeit_id + 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_lehreinheit.studiensemester_kurzbz, + lehre.tbl_lehrveranstaltung.studiengang_kz, + public.tbl_studiengang.kurzbzlang, + lehre.tbl_projektbetreuer.note as note, + public.tbl_mitarbeiter.mitarbeiter_uid, + lehre.tbl_projektarbeit.titel as titel, + 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, + (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, + (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 + LEFT JOIN lehre.tbl_projektbetreuer USING(projektarbeit_id) + LEFT JOIN public.tbl_person USING(person_id) + 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 + (projekttyp_kurzbz='Bachelor' OR projekttyp_kurzbz='Diplom') + AND betreuerart_kurzbz IN ('Betreuer', 'Begutachter', 'Erstbegutachter', 'Senatsvorsitz')"; + + return $this->execReadOnlyQuery($betreuerQuery, array($studentUID)); + } + + /** + * Get a List of Projektarbeit Abgabetermin used by the student cis4 abgabetool. + */ + public function getProjektarbeitAbgabetermine($projektarbeit_id) { + $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_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 = ? + ORDER BY campus.tbl_paabgabe.datum"; + + return $this->execReadOnlyQuery($qry, array($projektarbeit_id)); + } + + 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= ?"; + + return $this->execReadOnlyQuery($qry_betr, [$bperson_id]); + + } + + public function getProjektarbeitBenutzer($uid) { + $qry="SELECT * FROM campus.vw_benutzer where uid=?"; + return $this->execReadOnlyQuery($qry, [$uid]); + } + + /** + * Checks if mitarbeiter has a projektbetreuer zuordnung to student. + */ + public function checkZuordnung($studentUID, $maUID) { + //oder Lektor mit Betreuung dieses Studenten + $qry = " + SELECT 1 + FROM + lehre.tbl_projektarbeit + JOIN lehre.tbl_projektbetreuer USING(projektarbeit_id) + JOIN campus.vw_benutzer on(vw_benutzer.person_id=tbl_projektbetreuer.person_id) + WHERE + tbl_projektarbeit.student_uid = ? AND + vw_benutzer.uid = ?"; + + return $this->execReadOnlyQuery($qry, array($studentUID, $maUID)); + } + + /** + * Get a List of Projektarbeiten of a mitarbeiter with zuordnung + * used by the mitarbeiter cis4 abgabetool. + */ + public function getMitarbeiterProjektarbeiten($uid, $showAll){ + $qry = "SELECT + * + 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 + FROM lehre.tbl_projektarbeit + LEFT JOIN lehre.tbl_projektbetreuer using(projektarbeit_id) + LEFT JOIN lehre.tbl_betreuerart using(betreuerart_kurzbz) + LEFT JOIN public.tbl_benutzer on(uid=student_uid) + LEFT JOIN public.tbl_student on(public.tbl_benutzer.uid=public.tbl_student.student_uid) + LEFT JOIN public.tbl_person on(tbl_benutzer.person_id=tbl_person.person_id) + LEFT JOIN lehre.tbl_lehreinheit using(lehreinheit_id) + LEFT JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id) + LEFT JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz=public.tbl_studiengang.studiengang_kz) + LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz) + WHERE (projekttyp_kurzbz='Bachelor' OR projekttyp_kurzbz='Diplom') + AND tbl_projektbetreuer.person_id IN (SELECT person_id FROM public.tbl_benutzer + WHERE public.tbl_benutzer.person_id=lehre.tbl_projektbetreuer.person_id + AND public.tbl_benutzer.uid= ? ) + ".($showAll?'':' AND public.tbl_benutzer.aktiv AND lehre.tbl_projektarbeit.note IS NULL ')." + AND betreuerart_kurzbz IN ('Betreuer', 'Begutachter', 'Erstbegutachter', 'Zweitbegutachter', 'Erstbetreuer', 'Senatsvorsitz', 'Senatsmitglied') + ORDER BY tbl_projektarbeit.projektarbeit_id, betreuerart_kurzbz desc) as xy + ORDER BY nachname;"; + + return $this->execReadOnlyQuery($qry, array($uid)); + } + + /** + * Fetch Student info relevant to a projektarbeit_id + */ + public function getStudentInfoForProjektarbeitId($projektarbeit_id) { + + $qry = "SELECT * + FROM campus.vw_student + WHERE uid IN( + SELECT student_uid + FROM lehre.tbl_projektarbeit + WHERE projektarbeit_id = ? )"; + + return $this->execReadOnlyQuery($qry, array($projektarbeit_id)); + } + /** * * @param diff --git a/application/models/organisation/Studiengang_model.php b/application/models/organisation/Studiengang_model.php index 7ea8a901c..02f972690 100644 --- a/application/models/organisation/Studiengang_model.php +++ b/application/models/organisation/Studiengang_model.php @@ -709,24 +709,38 @@ class Studiengang_model extends DB_Model if (isError($stg_ltg)) return $stg_ltg; $stg_ltg = getData($stg_ltg) ?: []; + $stg_ltg = array_values(array_filter($stg_ltg, function($stg_leitung){ + return $stg_leitung->aktiv; + })); $addFotoProperty($stg_ltg); $gf_ltg = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('gLtg', $stg_obj->oe_kurzbz); if (isError($gf_ltg)) return $gf_ltg; $gf_ltg = getData($gf_ltg) ?: []; + $gf_ltg = array_values(array_filter($gf_ltg, function($gf_leitung){ + return $gf_leitung->aktiv; + })); $addEmailProperty($gf_ltg); + $addFotoProperty($gf_ltg); $stv_ltg = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('stvLtg', $stg_obj->oe_kurzbz); if (isError($stv_ltg)) return $stv_ltg; $stv_ltg = getData($stv_ltg) ?: []; + $stv_ltg = array_values(array_filter($stv_ltg, function($stv_leitung){ + return $stv_leitung->aktiv; + })); $addEmailProperty($stv_ltg); - + $addFotoProperty($stv_ltg); + $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; + })); $addEmailProperty($ass); $addFotoProperty($ass); @@ -734,6 +748,9 @@ class Studiengang_model extends DB_Model if (isError($hochschulvertr)) return $hochschulvertr; $hochschulvertr = getData($hochschulvertr) ?: []; + $hochschulvertr = array_values(array_filter($hochschulvertr, function($hochschul_vertreter){ + return $hochschul_vertreter->aktiv; + })); $addEmailProperty($hochschulvertr); @@ -741,6 +758,9 @@ class Studiengang_model extends DB_Model if (isError($stdv)) return $stdv; $stdv = getData($stdv) ?: []; + $stdv = array_values(array_filter($stdv, function($std_vertreter){ + return $std_vertreter->aktiv; + })); $addEmailProperty($stdv); @@ -748,6 +768,9 @@ class Studiengang_model extends DB_Model if (isError($jahrgangsvertr)) return $jahrgangsvertr; $jahrgangsvertr = getData($jahrgangsvertr) ?: []; + $jahrgangsvertr = array_values(array_filter($jahrgangsvertr, function($jahrgang_vertreter){ + return $jahrgang_vertreter->aktiv; + })); $addEmailProperty($jahrgangsvertr); diff --git a/application/models/organisation/Studienplan_model.php b/application/models/organisation/Studienplan_model.php index c27eeac4d..4a5f87832 100644 --- a/application/models/organisation/Studienplan_model.php +++ b/application/models/organisation/Studienplan_model.php @@ -107,6 +107,8 @@ class Studienplan_model extends DB_Model )); } + // Deprecated + // im Lehrveranstaltung_model vorhanden public function getAllOesForLv($lehrveranstaltung_id) { $this->addDistinct('oe_kurzbz'); @@ -167,5 +169,4 @@ class Studienplan_model extends DB_Model 'person_id' => $person_id ]); } - } diff --git a/application/models/organisation/Studiensemester_model.php b/application/models/organisation/Studiensemester_model.php index f29ab223c..5fa6ffb14 100644 --- a/application/models/organisation/Studiensemester_model.php +++ b/application/models/organisation/Studiensemester_model.php @@ -341,4 +341,10 @@ class Studiensemester_model extends DB_Model WHERE studiensemester_kurzbz = ?",[$studiensemester_kurzbz]); } + + public function isValidStudiensemester($studiensemester_kurzbz) + { + $result = $this->load($studiensemester_kurzbz); + return hasData($result); + } } diff --git a/application/models/person/Notiz_model.php b/application/models/person/Notiz_model.php index c24919b2d..64fce8944 100644 --- a/application/models/person/Notiz_model.php +++ b/application/models/person/Notiz_model.php @@ -153,57 +153,58 @@ class Notiz_model extends DB_Model */ public function getNotizWithDocEntries($id, $type, $withoutTags = true) { - $withoutTagsClause = $withoutTags ? " AND n.typ IS NULL" : ""; - - $qry = " - SELECT - n.*, - CASE - WHEN person_verfasser.vorname IS NOT NULL AND person_verfasser.vorname != '' - OR person_verfasser.nachname IS NOT NULL AND person_verfasser.nachname != '' - THEN CONCAT(person_verfasser.vorname, ' ', person_verfasser.nachname) - ELSE NULL - END AS verfasser, - CASE - WHEN person_bearbeiter.vorname IS NOT NULL AND person_bearbeiter.vorname != '' - OR person_bearbeiter.nachname IS NOT NULL AND person_bearbeiter.nachname != '' - THEN CONCAT(person_bearbeiter.vorname, ' ', person_bearbeiter.nachname) - ELSE NULL - END AS bearbeiter, - count(dms_id) as countDoc, z.notizzuordnung_id, - (CASE - WHEN n.updateamum >= n.insertamum THEN n.updateamum - ELSE n.insertamum - END) AS lastUpdate, - regexp_replace(n.text, '<[^>]*>', '', 'g') as text_stripped, - TO_CHAR(n.start::timestamp, 'DD.MM.YYYY') AS start_format, - TO_CHAR(n.ende::timestamp, 'DD.MM.YYYY') AS ende_format, - z.notiz_id, z.person_id as id, ? as type_id - - FROM - public.tbl_notiz n - JOIN - public.tbl_notizzuordnung z USING (notiz_id) - LEFT JOIN - public.tbl_notiz_dokument dok USING (notiz_id) - LEFT JOIN - campus.tbl_dms_version USING (dms_id) - LEFT JOIN - public.tbl_benutzer p_verfasser ON (p_verfasser.uid = n.verfasser_uid) - LEFT JOIN - public.tbl_person person_verfasser ON (person_verfasser.person_id = p_verfasser.person_id) - LEFT JOIN - public.tbl_benutzer p_bearbeiter ON (p_bearbeiter.uid = n.bearbeiter_uid) - LEFT JOIN - public.tbl_person person_bearbeiter ON (person_bearbeiter.person_id = p_bearbeiter.person_id) - WHERE - z.{$type} = ? - {$withoutTagsClause} - GROUP BY - notiz_id, z.notizzuordnung_id, - person_verfasser.vorname, person_verfasser.nachname, - person_bearbeiter.vorname, person_bearbeiter.nachname - "; + $qry = " + SELECT + n.*, + CASE + WHEN person_verfasser.vorname IS NOT NULL AND person_verfasser.vorname != '' + OR person_verfasser.nachname IS NOT NULL AND person_verfasser.nachname != '' + THEN CONCAT(person_verfasser.vorname, ' ', person_verfasser.nachname) + ELSE NULL + END AS verfasser, + CASE + WHEN person_bearbeiter.vorname IS NOT NULL AND person_bearbeiter.vorname != '' + OR person_bearbeiter.nachname IS NOT NULL AND person_bearbeiter.nachname != '' + THEN CONCAT(person_bearbeiter.vorname, ' ', person_bearbeiter.nachname) + ELSE NULL + END AS bearbeiter, + count(dms_id) as countDoc, z.notizzuordnung_id, + (CASE + WHEN n.updateamum >= n.insertamum THEN n.updateamum + ELSE n.insertamum + END) AS lastUpdate, + regexp_replace(n.text, '<[^>]*>', '', 'g') as text_stripped, + TO_CHAR(n.start::timestamp, 'DD.MM.YYYY') AS start_format, + TO_CHAR(n.ende::timestamp, 'DD.MM.YYYY') AS ende_format, + z.notiz_id, z.person_id as id, ? as type_id + + FROM + public.tbl_notiz n + JOIN + public.tbl_notizzuordnung z USING (notiz_id) + LEFT JOIN + public.tbl_notiz_dokument dok USING (notiz_id) + LEFT JOIN + campus.tbl_dms_version USING (dms_id) + LEFT JOIN + public.tbl_benutzer p_verfasser ON (p_verfasser.uid = n.verfasser_uid) + LEFT JOIN + public.tbl_person person_verfasser ON (person_verfasser.person_id = p_verfasser.person_id) + LEFT JOIN + public.tbl_benutzer p_bearbeiter ON (p_bearbeiter.uid = n.bearbeiter_uid) + LEFT JOIN + public.tbl_person person_bearbeiter ON (person_bearbeiter.person_id = p_bearbeiter.person_id) + WHERE + z.$type = ?"; + + if ($withoutTags) + $qry .= " AND n.typ IS NULL "; + + $qry .= "GROUP BY + notiz_id, z.notizzuordnung_id, + person_verfasser.vorname, person_verfasser.nachname, + person_bearbeiter.vorname, person_bearbeiter.nachname + "; return $this->execQuery($qry, array($type, $id)); } diff --git a/application/models/ressource/Mitarbeiter_model.php b/application/models/ressource/Mitarbeiter_model.php index 8afd908c0..f6cdc74b8 100644 --- a/application/models/ressource/Mitarbeiter_model.php +++ b/application/models/ressource/Mitarbeiter_model.php @@ -402,20 +402,6 @@ class Mitarbeiter_model extends DB_Model return $this->execQuery($qry, $parametersArray); } - public function isLehrauftragFirma($mitarbeiter_uid) - { - $this->addSelect('firma_id'); - $this->addJoin('public.tbl_benutzer', 'uid = mitarbeiter_uid'); - $this->addJoin('public.tbl_person', 'person_id'); - $this->addJoin('public.tbl_adresse', 'person_id', 'LEFT'); - $this->addOrder('zustelladresse', 'DESC'); - $this->addOrder('firma_id'); - $this->addLimit(1); - $firma_result = $this->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid)); - $firma = getData($firma_result)[0]->firma_id; - return !is_null($firma); - } - /** * Get Lektoren by studiengang_kz * @@ -444,4 +430,18 @@ class Mitarbeiter_model extends DB_Model return $this->execQuery($qry, $parametersArray); } + + public function isLehrauftragFirma($mitarbeiter_uid) + { + $this->addSelect('firma_id'); + $this->addJoin('public.tbl_benutzer', 'uid = mitarbeiter_uid'); + $this->addJoin('public.tbl_person', 'person_id'); + $this->addJoin('public.tbl_adresse', 'person_id', 'LEFT'); + $this->addOrder('zustelladresse', 'DESC'); + $this->addOrder('firma_id'); + $this->addLimit(1); + $firma_result = $this->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid)); + $firma = getData($firma_result)[0]->firma_id; + return !is_null($firma); + } } diff --git a/application/models/ressource/Reservierung_model.php b/application/models/ressource/Reservierung_model.php index f635d0cb1..789ff3d9c 100644 --- a/application/models/ressource/Reservierung_model.php +++ b/application/models/ressource/Reservierung_model.php @@ -21,7 +21,7 @@ class Reservierung_model extends DB_Model public function getReservierungen($start_date, $end_date, $ort_kurzbz = null) { - $stundenplan_reservierungen_query="SELECT r.* , stund.beginn, stund.ende, + $lvplan_reservierungen_query="SELECT r.* , stund.beginn, stund.ende, CASE WHEN r.gruppe_kurzbz IS NOT NULL THEN r.gruppe_kurzbz ELSE CONCAT(UPPER(studg.typ),UPPER(studg.kurzbz),'-',COALESCE(CAST(r.semester AS varchar),'/'),COALESCE(CAST(r.verband AS varchar),'/')) @@ -46,7 +46,7 @@ class Reservierung_model extends DB_Model JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = res.stunde WHERE res.ort_kurzbz = ? AND datum >= ? AND datum <= ?"; - $subquery = is_null($ort_kurzbz)? $stundenplan_reservierungen_query:$raum_reservierungen_query; + $subquery = is_null($ort_kurzbz)? $lvplan_reservierungen_query:$raum_reservierungen_query; $query_result= $this->execReadOnlyQuery(" SELECT @@ -89,7 +89,7 @@ class Reservierung_model extends DB_Model JOIN lehre.tbl_stunde ON lehre.tbl_stunde.stunde = res.stunde WHERE res.uid = ? AND datum >= ? AND datum <= ?"; -// $subquery = is_null($ort_kurzbz)? $stundenplan_reservierungen_query:$raum_reservierungen_query; +// $subquery = is_null($ort_kurzbz)? $lvplan_reservierungen_query:$raum_reservierungen_query; $subquery = $raum_reservierungen_query; diff --git a/application/models/ressource/Stunde_model.php b/application/models/ressource/Stunde_model.php index 05a9cddff..0203163f7 100644 --- a/application/models/ressource/Stunde_model.php +++ b/application/models/ressource/Stunde_model.php @@ -11,4 +11,19 @@ class Stunde_model extends DB_Model $this->dbTable = 'lehre.tbl_stunde'; $this->pk = 'stunde'; } + + /** + * $time needs to be of PGSQL TIME format + */ + public function getStundeForTime($time) { + $query = " + SELECT min(stunde) as stunde FROM ( + SELECT stunde, extract(epoch from (beginn-?)) AS delta FROM lehre.tbl_stunde + UNION + SELECT stunde, extract(epoch from (ende-?)) AS delta FROM lehre.tbl_stunde + ) foo WHERE delta>=0 + "; + + return $this->execReadOnlyQuery($query, [$time, $time]); + } } diff --git a/application/models/ressource/Stundenplan_model.php b/application/models/ressource/Stundenplan_model.php index ac20c96c3..389be582d 100644 --- a/application/models/ressource/Stundenplan_model.php +++ b/application/models/ressource/Stundenplan_model.php @@ -177,7 +177,7 @@ class Stundenplan_model extends DB_Model ) as subquery - GROUP BY unr, datum, beginn, ende, ort_kurzbz, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id + GROUP BY unr, datum, beginn, ende, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id ORDER BY datum, beginn "); @@ -327,7 +327,7 @@ class Stundenplan_model extends DB_Model ) as subquery - GROUP BY unr, datum, beginn, ende, ort_kurzbz, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id + GROUP BY unr, datum, beginn, ende, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id ORDER BY datum, beginn ", [$start_date, $end_date, $lv_id]); @@ -384,7 +384,7 @@ class Stundenplan_model extends DB_Model ) as subquery - GROUP BY unr, datum, beginn, ende, ort_kurzbz, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id + GROUP BY unr, datum, beginn, ende, titel, lehrform, lehrfach, lehrfach_bez, organisationseinheit, farbe, lehrveranstaltung_id ORDER BY datum, beginn", [$start_date, $end_date, $ma_uid]); } diff --git a/application/models/ressource/Stundenplandev_model.php b/application/models/ressource/Stundenplandev_model.php index 82b3779ab..e718ba073 100644 --- a/application/models/ressource/Stundenplandev_model.php +++ b/application/models/ressource/Stundenplandev_model.php @@ -223,13 +223,14 @@ class Stundenplandev_model extends DB_Model public function deleteLektorPlanning($lehreinheit_id, $mitarbeiter_uid) { - $this->addDistinct('mitarbeiter_uid'); + //TODO (david) prüfen ob der check notwendig ist + /*$this->addDistinct('mitarbeiter_uid'); $this->addSelect('mitarbeiter_uid'); $stundenplan_result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id)); $stundenplan_array = hasData($stundenplan_result) ? (getData($stundenplan_result)) : array(); if (sizeof($stundenplan_array) <= 1) - return error('Diese/r LektorIn kann nicht aus dem LVPlan entfernt werden da dies der/die letzte verplante LektorIn ist'); + return error('Diese/r LektorIn kann nicht aus dem LVPlan entfernt werden da dies der/die letzte verplante LektorIn ist');*/ $this->addJoin('lehre.tbl_stundenplan_betriebsmittel', 'stundenplandev_id'); $betriebsmittel_result = $this->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'tbl_stundenplandev.mitarbeiter_uid' => $mitarbeiter_uid)); diff --git a/application/views/Cis/Login.php b/application/views/Cis/Login.php index 68490e67e..90f78f123 100644 --- a/application/views/Cis/Login.php +++ b/application/views/Cis/Login.php @@ -2,7 +2,8 @@ $includesArray = array( 'title' => 'FH-Complete', 'bootstrap5' => true, - 'fontawesome6' => true + 'fontawesome6' => true, + 'customJSs' => 'public/js/helpers/ColorThemeSetting.js' ); $this->load->view('templates/FHC-Header', $includesArray); diff --git a/application/views/CisRouterView/CisRouterView.php b/application/views/CisRouterView/CisRouterView.php index 4590b210e..ab22fbb81 100644 --- a/application/views/CisRouterView/CisRouterView.php +++ b/application/views/CisRouterView/CisRouterView.php @@ -5,25 +5,32 @@ $includesArray = array( 'axios027' => true, 'bootstrap5' => true, 'fontawesome6' => true, - 'tabulator5' => 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/searchbar/searchbar.css', 'public/css/Fhc.css', 'public/css/components/dashboard.css', - 'public/css/components/calendar.css', + //'public/css/components/calendar.css', <= imported in dashboard.css 'public/css/components/Sprachen.css', 'public/css/components/MyLv.css', 'public/css/components/FilterComponent.css', 'public/css/components/Profil.css', 'public/css/components/FormUnderline.css', 'public/css/Cis4/Cms.css', + 'public/css/Cis4/Studium.css', ), 'customJSs' => array( - 'vendor/npm-asset/primevue/accordion/accordion.js', - 'vendor/npm-asset/primevue/accordiontab/accordiontab.js' + '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/moment/luxonjs/luxon.min.js' ), 'customJSModules' => array( 'public/js/apps/Dashboard/Fhc.js' @@ -33,7 +40,7 @@ $includesArray = array( $this->load->view('templates/CISVUE-Header', $includesArray); ?> -
> +
> diff --git a/application/views/lehre/anrechnung/requestAnrechnungImportant.php b/application/views/lehre/anrechnung/requestAnrechnungImportant.php index 6a3cc5a9a..0ec44c047 100644 --- a/application/views/lehre/anrechnung/requestAnrechnungImportant.php +++ b/application/views/lehre/anrechnung/requestAnrechnungImportant.php @@ -9,7 +9,6 @@ p->t('anrechnung', 'requestAnrechnungInfoFristenTitle'); ?> -
@@ -80,4 +79,4 @@ - \ No newline at end of file + diff --git a/application/views/templates/CISVUE-Header.php b/application/views/templates/CISVUE-Header.php index 86b5b8755..358fc75c9 100644 --- a/application/views/templates/CISVUE-Header.php +++ b/application/views/templates/CISVUE-Header.php @@ -1,4 +1,5 @@ load->config('theme'); $includesArray = array( 'title' => $title ?? 'FH-Complete', 'vue3' => true, @@ -10,7 +11,8 @@ $includesArray = array( 'public/js/apps/Cis.js' ], $customJSModules ?? []), 'customCSSs' => array_merge([ - 'public/css/Cis4/Cis.css' + 'public/css/Cis4/Cis.css', + $this->config->item('theme_css'), ], $customCSSs ?? []) ); @@ -26,7 +28,7 @@ $this->load->view('templates/FHC-Header', $includesArray);