Compare commits

...
Author SHA1 Message Date
Andreas Österreicher 339b08537e Merge branch 'master' into feature-77801/AbgabetoolSonstigesSprint252 2026-09-22 08:34:44 +02:00
Harald Bamberger d5c1721ab1 Merge branch 'feature-83457/cis4_redirect_blank_target' 2026-09-18 17:14:49 +02:00
Harald Bamberger 8eb27b194f add target attribute to redirect content menu entries, use entry target attribute if set when rendering cis4 menu 2026-09-18 17:12:30 +02:00
Harald Bamberger 579a55a00d fix nested ternary operators 2026-09-17 14:18:10 +02:00
Andreas Österreicher 0a00caa1e4 Merge branch 'feature-82683/lvverwaltung_zusaetzliche_spalten_bei_lehrenden' 2026-09-17 14:00:07 +02:00
Andreas Österreicher c53040ed5c Zusätzliche Datumsberechnung für Zutrittskarten hinzugefügt 2026-09-17 11:21:23 +02:00
Harald Bamberger f7465047cb Merge branch 'feature-75469/LeOptional4Projektarbeit' 2026-09-16 17:35:55 +02:00
Johann Hoffmann 69fd223358 fix load projektarbeit.studiensemester_kurzbz for fetchProjektarbeitById in order to query getDefaultStundensaetze successfully 2026-09-15 11:49:19 +02:00
Harald Bamberger 9c43374267 Merge branch 'master' into feature-75469/LeOptional4Projektarbeit 2026-09-15 07:53:10 +02:00
Paolo ea7c0cccde Added base seeders for testing/staging/demoing 2026-09-14 16:36:12 +02:00
Harald Bamberger 6dfe292776 API LV: extend regex to allow studiengang_kz 0 2026-09-14 11:09:45 +02:00
ma0048 c90f7a31bb columns hinzugefuegt: insertvon/updatevon insertamum/updateamum 2026-09-11 12:03:06 +02:00
Johann Hoffmann 56fe8c9d09 Merge remote-tracking branch 'origin/feature-75469/LeOptional4Projektarbeit' into feature-75469/LeOptional4Projektarbeit 2026-09-10 11:51:26 +02:00
Johann Hoffmann 9a3532265f information schema guard check for the data migration & table alter statements aswell, so they dont run on every checksystem.php invocation 2026-09-10 11:50:51 +02:00
Harald Bamberger 4abe6f0d24 Merge branch 'bugfix_missing-studvw-filter-clear-action-button' 2026-09-09 16:15:39 +02:00
adisposkofh 9fbbd6b855 moved studvw 'clear filter' action button into 'actions' slot in the filter component 2026-09-09 15:14:20 +02:00
Andreas Österreicher 59b4b2bac9 Merge branch 'feature-71639/StudVw_Noten_Renaming_Infopopup' 2026-09-09 12:40:42 +02:00
Andreas Österreicher 5f546fca2a Merge branch 'feature-82630/Infocenter_Verlinkung_StudVW' 2026-09-09 12:37:33 +02:00
Andreas Österreicher 1bf2b707ef Merge branch 'master' into feature-75469/LeOptional4Projektarbeit 2026-09-09 09:43:11 +02:00
Andreas Österreicher f74b885253 Abfrage von Verträgen korrigiert für Fälle wo der Monatsletzte gleichzeitig der Start des neuen Studiensemesters ist (zB 31.08.2026) damit die Abrechnung korrekt funktioniert (BFI) 2026-09-09 08:55:24 +02:00
Andreas Österreicher 3ab402adef Merge branch 'bugfix-82884_grades-export-group-names' 2026-09-08 14:43:17 +02:00
Manuela Thamer 52f24645fb update link StudVW 2026-09-08 14:23:59 +02:00
Manuela Thamer 4ac108174b rename title delete button 2026-09-08 08:29:08 +02:00
adisposkofh 6378b80d87 fixed issue where exported gradelist excel file formatted group names as numbers 2026-09-07 15:24:38 +02:00
Andreas Österreicher 658c8d6bd4 Schreibberechtigungsprüfung bei Anrechnungen angepasst damit diese korrekt angezeigt wird wenn oe_kurzb nicht gleich der Kurzbz des Studiegangs ist 2026-09-03 08:44:10 +02:00
Andreas Österreicher bf29faa5a7 Merge branch 'feature-82292/Cis4StudiumLVohneModulAnzeigen' 2026-09-02 15:20:28 +02:00
Andreas Österreicher 2ada167557 Merge branch 'bug-82614/StudVw_International_Incoming_Outgoing_GS_wird_nicht_geladen' 2026-09-02 14:56:27 +02:00
chfhtw cc9d1f983e bugfix: missing call to getStudiensemesterKurzbz 2026-09-01 10:39:02 +02:00
Johann Hoffmann 57c48f2c4a cis4 studium page dont filter away lehrveranstaltungen without a module and give them their own box in the ui; 2026-08-26 13:15:16 +02:00
Andreas Österreicher e32691994c Merge branch 'master' into feature-75469/LeOptional4Projektarbeit 2026-08-26 08:21:30 +02:00
Harald Bamberger 6d641bbd06 pass in uid by reference 2026-08-24 13:56:55 +02:00
Harald Bamberger 3455aed3f5 Merge branch 'bhdev_master_stundenplan' 2026-08-24 13:46:09 +02:00
Harald Bamberger f84d12277d remove debug code 2026-08-24 07:31:47 +02:00
Harald Bamberger 9bf5bc2ad9 more generic bugfix, to use studentlehrverband only with date_range for the same studiensemester_kurzbz 2026-08-24 07:26:12 +02:00
Harald Bamberger 27765606e3 bufix akadGrad by sex if exists 2026-08-20 19:31:37 +02:00
Harald Bamberger 75d2cabdbe bugfix lv-plan 2026-08-20 15:10:26 +02:00
Harald Bamberger bae9d6d9a0 Merge branch 'feature-78257/StudVW_Und_Tags_Finetuning' 2026-08-19 17:11:12 +02:00
Harald Bamberger 43d6a882ce add padding to tags buttons, remove orphanded template closing tag 2026-08-19 17:07:25 +02:00
Harald Bamberger 7f3b4100ab Merge branch 'master' into feature-78257/StudVW_Und_Tags_Finetuning 2026-08-19 15:07:07 +02:00
Harald Bamberger 9f54ecce54 Merge branch 'epic/LVEvaluierung-Neu' 2026-08-19 13:59:00 +02:00
Cristina 7af0f4a478 Merge remote-tracking branch 'origin/epic/LVEvaluierung-Neu' into epic/LVEvaluierung-Neu 2026-08-19 13:35:25 +02:00
Cristina 0f843db33d Merge branch 'master' into epic/LVEvaluierung-Neu 2026-08-19 13:34:53 +02:00
Cristina 3e59648d5b Merge branch 'master' into epic/LVEvaluierung-Neu 2026-08-19 12:55:38 +02:00
Cristina 5923991848 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-08-19 12:55:03 +02:00
Harald Bamberger 55a6ec9d0d fix handling of grundbetrag and betrag_valorisiert 2026-08-19 11:48:22 +02:00
chfhtw 78505589c8 Bugfix: racecondition renderers 2026-08-19 09:45:15 +02:00
Harald Bamberger 0e985113ec Merge branch 'feature-77666/Details_anzeigen_der_Valorisierung_pro_Person' 2026-08-19 08:20:42 +02:00
Harald Bamberger 8d9113d5c8 Merge branch 'master' into feature-77666/Details_anzeigen_der_Valorisierung_pro_Person 2026-08-19 08:06:16 +02:00
Harald Bamberger 7ce81ad4bd Merge branch 'feature-78292/dv_gehaltsbestandteil_ersteinstufung' 2026-08-19 07:57:07 +02:00
Harald Bamberger ea56ec8daa change wording 2026-08-19 07:50:50 +02:00
Harald Bamberger bf5ee2f64b Merge branch 'feature-78139/CIS4_Dashboard_ausgeblendete_Widgets' 2026-08-18 17:51:40 +02:00
Harald Bamberger 55d6d90fa6 Merge branch 'master' into feature-78139/CIS4_Dashboard_ausgeblendete_Widgets 2026-08-18 17:47:13 +02:00
Harald Bamberger 6adc55a843 Merge branch 'feature/78128-quick-copy-full-name-and-title' 2026-08-18 17:39:44 +02:00
Harald Bamberger 52c1fba17b Merge branch 'bugfix/78127-degree-programs-page-localization-ineffective' 2026-08-18 16:53:49 +02:00
Cristina 5e15d4b219 Add Distinct to getLeitung in Studiengang_model.php
Avoid multiple records for same active STGL.
e.g. double entries
2026-08-18 16:51:39 +02:00
Harald Bamberger 00954f680b Merge branch 'bugfix/78392-missing-searchbar-is-mobile-injectable' 2026-08-18 16:48:43 +02:00
Harald Bamberger 92d27fc242 Merge branch 'master' into feature/78128-quick-copy-full-name-and-title 2026-08-18 14:52:41 +02:00
Harald Bamberger f6bb27cdb0 Merge branch 'master' into bugfix/78127-degree-programs-page-localization-ineffective 2026-08-18 14:49:16 +02:00
Harald Bamberger 558963cd74 Merge branch 'master' into feature-78139/CIS4_Dashboard_ausgeblendete_Widgets 2026-08-18 14:42:44 +02:00
Harald Bamberger 0b5c0f27a5 Merge branch 'bugfix/77738-persisting-lv-menu' 2026-08-14 11:58:42 +02:00
adisposkofh f846bb221a refetching lv menu after a different calendar event is selected 2026-08-14 11:47:31 +02:00
Werner Masik d8355ba3f5 added Funktionsänderung to gehaltsanpassungtyp 2026-08-13 14:56:04 +02:00
ma0068 afb8011347 bugfix manual rebuilding of Tag ZGV Missing 2026-08-13 12:57:49 +02:00
Johann Hoffmann 46f8d0d07d remove all remaining projektarbeit-lehreinheit joins across the codebase;
master merge reverted the LE removal in Projektarbeit_model -> re-applied that fix and went through every file that touches tbl_projektarbeit to find remaining issues.

Projektarbeit_model, stv Projektarbeit controller, Vertrag_model, vertrag.class, lehrauftragsliste_gst.xls.php, zeitaufzeichnung.class.php, sammelzeugnis.rdf.php, zeugnis.rdf.php, projektarbeit.rdf.php,
lehrauftrag.xml.php, personal_lektorenohnelehrauftrag.php, personal_generateverwendung.php

tbl_lehreinheit joins remain in tbl_lehreinheitmitarbeiter contexts where lehreinheit_id is always set.
2026-08-12 18:05:45 +02:00
Harald Bamberger 6d5a4531e1 use tbl_studentlehrverband.semester instead of tbl_student.semester 2026-08-12 16:58:21 +02:00
Werner Masik d85a3cb08f extract DB migration for gehaltsanpassungtyp into separate file 2026-08-12 15:18:35 +02:00
ma0068 15beaa9be8 Merge branch 'feature-78257/StudVW_Und_Tags_Finetuning' of github.com:FH-Complete/FHC-Core into feature-78257/StudVW_Und_Tags_Finetuning 2026-08-12 12:42:10 +02:00
ma0068 574057da88 add masterzgv to CoremissingZgvLib 2026-08-12 12:41:39 +02:00
Harald Bamberger c81b5338de Merge branch 'master' into feature-78292/dv_gehaltsbestandteil_ersteinstufung 2026-08-12 11:39:49 +02:00
Harald Bamberger c433ff5c3a remove public/vendor symlink since created by composer install 2026-08-12 11:39:16 +02:00
Harald Bamberger ab2a0e93ed add public/vendor to .gitignore 2026-08-12 11:38:02 +02:00
Johann Hoffmann 9274743df3 Merge branch 'master' into feature-75469/LeOptional4Projektarbeit
# Conflicts:
#	application/controllers/api/frontend/v1/Abgabe.php
#	application/controllers/api/frontend/v1/stv/Projektarbeit.php
#	application/models/education/Projektarbeit_model.php
#	public/css/Studentenverwaltung.css
#	public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js
#	public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js
#	public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektarbeit.js
#	public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektbetreuer.js
2026-08-12 11:26:51 +02:00
Harald Bamberger d139c4ed66 Merge branch 'bug-78432/StudVw_Baum_fehlende_Route' 2026-08-12 10:23:23 +02:00
chfhtw dd410a74ba Add missing routes for StudVw 2026-08-12 10:14:02 +02:00
Harald Bamberger a5797a0bde Merge branch 'master' into feature-78257/StudVW_Und_Tags_Finetuning 2026-08-11 18:00:17 +02:00
Harald Bamberger 5c69ede19e Merge branch 'feature-78257/StudVW_Finetuning' 2026-08-11 17:53:06 +02:00
Harald Bamberger a5257eb934 rearange tiles, use placeholder if uid is not set 2026-08-11 17:50:33 +02:00
Harald Bamberger 317da29376 Merge branch 'master' into feature-78257/StudVW_Finetuning 2026-08-11 16:26:36 +02:00
adisposkofh 772b8c603c fixed issue with ineffective localization of courses in 'degree programs' page 2026-08-11 15:50:24 +02:00
Cristina 37d5f2da5d Merge branch 'master' into epic/LVEvaluierung-Neu 2026-08-11 15:45:27 +02:00
Cristina 27c39cfdca Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-08-11 15:45:08 +02:00
chfhtw 30c4e565dd bugfix: sprache index in studentlistlib corrected 2026-08-11 15:08:34 +02:00
Werner Masik d66fe72cc9 add field for salary adaption type (Ersteinstufung, indiv. Erhöhung, ..) 2026-08-11 11:18:36 +02:00
Harald Bamberger 684d4f890a Merge branch 'master' into feature-78257/StudVW_Finetuning 2026-08-11 10:49:05 +02:00
Harald Bamberger 10218305db Merge branch 'bug-78116/StudStatus_sendStglSammelmail_empty_list' 2026-08-11 10:40:26 +02:00
ma0068 31bae9b693 use function getStgAndDetails instead of getStgAndSem 2026-08-11 09:48:17 +02:00
adisposkofh 59ac56374e removed redundant response meta used for dev 2026-08-11 09:44:41 +02:00
adisposkofh a397460e0e Merge branch 'master' into feature/78128-quick-copy-full-name-and-title 2026-08-11 09:43:27 +02:00
Harald Bamberger c3c23d28bb Merge branch 'feature-76995/StudStatusModal_Hinweis_Beratungsgespraech_bei_Abmeldung' 2026-08-11 09:22:26 +02:00
Harald Bamberger 9f0b387ab6 use phrase ui/cancel instead of ui/abbrechen 2026-08-11 09:21:48 +02:00
Harald Bamberger 3a97f20122 add v-bind syntax to avoid prop type warning 2026-08-11 09:08:32 +02:00
Harald Bamberger 046a552f34 Merge branch 'master' into feature-76995/StudStatusModal_Hinweis_Beratungsgespraech_bei_Abmeldung 2026-08-11 08:11:55 +02:00
Harald Bamberger e8a534f0fe Cis MyLv Endpoints only require logged in user 2026-08-11 07:52:02 +02:00
Harald Bamberger 1f21ed7364 Merge branch 'feature-69378/Studienverlauf_verlinken_im_neuen_FAS' 2026-08-10 18:22:28 +02:00
Harald Bamberger 774a1b81c4 grades: change layout semester mode dropdown and gradelist link, details: remove css class from noImage img tag 2026-08-10 18:21:24 +02:00
Harald Bamberger f566ea1ac3 Merge branch 'master' into feature-69378/Studienverlauf_verlinken_im_neuen_FAS 2026-08-10 18:06:00 +02:00
adisposkofh 108f91ea1a quick copy option on full name and title in profile and other lv plan 2026-08-10 17:09:31 +02:00
Harald Bamberger 4a92511b9b Merge branch 'tabulator-localization-minor-fixes' 2026-08-10 17:04:31 +02:00
adisposkofh dc5a846c10 defaulting searchbar isMobile injectable to false when not provided 2026-08-10 16:24:58 +02:00
adisposkofh 364477f0e9 merged master into 2026-08-10 15:58:21 +02:00
adisposkofh d2ca33e757 Merge branch 'master' into tabulator-localization-minor-fixes 2026-08-10 15:57:12 +02:00
Harald Bamberger 8bfd90e159 Merge branch 'master' into feature-69378/Studienverlauf_verlinken_im_neuen_FAS 2026-08-10 14:48:41 +02:00
Harald Bamberger 8d8a4e8ca6 Merge branch 'feature/76688-general-tabulator-issues_77080-persistence' 2026-08-10 14:29:40 +02:00
ma0068 06895510e0 add reloadList if language is changed 2026-08-10 14:25:07 +02:00
ma0068 83b06b6c50 - Redesign Tags
- use Slot in Filter Component
- use Phrase  for relaoding Tag in Detail Header
2026-08-10 14:04:45 +02:00
Harald Bamberger d710b4a9e4 Merge branch 'master' into feature/76688-general-tabulator-issues_77080-persistence 2026-08-10 13:11:12 +02:00
Werner Masik bd99f3f927 add db schema for gehaltsanpassungtyp 2026-08-10 12:20:30 +02:00
Cristina eeb1529b64 Merge branch 'master' into epic/LVEvaluierung-Neu 2026-08-10 12:07:45 +02:00
Cristina 98c3707802 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-08-10 12:07:01 +02:00
adisposkofh 43e9dad17d double checking if tabulator header filter inputs are filled in on preset application 2026-08-10 11:06:17 +02:00
Harald Bamberger a27fa50e42 Merge branch 'studvw_lvvw_2026_08_rc_77973_76688' 2026-08-10 09:16:11 +02:00
Harald Bamberger 196e9be728 comment in groups in lvvw treemenu to have them for drag and drop, add language and isMobile injects to prevent warnings from searchbar component, studvw clear selection when degree program changes, update fontawesome from 6.1.1 to 6.7.2 and primeicons from 5.0.0 to 6.0.1 to prevent glyph bbox warnings in ff browser console 2026-08-10 06:48:53 +02:00
Harald Bamberger a00f6363d9 add legacy bis links to app menu and needed phrases, consistently use appMenuLvPlanungItems computed for LvPlanung app menu extra items 2026-08-07 17:11:38 +02:00
adisposkofh a65b0d693f implemented spinner while tabulator preset is being applied 2026-08-07 12:02:52 +02:00
Johann Hoffmann cdcc88c04e check for schlagwoerter length in zusatzdaten frontend/backend - likely the cause of finished projects with missing data; extracted a lot more duplicate code across a abgabetool mixin; put the multiSelectHeaderFilter.js into tabulator/filters to reuse since 2 abgabetool pages already use it for 6 columns; checked over AbgabetoolJob.php again to make sure to avoid unnecessary automated emails + some logging; 2026-08-06 16:38:07 +02:00
Harald Bamberger 736e897928 fix automated tags not found in stv search 2026-08-06 16:23:54 +02:00
Harald Bamberger 21f8bb39b5 reload list after rebuild tags for degree program or selection 2026-08-06 16:04:35 +02:00
Harald Bamberger cd87ecc2d9 fix assign batchUser 2026-08-06 15:00:35 +02:00
Johann Hoffmann 6a67eb750e check for schlagwoerter length in zusatzdaten frontend/backend - likely the cause of finished projects with missing data 2026-08-06 14:11:44 +02:00
adisposkofh a3ae14b3f5 Merge branch 'master' into feature/76688-general-tabulator-issues_77080-persistence 2026-08-06 14:08:55 +02:00
adisposkofh 6cf4458dcd fixed ordering of columns in column filter while preset ios applied 2026-08-06 14:06:25 +02:00
Harald Bamberger 59b8d195c1 reaply TagHelper from 77417 to fix adding tags without reloading stv studentlist 2026-08-06 13:52:59 +02:00
ma0068 7926a2b201 add Tile PrestudentID to FHC Header 2026-08-06 13:26:33 +02:00
Harald Bamberger b6aa459b98 Merge branch 'feature-777242/StudVW_alternative_Contacting_ma0080' into studvw_lvvw_2026_08_rc_77973_76688 2026-08-06 11:56:18 +02:00
Harald Bamberger 53a9fab70b use neutral phrase for webmail 2026-08-06 09:43:02 +02:00
Harald Bamberger 5182f13bdb add checked indicator to webmail client links when clicked 2026-08-06 09:34:16 +02:00
Harald Bamberger 804dfc9327 refactor and add localStorage for webmail mode 2026-08-06 08:14:05 +02:00
Harald Bamberger 74e2d1dcc5 ensure tabulator is rendered after required phrases are loaded, apply optionalTabulatorOptions column visibility if set and localstorage does not already contain user preferences 2026-08-06 07:46:16 +02:00
Cristina e5c8807f17 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-08-05 15:13:35 +02:00
Harald Bamberger af9e34a8ae Merge branch 'feature/76688-general-tabulator-issues_77080-persistence' into studvw_lvvw_2026_08_rc_77973_76688 2026-08-05 13:48:03 +02:00
Harald Bamberger 10a97a80de add missing nav-language component import 2026-08-05 13:35:51 +02:00
Harald Bamberger abd2f831f2 Merge branch 'studvw_lvvw_2026_08_rc' into studvw_lvvw_2026_08_rc_77973_76688 2026-08-04 16:58:03 +02:00
Harald Bamberger 9d7f48f52c Merge branch 'master' into studvw_lvvw_2026_08_rc 2026-08-04 16:57:43 +02:00
Harald Bamberger dd1a5064e4 tabs: add padding to prevent minimal horizontal scrolling 2026-08-04 16:54:53 +02:00
Harald Bamberger a3ca578b3d Merge branch 'studvw_lvvw_2026_08_rc' into studvw_lvvw_2026_08_rc_77973_76688 2026-08-04 16:13:55 +02:00
Harald Bamberger e37321eeff Merge branch 'master' into studvw_lvvw_2026_08_rc 2026-08-04 16:13:36 +02:00
adisposkofh 505c71b18c reworked applying tabulator presets for efficiency 2026-08-04 16:10:40 +02:00
Harald Bamberger efde2e9601 Merge branch 'feature-76201/StudVWTabsBeibehalten' 2026-08-04 16:05:56 +02:00
Harald Bamberger 8f34142599 Merge branch 'master' into feature-76201/StudVWTabsBeibehalten 2026-08-04 16:04:01 +02:00
Harald Bamberger 6570cc1fd7 Merge branch 'bug-76780/StudVW_Messages_MultiAction_lock_SendButton_and_Modal_during_Sending' 2026-08-04 15:52:44 +02:00
Harald Bamberger fed0afd426 Merge branch 'master' into bug-76780/StudVW_Messages_MultiAction_lock_SendButton_and_Modal_during_Sending 2026-08-04 15:46:03 +02:00
Harald Bamberger 2c2c6efc5e Merge branch 'studvw_lvvw_2026_08_rc' into studvw_lvvw_2026_08_rc_77973_76688 2026-08-04 15:41:37 +02:00
Harald Bamberger 0419286557 Merge branch 'master' into studvw_lvvw_2026_08_rc 2026-08-04 15:41:05 +02:00
Harald Bamberger 08f6bee2e4 Merge branch 'feature-775595/StudVW_Notizen_konfigurierbar' 2026-08-04 15:34:30 +02:00
Harald Bamberger cfa4dd8b8a add padding to filtercomponent tabulator-tableholder to prevent scrollbar covering a row in tables with few rows 2026-08-04 15:33:36 +02:00
Harald Bamberger ab637ded26 stv config: change default for notes showErweitert to false 2026-08-04 15:12:17 +02:00
Harald Bamberger 4c072aa819 Merge branch 'master' into feature-775595/StudVW_Notizen_konfigurierbar 2026-08-04 14:49:08 +02:00
Harald Bamberger f693f9d17c add padding to tabulator container, e.g. to make resizing of last column possible 2026-08-04 14:45:53 +02:00
chfhtw 2f86a1b017 Changing the edit button into a toggle 2026-08-04 10:46:08 +02:00
chfhtw 75ddbdf7c1 Recovery items on top 2026-08-04 10:24:29 +02:00
chfhtw d824334538 Hiding widgets should look like deleting and recovering is moved to the "add widget" popup 2026-08-04 09:42:18 +02:00
chfhtw 13515b2522 Bugfix: after a drag and drop operation, when resizing the page, the moved item stays in the drop position even if it has had a position in the resized layout 2026-08-04 09:40:47 +02:00
Harald Bamberger ecfe648bf5 Merge branch 'master' into studvw_lvvw_2026_08_rc_77973_76688 2026-08-03 19:36:18 +02:00
Harald Bamberger bddd7b5d65 Merge branch 'bugfix/78150-other-lv-plan-displays-locked-profile-pics' 2026-08-03 19:31:12 +02:00
Harald Bamberger 2686aee158 avoid multiple assignments to one variable 2026-08-03 19:30:49 +02:00
Harald Bamberger b7a2198057 Merge branch 'feature/76688-general-tabulator-issues_77080-persistence' into studvw_lvvw_2026_08_rc_77973_76688 2026-08-03 17:04:34 +02:00
Harald Bamberger bf6b588675 only select active rows with ctrl + a 2026-08-03 17:02:43 +02:00
adisposkofh b427788e04 renamed tabulator presets-related phrases 2026-08-03 17:02:40 +02:00
Harald Bamberger e7e561a4ba Merge branch 'feature/76688-general-tabulator-issues_77080-persistence' into studvw_lvvw_2026_08_rc_77973_76688 2026-08-03 16:29:21 +02:00
adisposkofh d9972c0d32 Merge branch 'feature/76688-general-tabulator-issues_77080-persistence' of github.com:FH-Complete/FHC-Core into feature/76688-general-tabulator-issues_77080-persistence 2026-08-03 16:28:16 +02:00
adisposkofh 6c03110442 removed redundant collapse-auto directives from table presets 2026-08-03 16:27:50 +02:00
adisposkofh f717fb462f fixed issue with tabulator applying preset before table is built 2026-08-03 16:27:26 +02:00
Harald Bamberger 640a7285e1 activate presets for stv list table and add default preset 2026-08-03 16:08:22 +02:00
Harald Bamberger e9fc0629f5 Merge branch 'feature/76688-general-tabulator-issues_77080-persistence' into studvw_lvvw_2026_08_rc_77973 2026-08-03 16:06:34 +02:00
Harald Bamberger 6f0279d451 Merge branch 'master' into feature/76688-general-tabulator-issues_77080-persistence 2026-08-03 14:58:07 +02:00
Harald Bamberger 2d73f97a25 Merge branch 'studvw_lvvw_2026_08_rc' into studvw_lvvw_2026_08_rc_77973 2026-08-03 14:49:42 +02:00
Harald Bamberger dcd6163198 fix typo 2026-08-03 14:49:11 +02:00
Harald Bamberger 9f68fe6b3b Merge branch 'feature-77973/StudVw-Feedback_Finetuning_bhmod' into studvw_lvvw_2026_08_rc 2026-08-03 11:18:34 +02:00
Harald Bamberger 7c9f6d89d6 move setting index_bezeichnung_mehrsprachig to StudentListLib 2026-08-03 10:43:53 +02:00
Harald Bamberger ea3d01d23b rebuild tags for degree programm or selection - split in multiple requests and render progressbar in loading modal 2026-08-03 08:37:45 +02:00
Harald Bamberger c4ffc7283d Merge branch 'master' into bug-76780/StudVW_Messages_MultiAction_lock_SendButton_and_Modal_during_Sending 2026-07-31 17:06:30 +02:00
Harald Bamberger 0fa663145d Merge branch 'master' into studvw_lvvw_2026_08_rc 2026-07-31 17:04:26 +02:00
Harald Bamberger b49831cae8 Merge branch 'bug-77253/StudVw_Abschlusspuefung_ImproveDropDownAkadGrad' 2026-07-31 16:59:30 +02:00
Harald Bamberger c616e9d450 Merge branch 'master' into bug-77253/StudVw_Abschlusspuefung_ImproveDropDownAkadGrad 2026-07-31 16:42:28 +02:00
Harald Bamberger 9b0607ca74 use refactored routes 2026-07-31 16:34:32 +02:00
Harald Bamberger 3d728fd884 Merge branch 'master' into studvw_lvvw_2026_08_rc 2026-07-31 15:51:35 +02:00
chfhtw 2b4aef5633 Merge branch 'feature-77417/studvw-tags-formatter-and-header-filter' into studvw_lvvw_2026_08_rc 2026-07-31 12:52:29 +02:00
Harald Bamberger dca30dccf3 Merge branch 'bug-78215/LVPlanEintraege_in_Sommerluecke_werden_nicht_immer_angezeigt' 2026-07-31 11:05:54 +02:00
Harald Bamberger b9d4aefd5e add meta info 2026-07-31 11:02:46 +02:00
Harald Bamberger 69048f8f48 bugfix semester calculation between semesters 2026-07-31 09:51:04 +02:00
adisposkofh 36fe0a0f3c including non-localized column title in column filter collapsible 2026-07-29 15:26:07 +02:00
adisposkofh c5e296d557 replacing language injectable with computed property 2026-07-29 13:48:08 +02:00
adisposkofh d1ca6eb988 reworked other lv plan view data controller using profil library 2026-07-29 11:28:13 +02:00
adisposkofh be4db980ad fixed issue with displayed locked profile images in other lv plan 2026-07-29 11:17:03 +02:00
ma0048 0ef905c6f2 use language index 2026-07-29 11:15:24 +02:00
ma0048 21f0b18af4 merged #75959 and added horizontalsplit to lvverwaltung 2026-07-29 10:52:02 +02:00
adisposkofh 6a786df198 disabling columns, header filters, sort persistence in tabulator where presets are used 2026-07-29 09:56:00 +02:00
ma0048 4e16220da1 Merge remote-tracking branch 'origin/feature-75959/StudVw_Automatische_Tags' into studvw_lvvw_2026_08_rc
# Conflicts:
#	application/controllers/api/frontend/v1/stv/Students.php
2026-07-29 09:53:48 +02:00
Harald Bamberger 5ce02d747c lvvw apps menu fix reports links using studiengang_kz 2026-07-29 08:50:50 +02:00
Harald Bamberger 9c31b27339 set vuejs app names 2026-07-28 16:23:56 +02:00
Harald Bamberger aa52c32d40 Merge branch 'feature-77372/lv_verwaltung_release_fine_tuning' into studvw_lvvw_2026_08_rc 2026-07-28 15:50:06 +02:00
Harald Bamberger 02a97fb0e2 Merge branch 'feature-76160/StudVw_Verbandsbaum_durch_Extensions_erweiterbar_machen' into studvw_2026_08_rc 2026-07-28 15:35:54 +02:00
adisposkofh 2107c0839f removed obsolete testing lines in lvv 2026-07-28 12:49:40 +02:00
adisposkofh b277725cc3 displaying name of applied tabulator preset (w/ 'modified' marker as necessary) 2026-07-28 12:48:28 +02:00
Harald Bamberger aade60179d Merge branch 'master' into studvw_2026_05_rc_tags 2026-07-28 11:46:32 +02:00
adisposkofh e029b09add persisting tabulator preset in local storage 2026-07-27 16:53:07 +02:00
adisposkofh 47b9e6c086 removed redundant declared emit in tabulator presets 2026-07-27 16:11:47 +02:00
adisposkofh 2fa8fd1703 resolved warning; checking tabulator init before calling getLang in custom module 2026-07-27 16:08:17 +02:00
adisposkofh 89ea4187fa merged master into 2026-07-27 15:58:08 +02:00
chfhtw 0e099b2752 Remove deprecated files and lv_favorites variable 2026-07-24 14:05:50 +02:00
chfhtw d7f383b969 stud & lv verwaltung: add component to each route (childroutes should inherit those but a warning is thrown) 2026-07-24 10:57:40 +02:00
ma0048 a22a8acf83 fixed drag and drop 2026-07-24 09:12:12 +02:00
chfhtw 5c7df11ff3 Phrase corrected 2026-07-23 15:05:26 +02:00
chfhtw c83674fc41 StudentListLib: store where clauses and add it in later in execute function to prevent errors like in Task:78115 2026-07-23 15:05:11 +02:00
ma0068 dcd17bb34f add Compatibility Mode for SOGO
add logic for BCC to default Mail Client Version
add phrases
2026-07-23 11:25:22 +02:00
Harald Bamberger ed1925b517 Merge branch 'master' into feature-76160/StudVw_Verbandsbaum_durch_Extensions_erweiterbar_machen 2026-07-23 09:11:43 +02:00
Harald Bamberger 5d024b3a71 Merge branch 'feature-77978/Renew_52546_and_53902' 2026-07-23 08:01:44 +02:00
Harald Bamberger 507b47e9ea add name to Udf component 2026-07-23 07:59:02 +02:00
chfhtw e7d2d3502b Allow callables in $redirect_method 2026-07-22 16:45:23 +02:00
ma0068 54168c86b4 add Abstand 2026-07-22 14:41:59 +02:00
ma0068 a8dd995195 rebuild tags for whole studiengang / selection
refactor backend for multiaction rebuildTags
add phrases
refactor haederFilter
2026-07-22 14:11:07 +02:00
chfhtw f46a3c1f68 LvVerwaltung: add routes for orgform and adapt endpoint to accept lower case orgform_kurzbz 2026-07-22 10:36:38 +02:00
Paolo a83fe561b9 Added the new property "readonly" to the UDF component to switch between edit and readonly mode for all the UDfs 2026-07-22 09:18:23 +02:00
chfhtw ae56a4f2ed Move LvVerwaltung treemenu config to config file and disable groups & verband per default 2026-07-21 14:57:41 +02:00
Harald Bamberger 22b1f2822a fix typo 2026-07-21 14:45:07 +02:00
Harald Bamberger 1fd15e14d5 Merge branch 'master' into feature-76160/StudVw_Verbandsbaum_durch_Extensions_erweiterbar_machen 2026-07-21 14:06:04 +02:00
ma0068 1ae02d8ed8 refactor addTaginTable and deleteTagInTable, add missing logic for automated tags in case of manual adding 2026-07-21 13:35:31 +02:00
ma0068 7cda22f807 use language index for tags 2026-07-21 10:41:27 +02:00
ma0068 68292b60af add Tags Incoming and Preabbrecher 2026-07-20 17:36:54 +02:00
Johann Hoffmann ef3015dff2 also check for abgabetermin note on upload in backend 2026-07-20 11:28:49 +02:00
Johann Hoffmann 1b599b49ed actually block upload for graded abgabetermine (quality gates) for students, not only assistenz; updated tooltip accordingly; 2026-07-20 11:04:26 +02:00
chfhtw 542590b470 Remove comment 2026-07-20 09:26:31 +02:00
chfhtw eb460fdc0a Fix buildApiUrl 2026-07-17 14:05:04 +02:00
chfhtw 65e76e951a Translate treemenu entries 2026-07-17 12:01:17 +02:00
chfhtw 43d69a5683 Add comma for better merging 2026-07-17 12:01:08 +02:00
Harald Bamberger 6c25a3b262 Merge branch 'feature-77537/Studvw_Feedback' into studvw_2026_05_rc_tags 2026-07-17 11:38:46 +02:00
Harald Bamberger 1f6c9e865b Merge branch 'bug-77392/StudVW_Dokumente_Nachreichlogik_fehlendeBezeichnung' into studvw_2026_05_rc_tags 2026-07-17 11:30:23 +02:00
Harald Bamberger 1abfbccb3e Merge branch 'bug-77399/AppMenu_Show_Toasts' into studvw_2026_05_rc_tags 2026-07-17 11:25:11 +02:00
Harald Bamberger 362d1c8bb0 Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-07-17 11:22:50 +02:00
Harald Bamberger 25a61a56b7 Merge branch 'master' into studvw_2026_05_rc 2026-07-17 11:22:20 +02:00
Harald Bamberger afb210b0c2 Merge branch 'master' into studvw_2026_05_rc 2026-07-17 11:21:24 +02:00
Harald Bamberger c84146fcbd Merge branch 'bug-77989/StudVW_Datepicker_check_modeltype' 2026-07-17 10:36:23 +02:00
ma0068 35decf476c make fields deletable with keyboard: Konto Buchungsdatum, Prüfung Datum, Abschlussprüfung Datum und Sponsion, Mobilität von und bis 2026-07-17 09:12:02 +02:00
chfhtw 0471f838b9 Remove empty lines for better merge compatibility 2026-07-17 07:46:11 +02:00
chfhtw 1c9d9d1ce5 Add additional computed instead of deleted props 2026-07-17 07:44:45 +02:00
chfhtw 379a99cb14 Add empty function to let git detect where to merge 2026-07-17 07:43:22 +02:00
chfhtw 0d29a9ba32 Revert fix for merge compatibility 2026-07-17 07:40:15 +02:00
chfhtw ed44732eef Remove things that where commented out 2026-07-17 07:39:50 +02:00
Harald Bamberger 6cfc4b0973 Merge branch 'master' into bug-77989/StudVW_Datepicker_check_modeltype 2026-07-16 16:01:25 +02:00
Harald Bamberger 6296b87ea5 Merge branch 'bug-77989/StudVW_Datepicker_check_modeltype' 2026-07-16 15:54:18 +02:00
Harald Bamberger 576a44838f datetime format bewerbung_abgeschickt_am 2026-07-16 15:53:32 +02:00
Harald Bamberger c00e7a182c Merge branch 'master' into bug-77989/StudVW_Datepicker_check_modeltype 2026-07-16 15:00:45 +02:00
ma0068andHarald Bamberger fd1b5daf9c enable deletion of zgv and zgv master date with null and empty string 2026-07-16 14:51:38 +02:00
Harald Bamberger c0b5f2f748 add permission to DetailHeader function for use in pv21 2026-07-16 12:58:00 +02:00
chfhtw d391d1f09c Move computed to the correct position to avoid merge conflicts 2026-07-16 11:43:51 +02:00
chfhtw a36ed55390 Add new props to beginning to avoid merge conflicts 2026-07-16 11:43:10 +02:00
chfhtw b0f317951b Add lvv_favorites 2026-07-15 16:18:39 +02:00
chfhtw f65135be1e For each treemenu seperate favorites 2026-07-15 16:18:19 +02:00
chfhtw b8d86ba628 Use luxon date formatters in studvw student list 2026-07-15 14:48:55 +02:00
ma0048 e9312dfbb3 lvverwaltung new release 2026-07-15 11:35:37 +02:00
ma0048 b21900d006 Merge remote-tracking branch 'origin/feature-70656/lvverwaltung_gruppen_im_baum_und_drag_and_drop' into feature-77372/lv_verwaltung_release_fine_tuning 2026-07-15 11:27:48 +02:00
chfhtw 11cfa670d6 Add dynamic tabulatorcolumns to lvverwaltung 2026-07-15 11:05:37 +02:00
chfhtw a94fbeba14 Only call reloadTable if a table was loaded 2026-07-15 11:05:37 +02:00
chfhtw e01b816ee8 Add treemenudata routes to lvverwaltung 2026-07-15 11:05:36 +02:00
chfhtw 52c90111cc Add treemenu to lvverwaltung 2026-07-15 11:01:03 +02:00
ma0048 012571d070 Merge remote-tracking branch 'origin/feature-69453/lv_verwaltung_karteireiter_noten' into feature-77372/lv_verwaltung_release_fine_tuning
# Conflicts:
#	public/js/components/Stv/Studentenverwaltung/Details/Noten/Teacher.js
#	public/js/components/Stv/Studentenverwaltung/Details/Noten/Zeugnis.js
2026-07-15 09:43:53 +02:00
ma0048 a2d10ae09d Merge remote-tracking branch 'origin/feature-69454/lvverwaltung_karteireiter_lv_termine' into feature-77372/lv_verwaltung_release_fine_tuning
# Conflicts:
#	application/controllers/api/frontend/v1/LvPlan.php
#	public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine/ListLehrveranstaltungstermine.js
2026-07-15 09:32:03 +02:00
ma0048 96bf45ceb0 Merge remote-tracking branch 'origin/feature-75410/lvverwaltung_finetuning' into feature-77372/lv_verwaltung_release_fine_tuning
# Conflicts:
#	system/phrasesupdate.php
2026-07-15 09:26:55 +02:00
ma0048 c233902fe2 Merge remote-tracking branch 'origin/feature-70746/lvverwaltung_lektorentausch' into feature-77372/lv_verwaltung_release_fine_tuning
# Conflicts:
#	application/libraries/LektorLib.php
2026-07-15 09:20:57 +02:00
ma0048 fd8de88abb Merge remote-tracking branch 'origin/bug-69283/scroll_verhalten_lv_verwaltung_anders_als_in_studierendenverwaltung' into feature-77372/lv_verwaltung_release_fine_tuning 2026-07-15 09:17:51 +02:00
ma0048 0ec2c8c543 Merge remote-tracking branch 'origin/bug-69492/bug_lvverwaltung_doppelte_eintraege' into feature-77372/lv_verwaltung_release_fine_tuning 2026-07-15 09:17:29 +02:00
ma0048 29738b6690 Merge remote-tracking branch 'origin/feature-69353/lv_verwaltung_stundensatz_auf_leer_setzen_geht_nicht' into feature-77372/lv_verwaltung_release_fine_tuning 2026-07-15 09:17:19 +02:00
Alexei Karpenko c5c29df6cc Gehaltsbestandteil, Gehaltsbestandteil_model: added gehaltstyp_bezeichnung 2026-07-14 20:51:41 +02:00
ma0068 b217681ee5 use model-type for interessenten anlegen, listNew 2026-07-14 15:23:06 +02:00
ma0068 7841a73fc0 prepare field bewerbung_abgeschicktamum for showing in frontend (datestamp in database) and add also model-type to datepicker 2026-07-14 15:05:54 +02:00
chfhtw 0b1d0fbe4c Merge branch 'master' into feature-76160/StudVw_Verbandsbaum_durch_Extensions_erweiterbar_machen 2026-07-14 14:31:51 +02:00
ma0068 2064008f9e add model-type to fields Betriebsmittel/ausgegebenam, Betriebsmittel/retouram, Funktionen/datumvon und Funktionen/datumbis 2026-07-14 14:31:13 +02:00
ma0068 19b9906c86 Aufnahmetermine: use model-type isodate for field anmeldedatum 2026-07-14 14:23:37 +02:00
chfhtw 85807f5b8c Allow treemenu entries to become draggables 2026-07-14 14:21:39 +02:00
chfhtw a1950d179b draggable directive: better handling of falsy values, better cleanup, remove attributes on falsy value/effect 2026-07-14 14:21:09 +02:00
ma0068 2c3913a763 Mobility: use model-type isodate for fields von and bis 2026-07-14 14:19:25 +02:00
ma0068 9111edf442 Dokumente: use model-type isodate for field nachgereicht_am 2026-07-14 14:06:59 +02:00
ma0068 b1c47da3c3 use model-type isodate for fields in StatusModal datum and bestaetigtam 2026-07-14 14:01:12 +02:00
ma0068 67eb238876 use model-type isodate for field Details Gebdatum 2026-07-14 13:37:19 +02:00
Harald Bamberger d4929c8e22 Merge branch 'studvw_2026_05_rc_tags' into feature-77537/Studvw_Feedback 2026-07-14 10:52:31 +02:00
Harald Bamberger 194b74e390 Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-07-14 10:52:05 +02:00
Harald Bamberger ee70e43bfb Merge branch 'master' into studvw_2026_05_rc 2026-07-14 10:51:40 +02:00
Harald Bamberger f8d8d501ca Merge branch 'studvw_2026_05_rc_tags' into feature-77537/Studvw_Feedback 2026-07-13 14:42:54 +02:00
Harald Bamberger 7e6d670d82 Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-07-13 14:32:51 +02:00
Harald Bamberger f3a3bfcab6 Merge branch 'master' into studvw_2026_05_rc 2026-07-13 14:30:36 +02:00
chfhtw d134509c90 Remove unused routes 2026-07-13 13:13:06 +02:00
chfhtw 4424c7d748 Handle "incoming" menu entry (in inout and prestudent filters) 2026-07-13 13:03:23 +02:00
chfhtw d436d8cb20 Check permissions for prestudent menu entry 2026-07-13 13:02:40 +02:00
Ivymaster 86c06e4756 BUG: issue fix for dropdown reposition errror 2026-07-10 11:50:07 +02:00
Johann Hoffmann f346bc6fcb zweitbetreuer in StudentDetail; query the fullname of insertvon user to display upon creating a new abgabetermin; 2026-07-09 15:53:09 +02:00
ma0068 3689c64b7b make also notizlayout configurable 2026-07-09 11:01:00 +02:00
ma0068 26ddd404c0 add geschlecht to dropdown and adapt default according to geschlecht 2026-07-09 08:57:17 +02:00
Harald Bamberger 2e33722674 Merge branch 'master' into studvw_2026_05_rc 2026-07-08 16:43:56 +02:00
Harald Bamberger b5e65cf072 Merge branch 'master' into studvw_2026_05_rc 2026-07-08 16:42:04 +02:00
chfhtw b991bbd9a5 Allow extra columns for studvw student list 2026-07-08 11:00:20 +02:00
chfhtw 5bed848aae Merge branch 'master' into feature-76160/StudVw_Verbandsbaum_durch_Extensions_erweiterbar_machen 2026-07-08 09:43:58 +02:00
Ivymaster f3b617d339 add removal of tag header sorting in LV and Student verwaltung 2026-07-07 17:13:51 +02:00
ma0068 a4c5f9946f change doku 2026-07-07 16:56:35 +02:00
Ivymaster 0be3505163 BUG: Add fix for tag dropdown issue during tag column drag 2026-07-07 16:50:44 +02:00
ma0068 81f0b7a4bf make showErweitert configurable 2026-07-07 16:43:01 +02:00
Ivymaster 6c550372a3 add definable tag column in modified helpers 2026-07-07 15:49:16 +02:00
ma0068 c86d6f4bf3 - enable opening in new tab with prevent.default
- rendering of maillinks
- useBCC without CC
2026-07-07 14:31:23 +02:00
chfhtw c59b24ab4a App urls for studierendenverwaltung (neu: /studvw) 2026-07-03 12:16:30 +02:00
ma0068 c194e94b5c add private email to detailHeader 2026-07-02 16:46:09 +02:00
ma0068 6d23f2b9fa Add Einstiegssemester
- calculate semester_berechnet also for Stati 'Aufgenommener','Bewerber','Wartender'
- show Einstiegssemester in DetailHeader for 'Aufgenommener','Bewerber','Wartender' and 'Interessent'
2026-07-02 15:58:23 +02:00
chfhtw 0b70153da0 throw 404 on endpoints with invalid studiengang 2026-07-02 15:32:20 +02:00
chfhtw 190d797d31 adapt routes and endpoints for getPrestudent, getStudent & getPerson 2026-07-02 14:36:30 +02:00
ma0068 fb1c7f8e90 Rename Lehraufträge to Lehrauftragsverwaltung 2026-07-02 08:12:06 +02:00
chfhtw 6428fccc48 Replace CoreRESTClient calls with $api calls in stv Studiensemester component and add logic to accept lowercase input (because it could come from the url) 2026-07-01 15:45:09 +02:00
ma0068 093e3d5c97 enable deletion of zgv and zgv master date with null and empty string 2026-06-30 15:43:19 +02:00
ma0068 9bc9e57deb add selectable to tabledownload in studentList 2026-06-30 14:28:12 +02:00
chfhtw 483d8f733f adapt routes and endpoints 2026-06-30 14:21:32 +02:00
Ivymaster eb885bfea7 BUG: fix issue with unexpected closing of tag filter dropdown 2026-06-30 14:20:04 +02:00
ma0068 be5aad7c33 only bind hover event if existing dropdown to avoid error 2026-06-30 11:15:32 +02:00
ma0068 b7940a5cce add mouse-over functionality to dropdowns LvPlanung and Notenspiegel 2026-06-30 10:53:15 +02:00
Ivymaster f9b3939d09 BUG: add issue fix for tag dropdown close on column drag 2026-06-30 10:33:24 +02:00
Ivymaster 69b19562f4 BUG: add issue fix for tag ordering 2026-06-30 10:27:16 +02:00
ma0068 9948060ed8 add shortcut str+alt for studentlist, add css for studentNames scrollable 2026-06-30 08:26:41 +02:00
ma0068 06ec020c1c make div for studentNames scrollable, do not show details in alert if ok 2026-06-30 08:25:46 +02:00
ma0068 01f2099c28 remove injection currentSemester, already as prop 2026-06-30 08:24:08 +02:00
chfhtw 9cb5d0895d Rework Treemenu endpoint and libraries 2026-06-29 16:12:32 +02:00
Ivymaster 086b271480 add implementation for custom tag filter in "LVVerwaltung" 2026-06-29 14:47:43 +02:00
Ivymaster 03b2d3d1a4 extracted some code related to tags from component to helper 2026-06-29 14:02:42 +02:00
ma0068 ff38731077 refactor rowSelectionChanged 2026-06-29 13:55:11 +02:00
Ivymaster 5399375bc1 add tags extraction from nested rows 2026-06-29 13:12:29 +02:00
ma0068 3e8445304c detailheader: append tagContainer only for one selected student 2026-06-29 11:40:32 +02:00
Ivymaster b047b95505 extracted repeated code to function in extendedHeaderFilter.js 2026-06-29 11:36:03 +02:00
ma0068 3e48401a04 add uids to success and error alerts 2026-06-29 11:16:10 +02:00
Ivymaster 48f07eb3ca added width buffer for tags display 2026-06-29 09:41:52 +02:00
Ivymaster db5339e4a5 BUG: Fix random issues found during testing 2026-06-27 17:54:24 +02:00
Ivymaster 4ed87b5c2b add custom tag filter 2026-06-27 12:29:28 +02:00
Harald Bamberger d680c3aa2b Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-06-26 15:17:02 +02:00
Harald Bamberger d98bdb9745 Merge branch 'master' into studvw_2026_05_rc 2026-06-26 15:16:37 +02:00
ma0068 90907d4276 add persistance pruefungsantritt_kurzbz to abschlusspruefung 2026-06-26 13:45:14 +02:00
chfhtw 4a283ebf5d rename menu => treemenu 2026-06-25 16:46:18 +02:00
chfhtw e27e64414a Merge branch 'master' into feature-76160/StudVw_Verbandsbaum_durch_Extensions_erweiterbar_machen 2026-06-25 16:34:09 +02:00
Ivymaster c47ac926d2 WIP 2026-06-25 15:23:41 +02:00
ma0068 f751df55b6 update query isPrestudentOutgoing to show only outgoing 2026-06-25 13:27:17 +02:00
ma0068 ecd6588ead edit default permissions: in core controller admin, in stv controller admin and assistance 2026-06-25 12:56:35 +02:00
ma0068 e7c133586b adding of 4 new colours and use shorter labels for automated tags 2026-06-25 08:47:00 +02:00
ma0068 d5ee6f9cc2 adapt query for outgoing students 2026-06-24 15:48:04 +02:00
ma0068 a721c1d14d add default permission assistenz:rw for tag functionality 2026-06-24 15:22:57 +02:00
ma0068 b662fa5fd3 show date of hochgeladenum in case of nachgereicht 2026-06-23 12:55:33 +02:00
ma0068 21886e30a3 refactor query getUnacceptedDocuments 2026-06-22 08:50:10 +02:00
ma0068 2ab2176795 use language index in all getting Functions for Tags 2026-06-19 13:50:19 +02:00
ma0068 df2f142f37 add toasts if no taken selections for Notenspiegel, LVplanung and Studienverlauf 2026-06-18 11:45:01 +02:00
Harald Bamberger c7bac03429 concat escaped string correct 2026-06-17 17:45:18 +02:00
Harald Bamberger 07d3b32279 fix typo 2026-06-17 17:23:05 +02:00
Harald Bamberger 245d0d3369 Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-06-17 17:15:37 +02:00
Harald Bamberger d3d04c5a77 Merge branch 'master' into studvw_2026_05_rc 2026-06-17 14:44:25 +02:00
Johann Hoffmann f4cc311806 getFormData (which loads lehrveranstaltungen) on editProjektarbeit + always query with student.studiengang_kz to have the same set of options when creating the projektarbeit; should work for incomings aswell. first attempt: lva in studienplan of last studentenstatus; if that yields no options just take the full lv list; 2026-06-17 10:44:55 +02:00
adisposkofh ff58f7a102 minor fix 2026-06-16 17:23:01 +02:00
adisposkofh c0ed296ba7 Revert "phrase typo fix"
This reverts commit a59f6085fe.
2026-06-16 17:21:15 +02:00
adisposkofh 2692806d4f not syncing dev-provided general table presets 2026-06-16 17:19:27 +02:00
adisposkofh a59f6085fe phrase typo fix 2026-06-16 16:59:36 +02:00
Johann Hoffmann df46b8ebdd Merge remote-tracking branch 'origin/master' into feature-75469/LeOptional4Projektarbeit 2026-06-16 10:46:44 +02:00
Harald Bamberger cce1c50495 override permission for all methods not only the overwritten ones 2026-06-15 16:46:31 +02:00
adisposkofh 4474a24ee2 streamlined collapsing table presets sub-collapsibles when tablePresets is collapsed 2026-06-11 14:09:45 +02:00
adisposkofh f59e5a20ea formatting preset info/new preset overviews 2026-06-11 13:36:26 +02:00
adisposkofh c9fe633706 localized tabulator preset backend error messages 2026-06-11 13:21:56 +02:00
adisposkofh 3ced1966f4 minor fix 2026-06-11 12:53:34 +02:00
adisposkofh 538223752b hiding preset info/new preset form when table presets section is collapsed 2026-06-11 12:38:57 +02:00
adisposkofh c9011fd6ed minor naming change in table presets 2026-06-11 11:30:42 +02:00
adisposkofh f0f9becc1f fixed new table preset info string formatting 2026-06-11 11:29:29 +02:00
adisposkofh 34c210a2a7 fixed table preset info string formatting 2026-06-11 11:27:43 +02:00
adisposkofh 7abd35d11b added tabulator preset phrases 2026-06-11 11:20:34 +02:00
adisposkofh d2c97d0238 check to sync table preset with modified config 2026-06-10 14:43:20 +02:00
adisposkofh 1d0ca15bcb passing generalPresets prop from filter to table presets 2026-06-09 17:02:02 +02:00
adisposkofh 0bb81b23e5 implemented table presets functionality 2026-06-09 16:07:55 +02:00
adisposkofh b3ae1b74ab implemented basic tabulator table presets ui 2026-06-03 16:53:55 +02:00
adisposkofh bf4b8348d2 defined cis profile tabulator columns collapse order 2026-06-03 09:18:40 +02:00
ma0068 22228478ad refactor addTaginTable and deleteTagInTable, add missing logic for automated tags in case of manual adding 2026-05-27 11:51:41 +02:00
Harald Bamberger ac6aa28680 Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-05-26 11:01:39 +02:00
ma0068 f6f58642f5 update second occurence of id STORAGE_KEY 2026-05-26 10:57:26 +02:00
Harald Bamberger 57eec98604 Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-05-26 09:38:06 +02:00
Harald Bamberger 1561aa55b7 correct model path 2026-05-26 09:37:49 +02:00
Harald Bamberger 35f4d23308 Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-05-26 09:28:40 +02:00
Harald Bamberger bb366e4117 font color black on tag limette 2026-05-26 09:06:44 +02:00
ma0068 0ed56ca067 add config for userAutomatedTags 2026-05-22 14:04:32 +02:00
Johann Hoffmann 870c36e76b Merge remote-tracking branch 'origin/master' into feature-75469/LeOptional4Projektarbeit
# Conflicts:
#	system/dbupdate_3.4.php
2026-05-20 16:22:31 +02:00
ma0068 b9c045382d add Hinweistext for Modal Hinweis Beratungsgespraech 2026-05-20 09:15:15 +02:00
Harald Bamberger c099eec7a7 Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-05-19 17:29:52 +02:00
Harald Bamberger 0962e62e69 Merge branch 'feature-76202/HorizontalSplit_from_master' into studvw_2026_05_rc 2026-05-19 17:28:08 +02:00
Harald Bamberger dcd6cfd74b increase width of horizontal split 2026-05-19 17:26:46 +02:00
Harald Bamberger 5caab182b2 Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-05-19 17:12:37 +02:00
Harald Bamberger baaf941f25 Merge branch 'feature-75958/StudVW_DatenExport_wie_im_Fas' into studvw_2026_05_rc 2026-05-19 17:12:11 +02:00
Harald Bamberger 2e5e7afb4d slot end tag 2026-05-19 17:11:51 +02:00
Harald Bamberger 2c4626fd1a Merge branch 'studvw_2026_05_rc' into studvw_2026_05_rc_tags 2026-05-19 16:52:14 +02:00
Harald Bamberger 178638c006 Merge branch 'feature-75958/StudVW_DatenExport_wie_im_Fas' into studvw_2026_05_rc 2026-05-19 16:51:57 +02:00
Harald Bamberger 981c97173e add padding to export icon link 2026-05-19 16:51:24 +02:00
Harald Bamberger 49d5c46133 Merge branch 'feature-75959/StudVw_Automatische_Tags' into studvw_2026_05_rc_tags 2026-05-19 16:42:25 +02:00
Harald Bamberger 9fb00f6cbd remove orphaned end tag, add right padding 2026-05-19 16:40:18 +02:00
Harald Bamberger 7d3096c2e8 readd required assignments for tags removed during merge 2026-05-19 10:28:08 +02:00
Harald Bamberger ef2f9630a9 Merge branch 'feature-75959/StudVw_Automatische_Tags' into studvw_2026_05_rc_tags 2026-05-19 10:22:28 +02:00
Harald Bamberger 4d3c73c78f add join condition for notizzuordung via prestudent_id only 2026-05-19 10:21:56 +02:00
Harald Bamberger 1e226f4515 Merge branch 'master' into studvw_2026_05_rc_tags 2026-05-18 17:27:36 +02:00
Harald Bamberger ca8fe5bd19 Merge branch 'feature-75959/StudVw_Automatische_Tags' into studvw_2026_05_rc_tags 2026-05-18 17:27:06 +02:00
ma0068 e2497e1958 add Infomodal Beratungsgespraech in case of Abmeldung and configEntry 2026-05-18 17:25:48 +02:00
ma0068 d4e170037b add order Nachname, Vorname 2026-05-18 10:11:17 +02:00
ma0068 0326a01585 disable sendButton, show Spinner and prevent closeModal while sending Message 2026-05-15 14:14:22 +02:00
ma0068 7aba7aefb9 add order mitarbeiter_uid 2026-05-15 11:05:12 +02:00
ma0068 e5ae400686 Tab Abschlusspruefung: use searchPersons instead of Mitarbeiter and refactor Label for dropdown 2026-05-13 17:38:39 +02:00
chfhtw c468d350f3 outsource config to better read it and make reuse easier 2026-05-13 14:16:14 +02:00
ma0068 1b822fc8f8 reset config stv to readonly for automated tags 2026-05-11 15:15:06 +02:00
ma0068 368eded1fd remove frontend filtering list for studiensemester, update logs TagJob 2026-05-11 15:12:53 +02:00
ma0068 dbcacdddd6 add tagFilter for semester to students endpoint, add decoding jsonResult in Tags 2026-05-11 13:18:56 +02:00
Harald Bamberger 8b2ef4e832 Merge branch 'master' into feature-75959/StudVw_Automatische_Tags 2026-05-11 10:54:26 +02:00
ma0068 6fedb4b108 delete unused code 2026-05-11 10:07:28 +02:00
chfhtw a7cc07fe15 Add basic library and config for studvw 2026-05-11 09:31:08 +02:00
chfhtw e91f8e5ca4 Replace component and endpoint for Verband 2026-05-11 09:27:54 +02:00
ma0068 905c69c384 create log entries for Summary, Details and Errors 2026-05-11 09:20:59 +02:00
chfhtw c765c3c40a allow object as argument for drop directive to enable dynamic specification of allowed dragtypes 2026-05-11 09:20:42 +02:00
ma0068 6fa0a7c102 use injected studiensemester instead of api call for studiensemester 2026-05-08 11:53:47 +02:00
ma0068 7320dc448e correct bezeichnung interval.ende 2026-05-08 10:57:19 +02:00
ma0068 ede9323224 refactor manual triggering for double degree lib 2026-05-08 08:33:53 +02:00
ma0068 3dcf72d679 add semester filter for tags
- in detailheader: use currentSem for manual triggering and refactor formatter
- in list: preload list of ids with start and end for tabulator formatter to enable filtering
2026-05-07 17:36:34 +02:00
Harald Bamberger 8ce67a4726 Merge branch 'master' into studvw_2026_05_rc 2026-05-06 17:35:05 +02:00
Harald Bamberger bcfdf1e05c Merge branch 'feature-75838/UXImproveProjektarbeitSTVSprint247' into studvw_2026_05_rc 2026-05-06 17:33:33 +02:00
Harald Bamberger cb744799bd Merge branch 'feature-71776/StudVW_Abschlusspruefung_DropdownsPrueferAndMultiActionNewPruefung' into studvw_2026_05_rc 2026-05-06 17:27:26 +02:00
Harald Bamberger 90ebee25fe Merge branch 'feature-71775/StudVW_ChangeSem_Behaviour' into studvw_2026_05_rc 2026-05-06 16:28:44 +02:00
Harald Bamberger 3e8ed231a6 Merge branch 'feature-71392/StudVW_Einstiegssemester_bei_Interessenten_anzeigen' into studvw_2026_05_rc 2026-05-06 16:03:37 +02:00
Harald Bamberger 4c67b9d267 Merge branch 'feature-76202/HorizontalSplit_from_master' into studvw_2026_05_rc 2026-05-06 15:56:14 +02:00
Johann HoffmannandHarald Bamberger c16cf342cb horizontalsplit component analog to verticalsplit; also built it into Studentenverwaltung.js menu; added defaultRatio prop to both components which defaults to 50/50 seperation 2026-05-06 15:54:49 +02:00
Harald Bamberger d843f05922 Merge branch 'feature-76201/StudVWTabsBeibehalten' into studvw_2026_05_rc 2026-05-06 15:42:29 +02:00
Harald Bamberger 44e9b4dff1 Merge branch 'feature-76145/StudVW_Studienverlauf_in_AppMenu' into studvw_2026_05_rc 2026-05-06 15:41:41 +02:00
Harald Bamberger bda42ab347 Merge branch 'feature-75958/StudVW_DatenExport_wie_im_Fas' into studvw_2026_05_rc 2026-05-06 15:06:51 +02:00
Harald Bamberger b5b69878b8 Merge branch 'feature-75901/StudVW_AppMenue_neueVerlinkungen' into studvw_2026_05_rc 2026-05-06 14:40:17 +02:00
Harald Bamberger 6f17ddbbdf Merge branch 'feature-63428/Infomail_Foto' into studvw_2026_05_rc 2026-05-06 14:35:45 +02:00
ma0068 ef1347c7d5 - use function getAktOrNextSemester
- restructure single libs to isolate typeId of data
- refactor Job: use params, details output
- use functions insert, update, delete
- use timeperiode for getAllTags and checkIfExistingTag
- controller: rebuild function: change to POST
- updated insertVon Batchuser
2026-05-05 15:20:02 +02:00
ma0068 d1fa5f64c4 refactor TagJob, TagLib and single TagLibs for dynamic use of typeId, add temporary testfile application/libraries/tags/CoreFiftyFiveTagLib.php for testing person_id 2026-04-30 11:17:39 +02:00
ma0068 21eb95bb23 manually triggering of updateTag 2026-04-28 16:24:30 +02:00
ma0048 b57836c2af fixed bug 2026-04-28 14:17:23 +02:00
ma0048 e80ee03365 fixed bug 2026-04-28 14:13:22 +02:00
ma0068 e856c8ad6b change settings bezeichnung_mehrsprachig::varchar[] in TagController functions getTag and getTags 2026-04-27 10:01:54 +02:00
ma0068 2723d6a741 get Semester of Model instead of Using CONST, delete unused models 2026-04-24 14:07:14 +02:00
ma0068 e5e22931a9 add db queries for update system, update tags in config 2026-04-24 12:49:00 +02:00
ma0068 21ea277aaf use checks for param studiengang_kurzbz instead of deleting it 2026-04-24 09:20:37 +02:00
ma0068 2c0badf67c bugfix error undefined offset: deletion of unused variable studiengang_kz 2026-04-23 17:28:43 +02:00
ma0068 5e72161ab0 add variables from and to to show time of validity in backend
refactor function getZuordnungIds of all single tagLibs
add description line for editing/showing modal tag
2026-04-23 16:39:21 +02:00
ma0068 903f3b99b3 add Studienverlauf to AppMenue 2026-04-20 11:36:54 +02:00
ma0068 df9edc36e0 save temporary 2026-04-20 08:40:55 +02:00
ma0068 39f1716ae2 set all automatic tags to readonly, add icon lock to automatic tags 2026-04-17 10:47:45 +02:00
Harald Bamberger c7b25e6632 add name to TagComponent, combine action slot definition for tagcomponent with definition for filter active 2026-04-16 16:21:33 +02:00
Harald Bamberger 695f3455e6 add function generateCSSsIncludeIfExtensionCssExists and use to load additional tag.css from extensions if exists 2026-04-16 15:20:11 +02:00
ma0068 1339077b57 use single tagLibs for dynamisation
new tagLibs (doubleDegree, jgv, missingZgv, Outgoing, StudienbeitragErhoeht, Unterbrecher)
refactor tagJob rebuildAutomatedTags
2026-04-15 09:45:57 +02:00
Johann Hoffmann 3aebccbb9d track activeTab in StudVW Details.js and pass it to :default property of fhcTabs instances to attempt to set the last active tab to current, else use the old default tab of route.params.tab 2026-04-10 13:01:13 +02:00
ma0068 ee6f28c06d Refactor TagJob and TabLib: use dynamic approach with column taglib for creating Tags 2026-04-09 13:58:42 +02:00
Harald Bamberger fdb037da96 poc move logic for single tags to libs, and add lib loading path and name to extra column in tbl_notiztyp 2026-04-09 08:36:13 +02:00
ma0068 49cbbfc50c update user 2026-04-08 15:24:06 +02:00
ma0068 4f8e98f5d5 restyle button reloadTags 2026-04-08 15:11:58 +02:00
ma0068 e9e614aa52 Add Functionality Frontend: triggering of reloading tags for prestudent from studentHeader
Refactoring: Recycling of tags instead of deleting it and creating new ones
2026-04-08 14:26:14 +02:00
Johann Hoffmann 4c0635be7c adapt lehrauftrag.xml.php queries to find projektbetreuer mitarbeiter_uid of projektarbeiten without le in future semesters for the lehrauftrag dokument (single lehrauftrag dokument curated for one betreuer) and also for the aggregated statistik listing the costs of all lehraufträge in a studiengang - resulting in the same data; 2026-04-02 16:45:03 +02:00
Johann Hoffmann 67b863f9db implemented the same studienplan lva_id check for stv projektarbeit anlage inside lva.rdf and lva.class; should result in the same data even though the quereies are written a second time; 2026-04-02 11:51:37 +02:00
Johann Hoffmann 7628ebc9ca remove unnecessary LE join in diplomasupplement.xml.php; fix studiensemester_kurzbz col datatype in dbupdate script; stv projektarbeit dropdown selection also by studienplan of current prestudent_status history entry 2026-04-01 16:05:51 +02:00
ma0068 50af6694d0 show Tags in CoreHeader 2026-03-31 12:48:27 +02:00
Johann Hoffmann deb6dad7ad WIP trying to get diplomasupplement.xml.php to print a thesis title; remove console log stv; removed le from getProjektarbeitStudiensemester in projektarbeit.class.php; 2026-03-30 18:45:01 +02:00
Johann Hoffmann 077f052112 stv projektarbeit getFormData call on actionEditProjektarbeit 2026-03-30 14:26:58 +02:00
Johann Hoffmann e7f57c9ddd remove last pa-le join from statistik/lvplanung.php 2026-03-30 13:52:50 +02:00
Johann Hoffmann 095e2bf581 revert lvgesamtnoteverwalten.php change 2026-03-27 11:29:04 +01:00
Johann Hoffmann 25345a0522 remove le join from vertrag.class.php; lehrauftrag_annehmen.xml.php fix 2nd query; 2026-03-27 11:24:38 +01:00
Johann Hoffmann e2b5201b5a remove le join from vertrag.class.php 2026-03-27 11:09:34 +01:00
Johann Hoffmann 5c80a382bf remove le join from lehrauftragsliste_gst.xls.php 2026-03-27 11:01:17 +01:00
Johann Hoffmann aa940683d6 remove le join from lvgesamtnoteverwalten.php 2026-03-27 10:49:13 +01:00
ma0068 5dbddb4beb remove char 2026-03-27 09:46:48 +01:00
ma0068 b20613f5d7 Basic Structure Automatic Tagging
- new library libTag
- new Job TagJob
- new entries for automatic tags in config stv.php
- automatic tagging of wiederholer and prewiederholer
2026-03-27 09:40:14 +01:00
Johann Hoffmann 843c65d52b Lehraufträge workflow wurde angepasst & getestet für zukünftige Projektarbeiten ohne hinterlegte LE. Subqueries "Projektbetreuungsaufträge and -vertragsstati" verwenden KEINE Lehreinheit table mehr, join funktioniert via pb -> pa -> lva & where clauses wurden entsprechend auf pa.lva & pa.sem_kurzbz angepasst für orderLehrauftragData.php, approveLehrauftragData.php & acceptLehrauftragData.php.
Weitere Anpassung in Vertrag_model: prüfung auf lehreinheit nur wenn vertragstyp nicht 'Betreuung' ist.

Added missing "setFormData" Method in stv Projektarbeit Details component
2026-03-25 11:56:19 +01:00
Johann Hoffmann e26f4262df LEFT join tbl_projektarbeit with tbl_lehreinheit to account for nullability 2026-03-24 16:08:20 +01:00
Johann Hoffmann dde586e004 Merge remote-tracking branch 'origin/master' into feature-75469/LeOptional4Projektarbeit 2026-03-23 15:37:57 +01:00
Johann Hoffmann 506c23ae89 fix joins in lehrauftragData files from 'pa JOIN lv JOIN le' to 'pa JOIN le JOIN lv'; fix join in projektarbeit.class.php "getProjektarbeitStudiensemester" to also correctly join on le table first but with lva_id & sem_kurzbz as join conditions; push all the relevant changes from "feature-75838/UXImproveProjektarbeitSTVSprint247" since we apparently still want them in the LE optional branch; fix FAS issue where lva dropdown loaded a limited list when existing projektarbeit was loaded into UI -> now query the lehrveranstaltung.rdf with the stg_kz selected and then set the value to achieve desired behaviour; 2026-03-23 15:29:16 +01:00
Harald Bamberger 0621564be7 Merge branch 'master' into feature-71775/StudVW_ChangeSem_Behaviour 2026-03-19 15:57:13 +01:00
ma0068 f1714db09e add ExcelExport of FAS to StudentList, add slot additional to Filtercomponent 2026-03-19 15:00:51 +01:00
Johann Hoffmann 335671b46a query fix 2026-03-17 17:03:18 +01:00
Johann Hoffmann 19b8c16057 specify lehrveranstaltung_id in 2 rdf queries 2026-03-17 16:15:47 +01:00
ma0068 70b025da30 add Link Reihungstestverwaltung to AppMenu 2026-03-17 14:59:05 +01:00
ma0068 87dd858358 add entry StudVw to navigation CI Menue 2026-03-17 14:58:39 +01:00
ma0068 51f3edcd72 delete not needed parameter orgform for html version lv planung 2026-03-17 12:57:55 +01:00
ma0068 e7f626bd72 add Lv-Planung to app menue 2026-03-17 12:49:40 +01:00
Johann Hoffmann dea3aac222 WIP stv projektarbeit detail modal ux rework 2026-03-16 17:20:31 +01:00
ma0068 17f94aabdf add loading skeletons for mitarbeiterHeader 2026-03-16 17:16:40 +01:00
Johann Hoffmann 5d7281e470 Merge branch 'master' into feature-75469/LeOptional4Projektarbeit
# Conflicts:
#	application/controllers/api/frontend/v1/Abgabe.php
#	public/js/components/Cis/Abgabetool/AbgabetoolAssistenz.js
#	public/js/components/Cis/Abgabetool/AbgabetoolMitarbeiter.js
#	public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Details.js
#	public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektbetreuer.js
#	system/phrasesupdate.php
2026-03-16 12:36:30 +01:00
ma0068 c49e32c4ac use skeletons for all data in studentHeader 2026-03-16 11:26:23 +01:00
Johann Hoffmann a7d925a177 even more legacy query projektarbeit join updates le_id -> lva_id & sem_kurzbz; WIP somehow touching the holy statistik queries 2026-03-13 12:58:55 +01:00
ma0068 df124db84a use primeVue Skeleton while loading Data for Semester, Verband and Gruppe 2026-03-13 12:40:29 +01:00
ma0068 29a4b4aadc use permission PERM_LOGGED for header, add condition one empty space for showing verband 2026-03-13 09:11:00 +01:00
Johann Hoffmann 4ef4a06a7e more legacy query projektarbeit join updates le_id -> lva_id & sem_kurzbz 2026-03-12 18:30:12 +01:00
ma0068 2682ea75ab use only one endpoint for detailheader 2026-03-12 16:58:48 +01:00
ma0068 b3a63a60e9 update phrase noTextInSem 2026-03-12 16:02:44 +01:00
Harald Bamberger a54dfaf0c7 Merge branch 'master' into feature-71775/StudVW_ChangeSem_Behaviour 2026-03-12 15:20:53 +01:00
Harald Bamberger 595538d6bb Merge branch 'master' into feature-71775/StudVW_ChangeSem_Behaviour 2026-03-12 15:10:06 +01:00
Harald Bamberger a5329e5bba Merge branch 'master' into feature-71775/StudVW_ChangeSem_Behaviour 2026-03-12 15:03:56 +01:00
Harald Bamberger 37a79c4589 Merge branch 'master' into feature-71775/StudVW_ChangeSem_Behaviour 2026-03-12 15:03:28 +01:00
Johann Hoffmann 29515491a2 WIP legacy queries refactor projektarbeit lehreinheit optional 2026-03-12 14:02:52 +01:00
Harald Bamberger dd760f8210 finetune behavior 2026-03-12 11:10:13 +01:00
ma0068 dd87e893ba working version for relaod header and data without updateUrl 2026-03-11 17:13:59 +01:00
Johann Hoffmann 6cb8d0a9d1 projektarbeit fas tab lva_id & sem_kurzbz required; le optional 2026-03-11 15:06:11 +01:00
Johann Hoffmann 2c4574d93b form input bugfix where 2 inputs where needed for select elements after invalid validation; Abgabetool Download Latest Action; WIP stv projektarbeit details/betreuer considerations; WIP adding le_id -> lva_id & sem_kurzbz to FAS code; 2026-03-10 16:45:15 +01:00
ma0068 127ce312ea reload Details and Detailheader without updateUrl 2026-03-10 08:28:11 +01:00
Johann Hoffmann 2fde630971 adjust abgabetool queries Studentenverwaltung Projektarbeit Tab: lehreinheit required -> lehreinheit optional, lehrveranstaltung & studiensemester_kurbz required; changed occurences of the typo "Studiensemster" rigorously; 2026-03-09 15:25:44 +01:00
ma0068 2237e9f1b7 refactor detail Header, relaod array if semester changed, show no status if no status, phrase 2026-03-09 11:42:24 +01:00
Johann Hoffmann fce5ee7a16 adjust abgabetool queries lehreinheit -> lehrveranstaltung table; always redraw with scrollX/Y preserve in abgabetool 2026-03-09 11:24:17 +01:00
Johann Hoffmann 8ccb9cd892 db migrate skript from le_id -> lva_id & stsem_kurzbz via existing references 2026-03-06 11:47:09 +01:00
ma0068 9b4fa132dc add status 2026-03-06 10:58:54 +01:00
Harald Bamberger daf332a102 add query_studiensemester_kurzbz to result of fetchStudents, fetchPrestudents and search 2026-03-06 10:39:37 +01:00
Johann Hoffmann d1af44bcdc dbupdate entry; WIP table altering statements for lehre.tbl_projektarbeit 2026-03-05 17:33:18 +01:00
ma0048 7f91e20d03 lvverwaltung: vilesci lehrveranstaltung verwaltung verlinkt 2026-03-04 15:15:12 +01:00
ma0048 233a6e8b89 lvverwaltung:
- event hinzugefuegt damit tabs erweitert werden können
- berichte hinzugefuegt
2026-02-25 15:25:36 +01:00
ma0068 c127c0900e refactor dropdown for pruefer, add localStorage for formVariables, add multiactions for adding new finalexam 2026-02-25 14:28:41 +01:00
ma0068 fc01fa045e add and use variable semester_berechnet for using ausbildungssemester in status interessent 2026-02-23 13:44:33 +01:00
ma0048 bb23679683 auskommentierten code entfernt 2026-02-12 10:45:32 +01:00
ma0048 e26387a75a lektoren tausch auch bei verplanten lektoren hinzugefuegt 2026-01-19 15:08:59 +01:00
ma0048 ab63bf9d74 gruppen in baum anzeigen und drag and drop von gruppen 2026-01-12 09:27:27 +01:00
ma0048 60f128b314 tabs gleichgezogen 2025-12-09 13:00:40 +01:00
ma0048 cc0a89c924 lvverwaltung noten hinzugefuegt
noten highlight wenn keine note im zeugnis eingetragen ist
2025-12-04 14:18:13 +01:00
ma0048 8f974e8902 sql angepasst 2025-12-03 08:37:38 +01:00
ma0048 a91fe05395 funktionen umbenannt 2025-12-02 13:23:09 +01:00
ma0048 d9cdeb9773 scroll verhalten angepasst 2025-12-02 08:42:04 +01:00
ma0048 0de033e428 termine tab hinzugefuegt 2025-12-01 10:55:04 +01:00
ma0048 1ab9635039 disitnct lv id 2025-11-26 13:56:37 +01:00
ma0048 e7fdbe13d0 nullable felder speichern 2025-11-20 15:32:27 +01:00
chfhtw 00477528cc Bugfix: LVs without Stg should not throw an PHP error 2025-11-19 10:19:34 +01:00
chfhtw 4c6d645cc6 Studienverlauf verlinken im neuen FAS 2025-11-18 15:02:55 +01:00
Harald Bamberger f57dc6785b Merge branch 'master' into feature-63428/Infomail_Foto 2025-09-30 13:47:04 +02:00
ma0068 cf59bcff12 add Functionality sendInfomail
- expand InputComponent for dynamic adding of actionButton to Form Upload Image
- add Phrases for Infomail
2025-08-19 09:16:26 +02:00
284 changed files with 17674 additions and 5983 deletions
+1
View File
@@ -1,5 +1,6 @@
documents/
vendor/
public/vendor
/nbproject/
.vscode
+12 -1
View File
@@ -8,4 +8,15 @@ $config['lvverwaltung_tags'] = [
];
*/
$config['lvverwaltung_tags'] = [];
$config['lvverwaltung_tags'] = [];
# Additional columns:
/*
$config["list_columns"] = [
'fieldname' => [
'js' => 'path/to/snippet.js', // tabulator config snippet (eg: return { name: 'Name', field: 'fieldname' }; )
// NOTE: 'default' & 'joins' like in stv.php config are currently not available here
]
];
*/
+8 -1
View File
@@ -170,6 +170,13 @@ $config['navigation_header'] = array(
'expand' => true,
'sort' => 51,
'requiredPermissions' => 'vertrag/mitarbeiter:r'
),
'studierendenverwaltung' => array(
'link' => site_url('studentenverwaltung'),
'description' => 'Studierendenverwaltung',
'expand' => true,
'sort' => 52,
'requiredPermissions' => ['admin:r', 'assistenz:r']
)
)
),
@@ -378,7 +385,7 @@ $config['navigation_menu']['apps'] = [
],
'lav' => [
'link' => site_url('lehre/lehrauftrag/Lehrauftrag/Dashboard'),
'description' => 'Lehraufträge',
'description' => 'Lehrauftragsverwaltung',
#'icon' => 'person-chalkboard',
'requiredPermissions' => array('lehre/lehrauftrag_bestellen:r', 'lehre/lehrauftrag_erteilen:r')
]
+52 -37
View File
@@ -75,52 +75,67 @@ $route['Abgabetool/Student'] = 'Cis/Abgabetool/Student';
$route['Abgabetool/Student/(:any)'] = 'Cis/Abgabetool/Student/$1';
$route['Abgabetool/Deadlines'] = 'Cis/Abgabetool/Deadlines';
// Studierendenverwaltung App Routes
$route['studvw'] = 'studentenverwaltung/index';
$route['studvw/.*'] = 'studentenverwaltung/index';
// Old routes
$route['studentenverwaltung'] = 'redirect/301/studvw';
$route['studentenverwaltung/(:any)'] = 'redirect/301/studvw/stdsem/$1';
$route['studentenverwaltung/(:any)/(prestudent|student|person|search)/(:any)'] = 'redirect/301/studvw/stdsem/$1/$2/$3';
$route['studentenverwaltung/(:any)/prestudent/(:any)/tab/:any'] = 'redirect/301/studvw/stdsem/$1/prestudent/$2';
$route['studentenverwaltung/(:any)/search/(:any)/(:any)'] = 'redirect/301/studvw/stdsem/$1/search/$2/$3';
$route['studentenverwaltung/(:any)/(:any)'] = 'redirect/301/studvw/stdsem/$1/stg/$2';
// Studierendenverwaltung List Routes
$route['api/frontend/v1/stv/[sS]tudents/inout'] = 'api/frontend/v1/stv/Students/index';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv/Students/index';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/inout/1/incoming/1'] = 'api/frontend/v1/stv/students/getIncoming/$1';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/inout/1/outgoing/1'] = 'api/frontend/v1/stv/students/getOutgoing/$1';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/inout/1/shared_studies/1'] = 'api/frontend/v1/stv/students/getGemeinsamestudien/$1';
// (studiensemester_kurzbz)/inout[/(incoming|outgoing|gemeinsamestudien)]
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout'] = 'api/frontend/v1/stv/Students/index';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/incoming'] = 'api/frontend/v1/stv/Students/getIncoming/$1';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/outgoing'] = 'api/frontend/v1/stv/Students/getOutgoing/$1';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/gemeinsamestudien'] = 'api/frontend/v1/stv/Students/getGemeinsamestudien/$1';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1/stdsem/(:any)/:any/1/:any/1/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudents/$1/$2/$3';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1/stdsem/(:any)/:any/1/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudents/$1/$2/$3';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1/stdsem/(:any)/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudents/$1/$2/$3';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1/stdsem/(:any)'] = 'api/frontend/v1/stv/students/getPrestudents/$1/$2';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/prestudent/1'] = 'api/frontend/v1/stv/students/getPrestudents/$1';
// (studiengang_kz)/prestudent[/(studiensemester_kurzbz)[/(filter)[/(otherfilter)]]]
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent'] = 'api/frontend/v1/stv/Students/getPrestudents/$1';
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv/Students/getPrestudents/$1/$2';
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent/([WS]S[0-9]{4})/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudents/$1/$2/$3';
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent/([WS]S[0-9]{4})/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudents/$1/$2/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/orgform/(:any)/prestudent/1/stdsem/(:any)/:any/1/:any/1/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudentsOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/orgform/(:any)/prestudent/1/stdsem/(:any)/:any/1/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudentsOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/orgform/(:any)/prestudent/1/stdsem/(:any)/(:any)/1'] = 'api/frontend/v1/stv/students/getPrestudentsOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/orgform/(:any)/prestudent/1/stdsem/(:any)'] = 'api/frontend/v1/stv/students/getPrestudentsOrgform/$1/$2/$3';
$route['api/frontend/v1/treemenudata/stv/stdsem/:any/stg/(:any)/orgform/(:any)/prestudent/1'] = 'api/frontend/v1/stv/students/getPrestudentsOrgform/$1/$2';
// (studiengang_kz)/(orgform)/prestudent[/(studiensemester_kurzbz)[/(filter)[/(otherfilter)]]]
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/([A-Z]{2,3})/prestudent'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2';
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/([A-Z]{2,3})/prestudent/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2/$3';
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/([A-Z]{2,3})/prestudent/([WS]S[0-9]{4})/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/([A-Z]{2,3})/prestudent/([WS]S[0-9]{4})/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getPrestudentsOrgform/$1/$2/$3/$5';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)/semester/(:any)/verband/(:any)/group/(:any)'] = 'api/frontend/v1/stv/students/getStudents/$1/$2/$3/$4/$5';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)/semester/(:any)/verband/(:any)'] = 'api/frontend/v1/stv/students/getStudents/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)/semester/(:any)'] = 'api/frontend/v1/stv/students/getStudents/$1/$2/$3';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)'] = 'api/frontend/v1/stv/students/getStudents/$1/$2';
// (studiensemester_kurzbz)/(studiengang_kz)/(semester)/grp/(gruppe)
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/(:num)/grp/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsSpezialgruppe/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)/orgform/(:any)/semester/(:any)/verband/(:any)/group/(:any)'] = 'api/frontend/v1/stv/students/getStudentsOrgform/$1/$2/$3/$4/$5/$6';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)/orgform/(:any)/semester/(:any)/verband/(:any)'] = 'api/frontend/v1/stv/students/getStudentsOrgform/$1/$2/$3/$4/$5';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)/orgform/(:any)/semester/(:any)'] = 'api/frontend/v1/stv/students/getStudentsOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)/orgform/(:any)'] = 'api/frontend/v1/stv/students/getStudentsOrgform/$1/$2/$3';
// (studiensemester_kurzbz)/(studiengang_kz)[/(semester)[/(verband)[/(gruppe)]]]
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/(:num)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2/$3';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/(:num)/(:any)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2/$3/$4';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/(:num)/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getStudents/$1/$2/$3/$4/$5';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)/semester/(:any)/group/(:any)'] = 'api/frontend/v1/stv/students/getStudentsSpezialgruppe/$1/$2/$3/$4';
// (studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester)/grp/(gruppe)
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})/(:num)/grp/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsOrgformSpezialgruppe/$1/$2/$3/$4/$5';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/stg/(:any)/orgform/(:any)/semester/(:any)/group/(:any)'] = 'api/frontend/v1/stv/students/getStudentsOrgformSpezialgruppe/$1/$3/$2/$4/$5';
// (studiensemester_kurzbz)/(studiengang_kz)/(orgform)[/(semester)[/(verband)[/(gruppe)]]]
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})/(:num)'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3/$4';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})/(:num)/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3/$4/$5';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/(-?[0-9]+)/([A-Z]{2,3})/(:num)/(:any)/(:any)'] = 'api/frontend/v1/stv/Students/getStudentsOrgform/$1/$2/$3/$4/$5/$6';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/prestudent/(:any)'] = 'api/frontend/v1/stv/students/getPrestudent/$1/$2';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/student/(:any)'] = 'api/frontend/v1/stv/students/getStudent/$1/$2';
$route['api/frontend/v1/treemenudata/stv/stdsem/(:any)/person/(:any)'] = 'api/frontend/v1/stv/students/getPerson/$1/$2';
$route['api/frontend/v1/treemenudata/stv/.*'] = 'api/frontend/v1/stv/students/index';
// Lvverwaltung List Routes
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/semester/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/semester/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/stg/(:any)/orgform/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByStg/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)/stg/(:any)'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2/$3';
$route['api/frontend/v1/treemenudata/lvverwaltung/stdsem/(:any)/emp/(:any)/stg/(:any)/.*'] = 'api/frontend/v1/Lehrveranstaltung/getByEmp/$1/$2/$3';
// // (studiensemester_kurzbz)/uid/(uid)
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/uid/(:any)'] = 'api/frontend/v1/stv/Students/getStudent/$1/$2';
// // (studiensemester_kurzbz)/prestudent/(prestudent_id)
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/prestudent/(:num)'] = 'api/frontend/v1/stv/Students/getPrestudent/$1/$2';
// // (studiensemester_kurzbz)/person/(person_id)
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/person/(:num)'] = 'api/frontend/v1/stv/Students/getPerson/$1/$2';
// load routes from extensions, also look for environment-specific configs
$subdirs = ['application/config/extensions', 'application/config/' . ENVIRONMENT . '/extensions'];
@@ -197,3 +197,11 @@ $config['unterbrechung_enabled'] = true;
*/
$config['wiederholung_enabled'] = true;
/**
* Modal with Infotext of TLC
* if true, there will be shown an info modal in the studentsView after the first button ABMELDUNG
*
* @var boolean
*/
$config['showInfoModalAbmeldung'] = true;
+47 -8
View File
@@ -1,6 +1,27 @@
<?php
$config['number_displayed_past_studiensemester_default'] = 5;
# Additional columns:
/*
$config["list_columns"] = [
'fieldname' => [
'js' => 'path/to/snippet.js', // tabulator config snippet (eg: return { name: 'Name', field: 'fieldname' }; )
'default' => "SQL SELECT statement for value",
'joins' => [
// additional joins needed for the SELECT statement above
[
'tablename',
'join condition', // single fieldname for USING or full condition for ON
'LEFT|RIGHT', // optional - join type
'after_xxx|before_xxx|end' // optional - position in query
]
// ...
]
]
];
*/
$config['tabs'] =
[
'details' => [
@@ -60,7 +81,13 @@ $config['tabs'] =
],
'notes' => [
//if true, the count of Messages will be shown in the header of the Tab Messages
'showCountNotes' => true
'showCountNotes' => true,
//if true: section with following fields will be displayed: 'verfasser', 'bearbeiter', 'von', 'bis' and 'erledigt'
'showErweitert' => false,
//notizlayout: choose of "classicFas", "twoColumnsFormLeft", twoColumnsFormRight, popupModal"
'notizLayout' => 'popupModal'
],
'combinePeople' => [
//multitab should only be shown with this length of selection
@@ -133,13 +160,25 @@ $config['students_tab_order'] = [
$config['stv_prestudent_tags'] = [
'prioone' => ['readonly' => false],
'priotwo' => ['readonly' => true],
'priotwo' => ['readonly' => false],
'hinweis' => ['readonly' => false],
'hinweis_assistenz' => ['readonly' => true],
'hinweis_kf' => ['readonly' => true],
'hinweis_assistenz' => ['readonly' => false],
'hinweis_kf' => ['readonly' => false],
'hinweis_lehrende' => ['readonly' => false],
'hinweis_stg_kf' => ['readonly' => true],
'finished_stg' => ['readonly' => true],
'finished_kf' => ['readonly' => true],
'inwork_kf' => ['readonly' => true],
'hinweis_stg_kf' => ['readonly' => false],
'finished_stg' => ['readonly' => false],
'finished_kf' => ['readonly' => false],
'inwork_kf' => ['readonly' => false],
'dd_auto' => ['readonly' => true],
'wh_auto' => ['readonly' => true],
'prewh_auto' => ['readonly' => true],
'out_auto' => ['readonly' => true],
'zgv_auto' => ['readonly' => true],
'unterbrecher_auto' => ['readonly' => true],
'stbtr_erh_auto' => ['readonly' => true],
'jgv_auto' => ['readonly' => true],
'in_auto' => ['readonly' => true],
'preabbr_auto' => ['readonly' => true],
];
$config['userAutomatedTags'] = 'sftest';
@@ -1,5 +1,7 @@
<?php
/**
* Copyright (C) 2025 fhcomplete.org
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,29 +17,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export default {
get(path) {
let url = 'api/frontend/v1/stv/verband';
if (path)
url += '/' + path;
return {
method: 'get',
url
};
},
favorites: {
get() {
return {
method: 'get',
url: 'api/frontend/v1/stv/favorites'
};
},
set(favorites) {
return {
method: 'post',
url: 'api/frontend/v1/stv/favorites/set',
params: { favorites }
};
}
}
};
if (!defined('BASEPATH')) exit('No direct script access allowed');
$config['stv'] = [
"library" => "treemenu/StudVwLib",
"permissions" => ["admin:r", "assistenz:r"]
];
$config['lvv'] = [
"library" => "treemenu/LvVwLib",
"permissions" => ["admin:r", "assistenz:r"]
];
@@ -0,0 +1,32 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
$config['root'] = [
'stg' => [
'semester' => [
'group',
'verband' => [
'group'
]
],
'orgform'
]
];
+65
View File
@@ -0,0 +1,65 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
$config['root'] = [
'stg' => [
'prestudent' => [
'stdsem' => [
'interessenten' => [
'bewerbungnichtabgeschickt',
'bewerbungabgeschickt',
'zgv',
'statusbestaetigt' => [
'statusbestaetigtrtnichtangemeldet',
'statusbestaetigtrtangemeldet'
],
'reihungstestnichtangemeldet',
'reihungstestangemeldet'
],
'bewerber' => [
'bewerberrtnichtangemeldet',
'bewerberrtangemeldet' => [
'bewerberrtangemeldetteilgenommen',
'bewerberrtangemeldetnichtteilgenommen'
]
],
'aufgenommen',
'warteliste',
'absage',
'incoming'
]
],
'semester' => [
'group',
'verband' => [
'group'
]
]
],
'inout' => [
'incoming',
'outgoing',
'shared_studies'
]
];
// copy stg tree into stg/orgforms
$config['root']['stg']['orgform'] = $config['root']['stg'];
+44
View File
@@ -0,0 +1,44 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller redirects urls to another location. This is mainly used
* with the $routes config
*/
class Redirect extends CI_Controller
{
public function __construct()
{
parent::__construct();
}
/**
* Main function to handle all redirects.
*
* @param string $method - the redirect code (30x)
* @param array $params - the url to redirect to
*
* @return void
*/
public function _remap($method, $params)
{
redirect($params, 'location', $method);
}
}
@@ -22,6 +22,10 @@ use CI3_Events as Events;
class Abgabe extends FHCAPI_Controller
{
// col limits of lehre.tbl_projektarbeit, exceeding them aborts the zusatzdaten update and lead to unpublishable enduploads
const MAX_LEN_SCHLAGWOERTER = 150; // varchar(150)
const MAX_LEN_ABSTRACT = 5000; // text, capped to match the ui counter
const MAX_SEITENANZAHL = 32767; // smallint
/**
* Object initialization
@@ -323,6 +327,13 @@ class Abgabe extends FHCAPI_Controller
$this->checkProjektarbeitForFinishedStatus($projektarbeit_id);
// block uploads for quality gate termine that are already graded
$this->checkPaabgabeForGradedStatus($paabgabe_id);
// the posted typ is client state only - verify it against the row so a stale ui cannot push an
// endabgabe through here, which would mark the abgabe without ever writing the zusatzdaten
$this->checkPaabgabeTypForZwischenabgabe($paabgabe_id, $paabgabetyp_kurzbz);
// load the $student_uid by $projektarbeit_id so we dont need any post params
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$res = $this->ProjektarbeitModel->getStudentInfoForProjektarbeitId($projektarbeit_id);
@@ -335,11 +346,11 @@ class Abgabe extends FHCAPI_Controller
$data = getData($res)[0];
$student_uid = $data->uid;
$studiengang_kz = $data->studiengang_kz;
if(!$this->checkZuordnung($projektarbeit_id, getAuthUID(), $student_uid, $studiengang_kz)) {
$this->terminateWithError($this->p->t('abgabetool', 'c4noZuordnungBetreuerStudent', [getAuthUID(), $student_uid]));
}
$path = PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf';
if ((isset($_FILES) and isset($_FILES['file']) and ! $_FILES['file']['error'])) {
@@ -400,8 +411,10 @@ class Abgabe extends FHCAPI_Controller
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
}
$this->checkZusatzdatenLengths($schlagwoerter, $schlagwoerter_en, $abstract, $abstract_en, $seitenanzahl);
$this->checkPaabgabeDeadline($paabgabe_id);
$this->checkProjektarbeitForFinishedStatus($projektarbeit_id);
// load the $student_uid by $projektarbeit_id so we dont need any post params
@@ -450,17 +463,25 @@ class Abgabe extends FHCAPI_Controller
$this->checkAbgabeSignatur($paabgabe, $projektarbeit->student_uid);
$signaturstatus = $paabgabe->signatur;
// update projektarbeit cols with zusatzdaten AND abgabedatum!
$this->ProjektarbeitModel->update($projektarbeit->projektarbeit_id, array(
'sprache' => $sprache,
'seitenanzahl' => $seitenanzahl,
'abgabedatum' => date('Y-m-d'),
'schlagwoerter_en' => $schlagwoerter_en,
'schlagwoerter' => $schlagwoerter,
'abstract' => $abstract,
'abstract_en' => $abstract_en
));
// update projektarbeit cols with zusatzdaten AND abgabedatum!
$updateRes = $this->ProjektarbeitModel->update($projektarbeit->projektarbeit_id, array(
'sprache' => $sprache,
'seitenanzahl' => $seitenanzahl,
'abgabedatum' => date('Y-m-d'),
'schlagwoerter_en' => $schlagwoerter_en,
'schlagwoerter' => $schlagwoerter,
'abstract' => $abstract,
'abstract_en' => $abstract_en
));
// abort before marking the abgabe - a failed update used to leave the projektarbeit without
// abgabedatum and zusatzdaten while the endupload counted as done, blocking the publication
if(isError($updateRes)) {
$this->logLib->logInfoDB(array('endupload projektarbeit update failed', getError($updateRes),
$projektarbeit_id, $paabgabe_id, getAuthUID(), getAuthPersonId()));
$this->terminateWithError($this->p->t('abgabetool', 'c4enduploadZusatzdatenSpeichernFehlgeschlagen'), 'general');
}
// update paabgabe datum
$res = $this->PaabgabeModel->update($paabgabe_id, array(
@@ -947,6 +968,16 @@ class Abgabe extends FHCAPI_Controller
$paabgabeArr = $this->getDataOrTerminateWithError($result, 'general');
$paabgabe = $paabgabeArr[0];
// resolve the insert/update user full names so the frontend info string ("saved at X by Y")
// renders immediately for freshly created/updated termine without needing a reload.
$this->load->model('person/Person_model', 'PersonModel');
if(!empty($paabgabe->insertvon)) {
$paabgabe->insertvon_fullname = getData($this->PersonModel->getFullName($paabgabe->insertvon));
}
if(!empty($paabgabe->updatevon)) {
$paabgabe->updatevon_fullname = getData($this->PersonModel->getFullName($paabgabe->updatevon));
}
// check if abgabe even has note
if($paabgabe->note) {
$this->load->model('education/Note_model', 'NoteModel');
@@ -1057,6 +1088,22 @@ class Abgabe extends FHCAPI_Controller
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
}
// a termin with an upload or a note must keep its typ and datum.
// the table only hides those rows client side, so a student upload
// after the table was loaded would otherwise still let a zwischenabgabe be retyped to 'end'
$existingPaabgabe = $paabgabeArr[0];
if($existingPaabgabe->note !== null || $existingPaabgabe->abgabedatum !== null) {
if(isset($updateFields['paabgabetyp_kurzbz'])
&& $updateFields['paabgabetyp_kurzbz'] !== $existingPaabgabe->paabgabetyp_kurzbz) {
$this->terminateWithError($this->p->t('abgabetool', 'c4abgabetypAendernNichtErlaubt'));
}
if(isset($updateFields['datum']) && $updateFields['datum'] !== $existingPaabgabe->datum) {
$this->terminateWithError($this->p->t('abgabetool', 'c4datumAendernNichtErlaubt'));
}
}
$result = $this->PaabgabeModel->update(
$paabgabe_id,
array_merge($updateFields, [
@@ -1570,7 +1617,9 @@ class Abgabe extends FHCAPI_Controller
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
}
$this->checkZusatzdatenLengths($schlagwoerter, $schlagwoerter_en, $abstract, $abstract_en, $seitenanzahl);
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
@@ -1605,7 +1654,7 @@ class Abgabe extends FHCAPI_Controller
}
// update projektarbeit cols with zusatzdaten only
$this->ProjektarbeitModel->update($projektarbeit_id, array(
$updateRes = $this->ProjektarbeitModel->update($projektarbeit_id, array(
'sprache' => $sprache,
'seitenanzahl' => $seitenanzahl,
'schlagwoerter_en' => $schlagwoerter_en,
@@ -1614,6 +1663,9 @@ class Abgabe extends FHCAPI_Controller
'abstract_en' => $abstract_en
));
// dont report success on a failed update, otherwise a repair attempt silently changes nothing
$this->getDataOrTerminateWithError($updateRes, 'general');
$this->logLib->logInfoDB(array('zusatzdatenEditMitarbeiter', array(
'updatevon' => getAuthUID(),
'updateamum' => date('Y-m-d H:i:s')
@@ -1996,13 +2048,59 @@ class Abgabe extends FHCAPI_Controller
$data = getData($res)[0];
if($data->note !== NULL) {
// hardcode this error msg cause phrasen arent reliable and people keep bugging why the cant edit old entries they definitely shouldnt update
$message = $this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeitv3');
if(strpos($message, "<<") === 0) { // phrase could not be loaded
$this->terminateWithError('Die Projektarbeit wurde bereits benotet, Sie dürfen deshalb keine weiteren Termine anlegen oder bearbeiten.', 'general');
} else {
$this->terminateWithError($message);
}
$this->terminateWithError($this->p->t('abgabetool','c4fehlerAktualitaetProjektarbeitv3'));
}
}
// validates the zusatzdaten against the column limits of lehre.tbl_projektarbeit.
private function checkZusatzdatenLengths($schlagwoerter, $schlagwoerter_en, $abstract, $abstract_en, $seitenanzahl) {
if(mb_strlen((string)$schlagwoerter) > self::MAX_LEN_SCHLAGWOERTER
|| mb_strlen((string)$schlagwoerter_en) > self::MAX_LEN_SCHLAGWOERTER) {
$this->terminateWithError($this->p->t('abgabetool', 'c4schlagwoerterZuLang', array(self::MAX_LEN_SCHLAGWOERTER)), 'general');
}
if(mb_strlen((string)$abstract) > self::MAX_LEN_ABSTRACT
|| mb_strlen((string)$abstract_en) > self::MAX_LEN_ABSTRACT) {
$this->terminateWithError($this->p->t('abgabetool', 'c4abstractZuLang', array(self::MAX_LEN_ABSTRACT)), 'general');
}
if(!is_numeric($seitenanzahl) || (int)$seitenanzahl < 1 || (int)$seitenanzahl > self::MAX_SEITENANZAHL) {
$this->terminateWithError($this->p->t('abgabetool', 'c4seitenanzahlUngueltig', array(self::MAX_SEITENANZAHL)), 'general');
}
}
// zwischenabgabe uploads must never touch an endabgabe termin, to avoid empty zusatzdaten
private function checkPaabgabeTypForZwischenabgabe($paabgabe_id, $posted_paabgabetyp_kurzbz) {
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$res = $this->PaabgabeModel->load($paabgabe_id);
if(isError($res) || !hasData($res)) {
$this->terminateWithError($this->p->t('abgabetool', 'c4projektabgabeNichtGefunden'), 'general');
}
$paabgabe = getData($res)[0];
if($paabgabe->paabgabetyp_kurzbz === 'end') {
$this->terminateWithError($this->p->t('abgabetool', 'c4enduploadUeberZwischenabgabeNichtErlaubt'), 'general');
}
// typ changed between page load and upload -> the client would use the wrong upload path
if($paabgabe->paabgabetyp_kurzbz !== $posted_paabgabetyp_kurzbz) {
$this->terminateWithError($this->p->t('abgabetool', 'c4abgabeterminGeaendertNeuLaden'), 'general');
}
}
private function checkPaabgabeForGradedStatus($paabgabe_id) {
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$res = $this->PaabgabeModel->load($paabgabe_id);
if(isError($res) || !hasData($res)) {
$this->terminateWithError($this->p->t('abgabetool', 'c4projektabgabeNichtGefunden'), 'general');
}
$paabgabe = getData($res)[0];
if($paabgabe->note !== NULL) {
$this->terminateWithError($this->p->t('abgabetool', 'c4studentAbgabeNotAllowedRegularv3'));
}
}
@@ -91,6 +91,8 @@ class CisMenu extends FHCAPI_Controller
$doc->loadXML($menuItem->content);
$urlElem = $doc->getElementsByTagName('url')->item(0);
$this->menuItemUrlTargetHelper($menuItem, $doc);
if (!$urlElem) {
return '';
}
@@ -122,5 +124,18 @@ class CisMenu extends FHCAPI_Controller
return $url;
}
private function menuItemUrlTargetHelper($menuItem, $xmldoc)
{
if($menuItem->template_kurzbz === 'redirect')
{
$targetElem = $xmldoc->getElementsByTagName('target')->item(0);
$target = ($targetElem) ? $targetElem->textContent : '';
if(!in_array($target, array('_self', '_top', '_blank')))
{
$target = '_self';
}
$menuItem->target = $target;
}
}
}
@@ -20,8 +20,8 @@ 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 favorite verbände
* Listens to ajax post calls to change the favorite verbände data
* Provides data to the ajax get calls about favorite treemenu entries
* Listens to ajax post calls to change the favorite treemenu entries
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Favorites extends FHCAPI_Controller
@@ -29,7 +29,7 @@ class Favorites extends FHCAPI_Controller
public function __construct()
{
parent::__construct([
'index' => self::PERM_LOGGED,
'get' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED
]);
@@ -37,19 +37,19 @@ class Favorites extends FHCAPI_Controller
$this->load->model('system/Variable_model', 'VariableModel');
}
public function index()
public function get($app)
{
$result = $this->VariableModel->getVariables(getAuthUID(), ['stv_favorites']);
$result = $this->VariableModel->getVariables(getAuthUID(), [$app . '_favorites']);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
$this->terminateWithSuccess(null);
else
$this->terminateWithSuccess($data['stv_favorites'] ?? null);
$this->terminateWithSuccess($data[$app . '_favorites'] ?? null);
}
public function set()
public function set($app)
{
$this->load->library('form_validation');
@@ -60,7 +60,7 @@ class Favorites extends FHCAPI_Controller
$favorites = $this->input->post('favorites');
$result = $this->VariableModel->setVariable(getAuthUID(), 'stv_favorites', $favorites);
$result = $this->VariableModel->setVariable(getAuthUID(), $app . '_favorites', $favorites);
$this->getDataOrTerminateWithError($result);
@@ -56,7 +56,9 @@ class Lehrveranstaltung extends FHCAPI_Controller
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$lehrveranstaltungen = $this->_ci->LehreinheitModel->getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz);
$studiengang_kz = $this->getStudiengangKz($stg_kz);
$lehrveranstaltungen = $this->_ci->LehreinheitModel->getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $studiengang_kz);
$lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen);
$tree = [];
@@ -75,15 +77,17 @@ class Lehrveranstaltung extends FHCAPI_Controller
$this->terminateWithSuccess($tree);
}
public function getByStg($studiensemester_kurzbz = null, $studiengang_kz = null, $semester = null)
public function getByStg($studiensemester_kurzbz = null, $stg_kz = null, $semester = null)
{
if (is_null($studiengang_kz) || !preg_match("/^-?[1-9][0-9]*$/", (string)$studiengang_kz))
$studiengang_kz = $this->getStudiengangKz($stg_kz);
if (is_null($studiengang_kz) || !preg_match("/^(-?[1-9][0-9]*|0)$/", (string)$studiengang_kz))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$verband = null;
if (!is_null($semester) && !is_numeric($semester))
{
$verband = $semester;
$verband = $this->getOrgformKurzbz($semester);
$semester = null;
}
@@ -260,18 +264,53 @@ class Lehrveranstaltung extends FHCAPI_Controller
}
}
protected function getStudiengangKz($studiengang_typ_kurzbz)
{
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$result = $this->StudiengangModel->loadWhere([
'LOWER(CONCAT(typ, kurzbz)) =' => strtolower($studiengang_typ_kurzbz)
]);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
return null;
return current($data)->studiengang_kz;
}
private function getStudiensemesterKurzbz($studiensemester_kurzbz = null)
{
if (!is_null($studiensemester_kurzbz))
{
$studiensemester_result = $this->_ci->StudiensemesterModel->load($studiensemester_kurzbz);
$studiensemester_result = $this->_ci->StudiensemesterModel->loadWhere([
'LOWER(studiensemester_kurzbz)' => strtolower($studiensemester_kurzbz)
]);
if (isError($studiensemester_result) || !hasData($studiensemester_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$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);
}
protected function getOrgformKurzbz($orgform_kurzbz)
{
if ($orgform_kurzbz === null)
return null;
$this->load->model('codex/Orgform_model', 'OrgformModel');
$result = $this->OrgformModel->loadWhere([
'LOWER(orgform_kurzbz) =' => strtolower($orgform_kurzbz)
]);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
return $orgform_kurzbz;
return current($data)->orgform_kurzbz;
}
}
@@ -49,6 +49,8 @@ class LvPlan extends FHCAPI_Controller
'getLehrverband' => self::PERM_LOGGED,
'permissionOtherLvPlan' => self::PERM_LOGGED,
'compactibleEventTypes' => self::PERM_LOGGED,
'getLeEvents' => self::PERM_LOGGED,
'getLvEvents' => self::PERM_LOGGED,
]);
$this->load->library('LogLib');
@@ -60,7 +62,13 @@ class LvPlan extends FHCAPI_Controller
'dbExecuteUser' => 'RESTful API'
));
$this->load->library('form_validation');
$this->load->library('form_validation');
$this->load->library('PhrasesLib');
$this->loadPhrases(
array(
'ui'
)
);
}
//------------------------------------------------------------------------------------------------------------------
@@ -106,6 +114,7 @@ class LvPlan extends FHCAPI_Controller
// fetching lvplan events
$result = $this->stundenplanlib->getEventsUser($start_date, $end_date, $uid);
$lvplanEvents = $this->getDataOrTerminateWithError($result);
// fetching moodle events
@@ -196,6 +205,38 @@ class LvPlan extends FHCAPI_Controller
));
}
public function getLeEvents($le_id = null, $start_date = null, $end_date = null, $stundenplan = 'stundenplandev')
{
if (is_null($le_id) || is_null($start_date) || is_null($end_date))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
if ($stundenplan !== 'stundenplandev' && $stundenplan !== 'stundenplan')
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->library('StundenplanLib');
$result = $this->stundenplanlib->getEventsByLE($le_id, $start_date, $end_date, $stundenplan);
$lvplanEvents = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($lvplanEvents);
}
public function getLvEvents($lv_id = null, $start_date = null, $end_date = null, $stundenplan = 'stundenplandev')
{
if (is_null($lv_id) || is_null($start_date) || is_null($end_date))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
if ($stundenplan !== 'stundenplandev' && $stundenplan !== 'stundenplan')
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->library('StundenplanLib');
$result = $this->stundenplanlib->getEventsByLV($lv_id, $start_date, $end_date, $stundenplan);
$this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
//TODO: delete this function if we don't use the old calendar export endpoints anymore
public function studiensemesterDateInterval($date)
{
@@ -17,60 +17,61 @@
*/
if (!defined('BASEPATH'))
exit('No direct script access allowed');
exit('No direct script access allowed');
class OtherLvPlan extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'otherLvPlanViewData' => ['basis/other_lv_plan:r'],
]);
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'otherLvPlanViewData' => ['basis/other_lv_plan:r'],
]);
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->library('ProfilLib');
}
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* retrieves viewData for other lv plan view
* @access public
* @param $uid the userID for which the other lv plan is being viewed
*/
public function otherLvPlanViewData($uid)
{
$isMitarbeiterResult = $this->MitarbeiterModel->isMitarbeiter($uid);
$isMitarbeiter = getData($isMitarbeiterResult);
$isStudent = !$isMitarbeiter;
/**
* retrieves viewData for other lv plan view
* @access public
* @param $uid the userID for which the other lv plan is being viewed
*/
public function otherLvPlanViewData($uid)
{
$isMitarbeiterResult = $this->MitarbeiterModel->isMitarbeiter($uid);
$isMitarbeiter = getData($isMitarbeiterResult);
$isStudent = !$isMitarbeiter;
$this->BenutzerModel->addSelect(["foto", "vorname", "nachname"]);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$personResult = $this->BenutzerModel->load([$uid]);
$person = hasData($personResult) ? getData($personResult) : null;
$resProfileData = $this->profillib->getView($uid);
$profileData = hasData($resProfileData) ? getData($resProfileData) : null;
$viewData = [
"user_data" => [
"username" => $uid,
"is_student" => $isStudent,
"is_mitarbeiter" => $isMitarbeiter,
"foto" => $person[0]->foto,
"vorname" => $person[0]->vorname,
"nachname" => $person[0]->nachname,
],
];
$viewData = [
"user_data" => [
"username" => $uid,
"is_student" => $isStudent,
"is_mitarbeiter" => $isMitarbeiter,
"foto" => $profileData->data->foto,
"vorname" => $profileData->data->vorname,
"nachname" => $profileData->data->nachname,
"titel" => $profileData->data->titel,
"postnomen" => $profileData->data->postnomen,
],
];
$this->terminateWithSuccess($viewData);
}
$this->terminateWithSuccess($viewData);
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
// -----------------------------------------------------------------------------------------------------------------
// Private methods
}
@@ -167,7 +167,9 @@ class Studium extends FHCAPI_Controller
if($aktuelles_studienplan){
$lehrveranstaltungen = $this->computeStudienplanLehrveranstaltungen($aktuelles_studienplan->studienplan_id, $aktuelles_semester);
foreach($lehrveranstaltungen as $lehrv){
foreach($lehrv->lehrveranstaltungen as $lv){
// a lehrveranstaltung without a modul has no children and gets its lektoren directly
$lvs = isset($lehrv->lehrveranstaltungen) ? $lehrv->lehrveranstaltungen : [$lehrv];
foreach($lvs as $lv){
$lvLektoren =$this->computeLektorenFromLehrveranstaltung($lv->lehrveranstaltung_id,$aktuelles_semester, $aktuelles_studiengang->studiengang_kz, $aktuelles_studiensemester->studiensemester_kurzbz);
$lv->lektoren = $lvLektoren;
}
@@ -286,6 +288,7 @@ SELECT tbl_lehrveranstaltung.*,
$lehrveranstaltungen = $this->LehrveranstaltungModel->execReadOnlyQuery($query,[$studienplan_id, $semester]);
$lehrveranstaltungen = $this->getDataOrTerminateWithError($lehrveranstaltungen);
usort($lehrveranstaltungen, function($a, $b){
if($a->lehrtyp_kurzbz == "modul"){
return -1;
@@ -302,12 +305,17 @@ SELECT tbl_lehrveranstaltung.*,
}
else{
$parent =array_filter($carry, function($item)use($lehrv){
return $item->studienplan_lehrveranstaltung_id == $lehrv->studienplan_lehrveranstaltung_id_parent;
return isset($item->lehrveranstaltungen)
&& $item->studienplan_lehrveranstaltung_id == $lehrv->studienplan_lehrveranstaltung_id_parent;
});
$parent = current($parent);
if($parent){
$parent->lehrveranstaltungen[] = $lehrv;
}
else{
// lehrveranstaltung without a modul: keep it on the top level
array_push($carry, $lehrv);
}
}
return $carry;
}, []);
@@ -0,0 +1,162 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the PhrasesLib (back-end)
* Provides data to the ajax get calls about the Phrasen plugin
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class TabulatorPresets extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getTabulatorPresets' => self::PERM_LOGGED,
'createTabulatorPreset' => self::PERM_LOGGED,
'updateTabulatorPreset' => self::PERM_LOGGED,
'deleteTabulatorPreset' => self::PERM_LOGGED,
]);
$this->load->model('tabulator/Tabulator_preset_model', 'TabulatorPresetModel');
$this->loadPhrases([
'global',
'tabulator_presets'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getTabulatorPresets()
{
$tableName = $this->input->get("tableName");
if (!$tableName) {
$this->terminateWithError(error($this->p->t("tabulator_presets", "invalid_params_err_msg")));
}
$uid = getAuthUID();
$presets = $this->TabulatorPresetModel->getTabulatorPresetsByUserAndTable($uid, $tableName);
$presetsData = $this->getDataOrTerminateWithError($presets) ?? [];
$this->terminateWithSuccess($presetsData);
}
public function createTabulatorPreset()
{
$tableName = $this->input->post("tableName");
$presetName = $this->input->post("presetName");
$preset = $this->input->post("preset");
if (!$tableName || !$presetName || !$preset) {
$this->terminateWithError($this->p->t("tabulator_presets", "invalid_params_err_msg"), "general", 400);
}
$uid = getAuthUID();
$existingPresetsResult = $this->TabulatorPresetModel->getTabulatorPresetsByUserAndTable($uid, $tableName);
$existingPresets = $this->getDataOrTerminateWithError($existingPresetsResult) ?? [];
if (count($existingPresets) > 19) {
$this->terminateWithError($this->p->t("tabulator_presets", "max_presets_count_err_msg"), "general", 409);
}
$existingPresetNames = array_map(function($presetInfo) {
return $presetInfo->preset_name;
}, $existingPresets);
if (in_array($presetName, $existingPresetNames)) {
$this->terminateWithError($this->p->t("tabulator_presets", "preset_name_duplicate_err_msg"), "general", 409);
}
$presetCreationResult = $this->TabulatorPresetModel->createTabulatorPreset($uid, $tableName, $presetName, $preset);
if (isError($presetCreationResult)) {
$this->terminateWithError($presetCreationResult->retval);
}
$newPresetData = $this->TabulatorPresetModel->getTabulatorPreset($presetCreationResult->retval);
$newPresetArray = $this->getDataOrTerminateWithError($newPresetData) ?? [null];
$newPreset = $newPresetArray[0];
$this->terminateWithSuccess($newPreset);
}
public function updateTabulatorPreset()
{
$presetId = $this->input->post("presetId");
$preset = $this->input->post("preset");
if (!$presetId || !$preset) {
$this->terminateWithError($this->p->t("tabulator_presets", "invalid_params_err_msg"), "general", 400);
}
$existingPresetData = $this->TabulatorPresetModel->getTabulatorPreset($presetId);
$existingPresetArray = $this->getDataOrTerminateWithError($existingPresetData) ?? [null];
$existingPreset = $existingPresetArray[0];
if (!$existingPreset) {
$this->terminateWithError($this->p->t("tabulator_presets", "preset_not_found_err_msg"), "general", 404);
}
$uid = getAuthUID();
if ($existingPreset->benutzer_uid !== $uid) {
$this->terminateWithError($this->p->t("tabulator_presets", "preset_not_own_update_err_msg"), "general", 403);
}
$presetUpdateResult = $this->TabulatorPresetModel->updateTabulatorPreset($presetId, $preset);
if (isError($presetUpdateResult)) {
$this->terminateWithError($presetUpdateResult->retval);
}
$updatedPresetData = $this->TabulatorPresetModel->getTabulatorPreset($presetId);
$updatedPresetArray = $this->getDataOrTerminateWithError($updatedPresetData) ?? [null];
$updatedPreset = $updatedPresetArray[0];
$this->terminateWithSuccess($updatedPreset);
}
public function deleteTabulatorPreset()
{
$presetId = $this->input->post("presetId");
if (!$presetId) {
$this->terminateWithError($this->p->t("tabulator_presets", "invalid_params_err_msg"), "general", 400);
}
$presetData = $this->TabulatorPresetModel->getTabulatorPreset($presetId);
$presetArray = $this->getDataOrTerminateWithError($presetData) ?? [null];
$preset = $presetArray[0];
if (!$preset) {
$this->terminateWithError($this->p->t("tabulator_presets", "preset_not_found_err_msg"), "general", 404);
}
$uid = getAuthUID();
if ($preset->benutzer_uid !== $uid) {
$this->terminateWithError($this->p->t("tabulator_presets", "preset_not_own_delete_err_msg"), "general", 403);
}
$presetDeletionResult = $this->TabulatorPresetModel->deleteTabulatorPreset($presetId);
if (isError($presetDeletionResult)) {
$this->terminateWithError($presetDeletionResult->retval);
}
$this->terminateWithSuccess();
}
}
@@ -0,0 +1,148 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \ReflectionMethod as ReflectionMethod;
use \ReflectionFunction as ReflectionFunction;
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about menues
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Treemenu extends FHCAPI_Controller
{
public function __construct()
{
// Load Router
$router = load_class('Router');
// Load Config
$config = load_class('Config');
$config->load('treemenu');
// Get Treemenu name & config
$name = $router->method;
$conf = $config->item($name);
// Get Permissions from config
$permissions = $conf['permissions'] ?? self::PERM_ANONYMOUS;
// Call constructor
parent::__construct([
$name => $permissions
]);
// Load Library
$libraryName = $conf['library'] ?? null;
$this->load->library($libraryName, null, 'treemenulib');
}
/**
* @param string $method
* @param array $params (optional)
*
* @return void
*/
public function _remap($method, $params = [])
{
if (!$this->treemenulib)
show_404();
$this->addMeta('ci_method', $method);
$this->addMeta('ci_params', $params);
$params = $this->uri->uri_to_assoc(6); // 6 = start of $params
$config = $this->treemenulib->config;
foreach (array_keys($params) as $key) {
if (!isset($config[$key]) || !$config[$key])
show_404();
$config = $config[$key];
}
// Prepare aliases
$argumentaliases = [];
if (property_exists($this->treemenulib, 'path_to_argument'))
$argumentaliases = array_flip($this->treemenulib->path_to_argument);
$methodaliases = [];
if (property_exists($this->treemenulib, 'redirect_method'))
$methodaliases = $this->treemenulib->redirect_method;
$items = [];
foreach ($config as $uripart => $children) {
if (!is_array($children)) {
$uripart = $children;
$children = [];
}
$methodName = $uripart;
if (isset($methodaliases[$methodName])) {
$methodName = $methodaliases[$methodName];
} elseif (strpbrk($methodName, ' _-') !== false) {
$methodName = lcfirst(str_replace([' ', '_', '-'], '', ucwords($methodName, " \t\r\n\f\v_-")));
}
// Prepare arguments
if (is_callable($methodName, false, $name)) {
if (is_string($methodName) && is_callable([$this->treemenulib, $methodName]))
$callable = [$this->treemenulib, $methodName];
else
$callable = $methodName;
} else {
$callable = [$this->treemenulib, $methodName];
}
if (is_array($callable))
$reflection = new ReflectionMethod($callable[0], $callable[1]);
elseif (is_string($callable) && strstr($callable, '::'))
$reflection = new ReflectionMethod($callable);
elseif ($name != 'Closure::__invoke' && strstr($name, '::__invoke'))
$reflection = new ReflectionMethod($callable, '__invoke');
else
$reflection = new ReflectionFunction($callable);
$arguments = [];
foreach ($reflection->getParameters() as $arg) {
if ($arg->name == 'path_template') {
$path = $params;
$path[$uripart] = '%s';
$arguments[] = $this->uri->assoc_to_uri($path);
} elseif ($arg->name == 'has_children') {
$arguments[] = $children;
} elseif ($arg->name == 'original_method') {
$arguments[] = $uripart;
} elseif (isset($argumentaliases[$arg->name]) && isset($params[$argumentaliases[$arg->name]])) {
$arguments[] = $params[$argumentaliases[$arg->name]];
} elseif (isset($params[$arg->name])) {
$arguments[] = $params[$arg->name];
} else {
$arguments[] = null;
}
}
// Call function from lib
$items = array_merge($items, call_user_func_array($callable, $arguments));
}
$this->terminateWithSuccess($items);
}
}
@@ -259,7 +259,7 @@ class BetriebsmittelP extends FHCAPI_Controller
$kaution = $this->input->post('kaution');
if($kaution) $kaution = str_replace(',', '.', $kaution);
$ausgegebenam = $this->input->post('ausgegebenam');
$retouram = $this->input->post('retouram');
$retouram = $this->input->post('retouram') == "" ? null : $this->input->post('retouram');
// NOTE(chris): transform_kartennummer
if ($betriebsmitteltyp == 'Zutrittskarte' && $nummer)
@@ -9,9 +9,10 @@ class Detailheader extends FHCAPI_Controller
public function __construct()
{
parent::__construct([
'getHeader' => ['vertrag/mitarbeiter:r'],
'getPersonAbteilung' => ['vertrag/mitarbeiter:r'],
'getLeitungOrg' => ['vertrag/mitarbeiter:r'],
'getHeader' => ['vertrag/mitarbeiter:r', 'basis/mitarbeiter:r', 'admin:r', 'assistenz:r'],
'getPersonAbteilung' => ['vertrag/mitarbeiter:r', 'basis/mitarbeiter:r', 'admin:r', 'assistenz:r'],
'getLeitungOrg' => ['vertrag/mitarbeiter:r', 'basis/mitarbeiter:r', 'admin:r', 'assistenz:r'],
'getSemesterStati' => ['admin:r', 'assistenz:r'],
]);
}
@@ -48,6 +49,17 @@ class Detailheader extends FHCAPI_Controller
$this->terminateWithSuccess(current($data));
}
public function getSemesterStati($prestudent_id)
{
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$result = $this->PrestudentstatusModel->getAllPrestudentstatiWithStudiensemester($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -294,6 +294,10 @@ class Funktionen extends FHCAPI_Controller
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
if($datum_von == '')
$datum_von = null;
if($datum_bis == '')
$datum_bis = null;
$result = $this->BenutzerfunktionModel->update(
[
@@ -0,0 +1,86 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Config extends FHCAPI_Controller
{
private $_ci;
private $_uid;
public function __construct()
{
parent::__construct([
'get' => ['admin:r', 'assistenz:r'],
'set' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->loadPhrases([
'lehre'
]);
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
$this->_ci->load->library('PermissionLib');
}
public function get()
{
if (!($this->permissionlib->isBerechtigt('basis/tempus')) && !($this->permissionlib->isBerechtigt('lv-plan')))
$this->terminateWithSuccess([]);
$ignore_kollision = $this->_ci->variablelib->getVar('ignore_kollision');
$ignore_zeitsperre = $this->_ci->variablelib->getVar('ignore_zeitsperre');
$ignore_reservierung = $this->_ci->variablelib->getVar('ignore_reservierung');
$config['ignore_kollision'] = [
"type" => "checkbox",
"label" => 'ignore_kollision',
"value" => $ignore_kollision,
];
$config['ignore_zeitsperre'] = [
"type" => "checkbox",
"label" => 'ignore_zeitsperre',
"value" => $ignore_zeitsperre,
];
$config['ignore_reservierung'] = [
"type" => "checkbox",
"label" => 'ignore_reservierung',
"value" => $ignore_reservierung,
];
$this->terminateWithSuccess($config);
}
public function set()
{
if (!($this->permissionlib->isBerechtigt('basis/tempus')) && !($this->permissionlib->isBerechtigt('lv-plan')))
$this->terminateWithSuccess([]);
$this->load->model('system/Variable_model', 'VariableModel');
foreach (['ignore_kollision','ignore_zeitsperre','ignore_reservierung'] as $variable)
{
if ($this->_ci->input->post($variable) !== null)
{
$this->VariableModel->update(array('uid' => $this->_uid, 'name' => $variable), array('wert' => $this->input->post($variable)));
}
}
$this->terminateWithSuccess();
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
}
@@ -1,47 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Favorites extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'index' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED
]);
// Load models
$this->load->model('system/Variable_model', 'VariableModel');
}
public function index()
{
$result = $this->VariableModel->getVariables(getAuthUID(), ['lv_favorites']);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
$this->terminateWithSuccess(null);
else
$this->terminateWithSuccess(isset($data['lv_favorites']) ? $data['lv_favorites'] : null);
}
public function set()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('favorites', 'Favorites', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$favorites = $this->input->post('favorites');
$result = $this->VariableModel->setVariable(getAuthUID(), 'lv_favorites', $favorites);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
}
}
@@ -15,6 +15,7 @@ class Gruppe extends FHCAPI_Controller
'getBenutzerSearch' => ['admin:r', 'assistenz:r'],
'getAllSearch' => ['admin:r', 'assistenz:r'],
'getByLehreinheit' => ['admin:r', 'assistenz:r'],
'getGruppe' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
@@ -67,7 +68,7 @@ class Gruppe extends FHCAPI_Controller
$this->checkPermission($lehreinheit_id);
$result = $this->_ci->LehreinheitgruppeModel->addGroup($lehreinheit_id, $gid, !($lehrverband === 'false'));
$result = $this->_ci->LehreinheitgruppeModel->addGroup($lehreinheit_id, $gid, $lehrverband === true || $lehrverband === 'true');
if (isError($result))
$this->terminateWithError(getError($result));
@@ -75,6 +76,71 @@ class Gruppe extends FHCAPI_Controller
$this->terminateWithSuccess($result);
}
public function getGruppe()
{
$lehrverband = $this->input->post('lehrverband');
$gruppen_result = array();
if ($lehrverband === false)
{
$gruppen_result = $this->_ci->GruppeModel->loadWhere(array(
'studiengang_kz' => $this->input->post('stg_kz'),
'gruppe_kurzbz' => $this->input->post('gruppe_kurzbz'),
'aktiv' => true
));
}
else if ($lehrverband === true)
{
if (!isEmptyString($this->input->post('verband')))
{
$this->LehrverbandModel->db->where('verband', $this->input->post('verband'));
}
else
{
$this->LehrverbandModel->db->group_start();
$this->LehrverbandModel->db->where("trim(verband) = ''");
$this->LehrverbandModel->db->or_where("verband IS NULL");
$this->LehrverbandModel->db->group_end();
}
if (!isEmptyString($this->input->post('gruppe')))
{
$this->LehrverbandModel->db->where('gruppe', $this->input->post('gruppe'));
}
else
{
$this->LehrverbandModel->db->group_start();
$this->LehrverbandModel->db->where("trim(gruppe) = ''");
$this->LehrverbandModel->db->or_where("gruppe IS NULL");
$this->LehrverbandModel->db->group_end();
}
if (!isEmptyString((string)$this->input->post('semester')))
{
$this->LehrverbandModel->db->where('semester', $this->input->post('semester'));
}
else
{
$this->LehrverbandModel->db->group_start();
$this->LehrverbandModel->db->where("semester = ''");
$this->LehrverbandModel->db->or_where("semester IS NULL");
$this->LehrverbandModel->db->group_end();
}
$gruppen_result = $this->LehrverbandModel->loadWhere(array('studiengang_kz' => $this->input->post('stg_kz'), 'aktiv' => true));
}
if (!hasData($gruppen_result))
return $this->terminateWithError('No group found');
$gruppen_array = getData($gruppen_result)[0];
$this->terminateWithSuccess($gruppen_array->gid);
}
public function getByLehreinheit($lehreinheit_id = null)
{
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id))
@@ -134,9 +134,14 @@ class Lektor extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
if (isset($formData['semesterstunden']) && (!is_numeric($formData['semesterstunden']) || $formData['semesterstunden'] === ''))
$nullable_fields = array('semesterstunden', 'stundensatz', 'planstunden');
foreach ($nullable_fields as $nullable_field)
{
$formData['semesterstunden'] = null;
if (isset($formData[$nullable_field]) && (!is_numeric($formData[$nullable_field]) || $formData[$nullable_field] === ''))
{
$formData[$nullable_field] = null;
}
}
$lehreinheit_permission = $this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan'));
@@ -144,6 +149,9 @@ class Lektor extends FHCAPI_Controller
if (!$lehreinheit_permission)
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
if (!is_null($this->getLektorVertrag($lehreinheit_id, $mitarbeiter_uid)) && (array_key_exists('mitarbeiter_uid', $formData) && $mitarbeiter_uid !== $formData['mitarbeiter_uid']))
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
$result = $this->_ci->lektorlib->updateLektorFromLehreinheit($lehreinheit_id, $mitarbeiter_uid, $formData);
if (isError($result)) $this->terminateWithError(getError($result));
@@ -154,7 +162,7 @@ class Lektor extends FHCAPI_Controller
{
$value = str_replace(',', '.', $value);
if (!is_numeric($value))
if (!is_numeric($value) && $value !== "")
{
$this->form_validation->set_message('_check_decimal', 'Das Feld {field} muss eine Zahl sein.');
return false;
@@ -0,0 +1,84 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Noten extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getCertificate' => 'student/noten:r',
'getTeacherProposal' => 'student/noten:r',
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load Phrases
$this->loadPhrases([
'stv',
'person',
'lehre'
]);
}
public function getCertificate($lv_id, $studiensemester_kurzbz = null)
{
if (is_null($lv_id) || !ctype_digit((string)$lv_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('education/lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->LehrveranstaltungModel->loadWhere([
'lehrveranstaltung_id' => $lv_id
]);
$lehrveranstaltung = $this->getDataOrTerminateWithError($result);
if (!$lehrveranstaltung)
$this->terminateWithSuccess([]);
if ($studiensemester_kurzbz !== null && !$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$result = $this->ZeugnisnoteModel->getZeugnisnoten(null, $studiensemester_kurzbz, $lehrveranstaltung[0]->lehrveranstaltung_id);
$grades = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($grades);
}
public function getTeacherProposal($lv_id, $studiensemester_kurzbz = null)
{
if (is_null($lv_id) || !ctype_digit((string)$lv_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('education/lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->LehrveranstaltungModel->loadWhere([
'lehrveranstaltung_id' => $lv_id
]);
$lehrveranstaltung = $this->getDataOrTerminateWithError($result);
if (!$lehrveranstaltung)
$this->terminateWithSuccess([]);
if ($studiensemester_kurzbz !== null && !$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$result = $this->LvgesamtnoteModel->getLvGesamtNoten($lv_id, null, $studiensemester_kurzbz);
$grades = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($grades);
}
}
@@ -19,6 +19,8 @@
if (!defined('BASEPATH'))
exit('No direct script access allowed');
use CI3_Events as Events;
class Setup extends FHCAPI_Controller
{
private $_ci;
@@ -27,7 +29,8 @@ class Setup extends FHCAPI_Controller
public function __construct()
{
parent::__construct([
'getTabs' => ['admin:r', 'assistenz:r'],
'getLETabs' => ['admin:r', 'assistenz:r'],
'getLVTabs' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r'],
'getSprache' => ['admin:r', 'assistenz:r'],
'getRaumtyp' => ['admin:r', 'assistenz:r'],
@@ -41,9 +44,10 @@ class Setup extends FHCAPI_Controller
$this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
$this->_ci->load->helper('hlp_document');
}
public function getTabs()
public function getLETabs()
{
$tabs['details'] = array (
'title' => 'Details',
@@ -60,11 +64,43 @@ class Setup extends FHCAPI_Controller
'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Lektor.js'),
'config' => []
);
$tabs['termine'] = array (
'title' => 'Termine',
'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Termine.js'),
'config' => []
);
$tabs['notiz'] = array (
'title' => 'Notizen',
'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Notiz.js'),
'config' => []
);
Events::trigger('lvv_conf_tabs', function & () use (&$tabs) {
return $tabs;
});
$this->terminateWithSuccess($tabs);
}
public function getLVTabs()
{
$tabs['termine'] = array (
'title' => 'Termine',
'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/LVTermine.js'),
'config' => []
);
$tabs['noten'] = array (
'title' => 'Noten',
'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Noten.js'),
'config' => [
'usePoints' => defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE,
'edit' => 'both', // Possible values: both|header|inline
'delete' => 'inline', // Possible values: both|header|inline
'documents' => 'inline', // Possible values: both|header|inline
'documentslist' => gradesDocumentsList(),
'semesterSelect' => false
]
);
$this->terminateWithSuccess($tabs);
}
@@ -1,117 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class StgTree extends FHCAPI_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['admin:r', 'assistenz:r'];
parent::__construct($permissions);
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
}
public function _remap($method, $params = [])
{
if ($method == '' || $method == 'index')
return $this->getBase();
if (!$this->permissionlib->isBerechtigt('assistenz', 's', $method)
&& !$this->permissionlib->isBerechtigt('admin', 's', $method)
) {
return $this->_outputAuthError([$method => ['admin:r', 'assistenz:r']]);
}
return $this->getStudiengang($method);
show_404();
}
protected function getBase()
{
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("v.studiengang_kz AS link");
$this->StudiengangModel->addSelect(
"CONCAT(kurzbzlang, ' (', UPPER(CONCAT(typ, kurzbz)), ') - ', tbl_studiengang.bezeichnung) AS name",
false
);
$this->StudiengangModel->addSelect('erhalter_kz');
$this->StudiengangModel->addSelect('typ');
$this->StudiengangModel->addSelect('kurzbz');
$this->StudiengangModel->addSelect('studiengang_kz');
$this->StudiengangModel->addSelect('studiengang_kz AS stg_kz');
$this->StudiengangModel->addOrder('erhalter_kz');
$this->StudiengangModel->addOrder('typ');
$this->StudiengangModel->addOrder('kurzbz');
$stgs = $this->permissionlib->getSTG_isEntitledFor('admin') ?: [];
$stgs = array_merge($stgs, $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []);
if (!$stgs)
$this->terminateWithSuccess([]);
$this->StudiengangModel->db->where_in('studiengang_kz', $stgs);
$result = $this->StudiengangModel->loadWhere(['v.aktiv' => true]);
$list = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($list);
}
protected function getStudiengang($studiengang_kz)
{
$link = $studiengang_kz . '/';
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", semester) AS link", false);
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester ORDER BY verband, gruppe LIMIT 1)) AS name", false);
$this->StudiengangModel->addSelect("TRUE AS leaf", false);
$this->StudiengangModel->addSelect('semester');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->StudiengangModel->addOrder('semester');
$result = $this->StudiengangModel->loadWhere([
'v.studiengang_kz' => $studiengang_kz,
'v.aktiv' => true
]);
$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);
}
}
@@ -26,7 +26,9 @@ class Studiensemester extends FHCAPI_Controller
'getAll' => self::PERM_LOGGED,
'getAktNext' => self::PERM_LOGGED,
'getStudienjahrByStudiensemester' => self::PERM_LOGGED,
'getAllStudiensemesterAndAktOrNext' => self::PERM_LOGGED
'getAllStudiensemesterAndAktOrNext' => self::PERM_LOGGED,
'current' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED
)
);
// Load model StudiensemesterModel
@@ -166,4 +168,39 @@ class Studiensemester extends FHCAPI_Controller
$this->terminateWithSuccess(array($studiensemester, $aktuell));
}
public function current()
{
$result = $this->StudiensemesterModel->getNearest();
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
$this->terminateWithError('Kein Studiensemester aktiv');
if (count($data) > 1)
$this->terminateWithError('Mehrere Studiensemester aktiv');
$this->terminateWithSuccess(current($data)->studiensemester_kurzbz);
}
public function set()
{
$this->load->library('AuthLib');
$this->load->library('form_validation');
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$stdsem = $this->input->post('studiensemester_kurzbz');
$this->load->model('system/Variable_model', 'VariableModel');
$result = $this->VariableModel->setVariable(getAuthUID(), 'semester_aktuell', $stdsem);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
}
}
@@ -246,12 +246,12 @@ class Abschlusspruefung extends FHCAPI_Controller
{
$searchString = $this->input->get('searchString') ?? '';
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('person/Person_model', 'PersonModel');
$result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'ohneMaUid');
$result = $this->PersonModel->searchPerson($searchString, 'mitMaUid');
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess($result ?: []);
@@ -371,6 +371,9 @@ class Abschlusspruefung extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$datum = $formData['datum'] == '' ? null : $formData['datum'];
$sponsion = $formData['sponsion'] == '' ? null : $formData['sponsion'];
$result = $this->AbschlusspruefungModel->update(
[
'abschlusspruefung_id' => $abschlusspruefung_id
@@ -382,8 +385,8 @@ class Abschlusspruefung extends FHCAPI_Controller
'vorsitz' => $vorsitz,
'pruefungsantritt_kurzbz' => $formData['pruefungsantritt_kurzbz'],
'abschlussbeurteilung_kurzbz' => $formData['abschlussbeurteilung_kurzbz'],
'datum' => $formData['datum'],
'sponsion' => $formData['sponsion'],
'datum' => $datum,
'sponsion' => $sponsion,
'pruefer1' => $pruefer1,
'pruefer2' => $pruefer2,
'pruefer3' => $pruefer3,
@@ -301,6 +301,7 @@ class Config extends FHCAPI_Controller
public function student()
{
$this->load->helper('hlp_document');
$result = [];
$config = $this->config->item('tabs');
@@ -376,9 +377,9 @@ class Config extends FHCAPI_Controller
'config' => [
'usePoints' => defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE,
'edit' => 'both', // Possible values: both|header|inline
'delete' => 'both', // Possible values: both|header|inline
'documents' => 'both', // Possible values: both|header|inline
'documentslist' => $this->gradesDocumentsList()
'delete' => 'inline', // Possible values: both|header|inline
'documents' => 'inline', // Possible values: both|header|inline
'documentslist' => gradesDocumentsList()
]
];
@@ -622,188 +623,6 @@ class Config extends FHCAPI_Controller
] + $this->kontoColumns();
}
/**
* Helper function to generate the default documentslist config for the
* grades tab.
*
* The resulting array consists of elements which are associative arrays
* that can have the following entries:
* title (required) on the first level this can be HTML code.
* permissioncheck (optional) an URL to an FHCAPI endpoint which returns
* true or false.
* link (optional) an URL that will be called if "action" and
* "children" are not defined.
* action (optional) an associative array that describes an
* POST action that will be called if "children" is
* not defined.
* It can have the following entries:
* - url (required) an URL to an FHCAPI endpoint.
* - post (optional) an associative array with the POST data to
* be sent.
* - response (optional) a string that will be displayed on success.
* children (optional) an array of child elements
*
* All strings that start with { and end with } in the URLs and the
* actions post parameter will be replaced with the corresponding
* attribute of the current dataset (e.G: {uid} will be replaced with the
* uid of the current dataset)
*
* @return array
*/
protected function gradesDocumentsList()
{
$permissioncheck = site_url("api/frontend/v1/documents/permissionAlternativeFormat/{studiengang_kz}");
$title_ger = $this->p->t("global", "deutsch");
$title_eng = $this->p->t("global", "englisch");
$title_ff = $this->p->t("stv", "document_certificate");
$title_lv = $this->p->t("stv", "document_coursecertificate");
$link_ff = "documents/export/" .
"zertifikat.rdf.php/" .
"Zertifikat" .
"?stg_kz={studiengang_kz_lv}" .
"&uid={uid}" .
"&ss={studiensemester_kurzbz}" .
"&lvid={lehrveranstaltung_id}";
$link_lv_ger = "documents/export/" .
"lehrveranstaltungszeugnis.rdf.php/" .
"LVZeugnis" .
"?stg_kz={studiengang_kz}" .
"&uid={uid}" .
"&ss={studiensemester_kurzbz}" .
"&lvid={lehrveranstaltung_id}";
$link_lv_eng = "documents/export/" .
"lehrveranstaltungszeugnis.rdf.php/" .
"LVZeugnisEng" .
"?stg_kz={studiengang_kz}" .
"&uid={uid}" .
"&ss={studiensemester_kurzbz}" .
"&lvid={lehrveranstaltung_id}";
$archive_url = "api/frontend/v1/documents/archiveSigned";
$archive_response = $this->p->t("stv", "document_signed_and_archived");
$archive_post_ff = [
"xml" => "zertifikat.rdf.php",
"xsl" => "Zertifikat",
"stg_kz" => "{studiengang_kz_lv}",
"uid" => "{uid}",
"ss" => "{studiensemester_kurzbz}",
"lvid" => "{lehrveranstaltung_id}"
];
$archive_post_lv_ger = [
"xml" => "lehrveranstaltungszeugnis.rdf.php",
"xsl" => "LVZeugnis",
"stg_kz" => "{studiengang_kz}",
"uid" => "{uid}",
"ss" => "{studiensemester_kurzbz}",
"lvid" => "{lehrveranstaltung_id}"
];
$archive_post_lv_eng = [
"xml" => "lehrveranstaltungszeugnis.rdf.php",
"xsl" => "LVZeugnisEng",
"stg_kz" => "{studiengang_kz}",
"uid" => "{uid}",
"ss" => "{studiensemester_kurzbz}",
"lvid" => "{lehrveranstaltung_id}"
];
$list = [
[
'title' => '<i class="fa fa-download" title="' . $this->p->t("stv", "document_download") . '"></i>',
'children' => [
[
'title' => $title_ff,
'link' => site_url($link_ff)
],
[
'title' => $title_lv,
'children' => [
[
'title' => $title_ger,
'link' => site_url($link_lv_ger),
'children' => [
[
'title' => 'PDF',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_ger)
],
[
'title' => 'DOC',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_ger . "&output=doc")
],
[
'title' => 'ODT',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_ger . "&output=odt")
]
]
],
[
'title' => $title_eng,
'link' => site_url($link_lv_eng),
'children' => [
[
'title' => 'PDF',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_eng)
],
[
'title' => 'DOC',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_eng . "&output=doc")
],
[
'title' => 'ODT',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_eng . "&output=odt")
]
]
]
]
]
]
],
[
'title' => '<i class="fas fa-archive" title="' . $this->p->t("stv", "document_archive") . '"></i>',
'children' => [
[
'title' => $title_ff,
'action' => [
'url' => site_url($archive_url),
'post' => $archive_post_ff,
'response' => $archive_response
]
],
[
'title' => $title_lv,
'children' => [
[
'title' => $title_ger,
'action' => [
'url' => site_url($archive_url),
'post' => $archive_post_lv_ger,
'response' => $archive_response
]
],
[
'title' => $title_eng,
'action' => [
'url' => site_url($archive_url),
'post' => $archive_post_lv_eng,
'response' => $archive_response
]
]
]
]
]
]
];
return $list;
}
/**
* Sort tab list
*
@@ -170,6 +170,8 @@ class Dokumente extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$nachgereicht_am = $this->input->post('nachgereicht_am') == '' ? null : $this->input->post('nachgereicht_am');
$uid = getAuthUID();
$result = $this->AkteModel->update(
@@ -180,7 +182,7 @@ class Dokumente extends FHCAPI_Controller
'dokument_kurzbz' => $this->input->post('dokument_kurzbz'),
'anmerkung_intern' => $this->input->post('anmerkung_intern'),
'titel_intern' => $this->input->post('titel_intern'),
'nachgereicht_am' => $this->input->post('nachgereicht_am'),
'nachgereicht_am' => $nachgereicht_am,
'updateamum' => date('c'),
'updatevon' => $uid,
]
@@ -429,9 +429,12 @@ class Konto extends FHCAPI_Controller
'updateamum' => date('c'),
'updatevon' => getAuthUID()
];
foreach ($allowed as $field)
if ($this->input->post($field) !== null)
$data[$field] = $this->input->post($field);
if($data['buchungsdatum'] == '')
$data['buchungsdatum'] = null;
$result = $this->KontoModel->update($id, $data);
@@ -34,7 +34,7 @@ class LvTermine extends FHCAPI_Controller
//TODO Build own lib or combine with Controller Stundenplan.php
//here use of logic of Stundenplan.php, extended with parameters uid, grouping, and used dbTable
public function getStundenplan($uid, $start_date = null, $end_date = null, $groupConsecutiveHours = false, $dbStundenplanTable = "stundenplan")
public function getStundenplan($uid, $start_date = null, $end_date = null, $dbStundenplanTable = "stundenplan", $groupConsecutiveHours = false)
{
$student_uid = $uid;
$semester_range = $this->studienSemesterErmitteln($start_date, $end_date);
@@ -80,13 +80,6 @@ class LvTermine extends FHCAPI_Controller
$stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? [];
$this->terminateWithSuccess($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);
}
public function getStudiensemester()
@@ -237,8 +237,8 @@ class Mobility extends FHCAPI_Controller
}
$formData = $this->input->post('formData');
$von = $formData['von'] ?? null;
$bis = $formData['bis'] ?? null;
$von = ($formData['von'] ?? '') ?: null;
$bis = ($formData['bis'] ?? '') ?: null;
$nation_code = $formData['nation_code'] ?? null;
$mobilitaetsprogramm_code = $formData['mobilitaetsprogramm_code'] ?? null;
$herkunftsland_code = $formData['herkunftsland_code'] ?? null;
@@ -193,7 +193,7 @@ class Prestudent extends FHCAPI_Controller
}
elseif (
$val === ''
&& in_array($prop, ['zgvnation', 'zgvmanation', 'zgvdoktornation', 'berufstaetigkeit_code', 'ausbildungcode'])
&& in_array($prop, ['zgvnation', 'zgvmanation', 'zgvdoktornation', 'berufstaetigkeit_code', 'ausbildungcode', 'zgvdatum', 'zgvmadatum'])
)
{
$val = null;
@@ -42,6 +42,8 @@ class Projektarbeit extends FHCAPI_Controller
$this->load->model('education/Note_model', 'NoteModel');
$this->load->model('education/Projektbetreuer_model', 'BetreuerModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
// load libraries
$this->load->library('PermissionLib');
@@ -100,16 +102,16 @@ class Projektarbeit extends FHCAPI_Controller
private function fetchProjektarbeitById($projektarbeit_id) {
$this->ProjektarbeitModel->resetQuery();
$this->ProjektarbeitModel->addSelect(
'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, lehrveranstaltung_id, lehreinheit_id,
firma_id, beginn, ende, gesperrtbis, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name'
'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, lehrveranstaltung_id, lehreinheit_id,
tbl_projektarbeit.studiensemester_kurzbz, firma_id, beginn, ende, gesperrtbis, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name'
);
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
$this->ProjektarbeitModel->addJoin('public.tbl_firma fa', 'firma_id', 'LEFT');
return $this->ProjektarbeitModel->loadWhere(
array('projektarbeit_id' => $projektarbeit_id)
);
}
/**
@@ -246,14 +248,38 @@ class Projektarbeit extends FHCAPI_Controller
$additional_lehrveranstaltung_id = $this->input->get('additional_lehrveranstaltung_id');
if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemster missing', self::ERROR_TYPE_GENERAL);
if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemester missing', self::ERROR_TYPE_GENERAL);
// get Lvs
// get prestudent_id from student model
$studentRes = $this->StudentModel->load(['student_uid' => $student_uid]);
if(hasData($studentRes)) {
$student = getData($studentRes);
} else {
$this->terminateWithError($studentRes, self::ERROR_TYPE_GENERAL);
}
// to get prestudent_status history
$historyRes = $this->PrestudentstatusModel->getHistoryPrestudent($student[0]->prestudent_id);
if(hasData($historyRes)) {
$history = getData($historyRes);
} else {
$this->terminateWithError($historyRes, self::ERROR_TYPE_GENERAL);
}
// query for every lva of a studiengang that has projektarbeit flag true
$lvsResult = $this->LehrveranstaltungModel->getLvsForProjektarbeit($student_uid, $studiengang_kz, $additional_lehrveranstaltung_id);
if (isError($lvsResult)) return $this->terminateWithError($lvsResult, self::ERROR_TYPE_GENERAL);
$lvs = hasData($lvsResult) ? getData($lvsResult) : [];
$lvsIDs = array_column($lvs, 'lehrveranstaltung_id');
// get current studienplan_id from status history to find out which lva options are actually assigned to the students studienplan
// important so the projektarbeit has the correct lva assigned to be able to find and print the thesis title on the degree documents!
$currentStatus = $history[0];
$lvByStudienPlanRes = $this->LehrveranstaltungModel->getLvsByStudienplanByLvaIDs($currentStatus->studienplan_id, $lvsIDs);
if(hasData($lvByStudienPlanRes)) {
$lvs = getData($lvByStudienPlanRes);
}
foreach ($lvs as $lv)
{
@@ -320,11 +346,18 @@ class Projektarbeit extends FHCAPI_Controller
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Projekttyp'])
]);
$this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'required|is_natural', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehreinheit']),
$this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'is_natural', [
'is_natural' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit'])
]);
$this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrveranstaltung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung'])
]);
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studiensemester'])
]);
$this->form_validation->set_rules('beginn', 'Beginn', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Beginn'])
]);
@@ -354,6 +387,8 @@ class Projektarbeit extends FHCAPI_Controller
'projekttyp_kurzbz' => $formData['projekttyp_kurzbz'],
'firma_id' => $formData['firma_id'] ?? null,
'lehreinheit_id' => $formData['lehreinheit_id'],
'lehrveranstaltung_id' => $formData['lehrveranstaltung_id'],
'studiensemester_kurzbz' => $formData['studiensemester_kurzbz'],
'beginn' => isset($formData['beginn']) && !isEmptyString($formData['beginn']) ? $formData['beginn'] : null,
'ende' => isset($formData['ende']) && !isEmptyString($formData['ende']) ? $formData['ende'] : null,
'note' => $formData['note'] ?? null,
@@ -448,8 +448,10 @@ class Pruefung extends FHCAPI_Controller
}
}
$datum = $this->input->post('datum') == '' ? null : $this->input->post('datum');
if(intval($pruefung_id) > 0)
{
$result = $this->PruefungModel->update(
[
'pruefung_id' => $pruefung_id
@@ -459,7 +461,7 @@ class Pruefung extends FHCAPI_Controller
'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'),
'note' => $this->input->post('note'),
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'datum' => $this->input->post('datum'),
'datum' => $datum,
'anmerkung' => $this->input->post('anmerkung'),
'updatevon' => $authUID,
'updateamum' => date('c'),
@@ -472,7 +474,7 @@ class Pruefung extends FHCAPI_Controller
'lehreinheit_id' => $this->input->post('lehreinheit_id'),
'student_uid' => $this->input->post('student_uid'),
'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'),
'datum' => $this->input->post('datum'),
'datum' => $datum,
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'note' => $this->input->post('note'),
'anmerkung' => $this->input->post('anmerkung'),
@@ -520,7 +522,7 @@ class Pruefung extends FHCAPI_Controller
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'note' => $this->input->post('note'),
'uebernahmedatum' => date('c'),
'benotungsdatum' => $this->input->post('datum'),
'benotungsdatum' => $datum,
'insertamum' => date('c'),
'insertvon' => $authUID,
'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null
@@ -555,7 +557,7 @@ class Pruefung extends FHCAPI_Controller
], [
'note' => $this->input->post('note'),
'uebernahmedatum' => date('c'),
'benotungsdatum' => $this->input->post('datum'),
'benotungsdatum' => $datum,
'updateamum' => date('c'),
'updatevon' => $authUID,
'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null
@@ -144,6 +144,7 @@ class Student extends FHCAPI_Controller
. $this->PrestudentModel->escape($studiensemester_kurzbz)
. ") AS statusofsemester"
);
$this->PrestudentModel->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz');
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 'student_uid = uid', 'LEFT');
@@ -296,6 +297,10 @@ class Student extends FHCAPI_Controller
$fotoval = ($val == '') ? null : str_replace('data:image/jpeg;base64,', '', $val);
$update_person[$prop] = $fotoval;
}
else if ($prop == 'gebdatum')
{
$update_person[$prop] = ($val == '') ? null : $val;
}
else
{
$update_person[$prop] = $val;
@@ -108,6 +108,7 @@ class Students extends FHCAPI_Controller
'studiensemester_kurzbz' => $studiensemester_kurzbz
]);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$this->studentlistlib->addJoin(
"(
@@ -138,7 +139,7 @@ class Students extends FHCAPI_Controller
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->decodeTagsJsonInResult($data);
$this->terminateWithSuccess($data);
}
@@ -153,7 +154,8 @@ class Students extends FHCAPI_Controller
$this->addMeta('ci_params', [
'studiensemester_kurzbz' => $studiensemester_kurzbz
]);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$this->studentlistlib->addJoin(
"(
@@ -190,14 +192,14 @@ class Students extends FHCAPI_Controller
) AS semester", false);
$this->studentlistlib->addSelect("COALESCE(v.verband::text, ''::text) AS verband");
$this->studentlistlib->addSelect("COALESCE(v.gruppe::text, ''::text) AS gruppe");
$this->addFilter($studiensemester_kurzbz);
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->decodeTagsJsonInResult($data);
$this->terminateWithSuccess($data);
}
@@ -213,6 +215,7 @@ class Students extends FHCAPI_Controller
'studiensemester_kurzbz' => $studiensemester_kurzbz
]);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$this->studentlistlib->addJoin(
"(
@@ -235,59 +238,66 @@ class Students extends FHCAPI_Controller
) AS semester", false);
$this->studentlistlib->addSelect("COALESCE(v.verband::text, ''::text) AS verband");
$this->studentlistlib->addSelect("COALESCE(v.gruppe::text, ''::text) AS gruppe");
$this->addFilter($studiensemester_kurzbz);
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->decodeTagsJsonInResult($data);
$this->terminateWithSuccess($data);
}
public function getPrestudents(
$studiengang_kz,
$studiengang_typ_kurzbz,
$studiensemester_kurzbz = null,
$filter = null
) {
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiengang_kz' => $studiengang_kz,
'studiengang_typ_kurzbz' => $studiengang_typ_kurzbz,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'filter' => $filter
));
$this->fetchPrestudents($studiengang_kz, $studiensemester_kurzbz, $filter);
$this->fetchPrestudents($studiengang_typ_kurzbz, $studiensemester_kurzbz, $filter);
}
public function getPrestudentsOrgform(
$studiengang_kz,
$studiengang_typ_kurzbz,
$orgform_kurzbz,
$studiensemester_kurzbz = null,
$filter = null
) {
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiengang_kz' => $studiengang_kz,
'studiengang_typ_kurzbz' => $studiengang_typ_kurzbz,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'filter' => $filter,
'orgform_kurzbz' => $orgform_kurzbz
));
$this->fetchPrestudents($studiengang_kz, $studiensemester_kurzbz, $filter, $orgform_kurzbz);
$this->fetchPrestudents($studiengang_typ_kurzbz, $studiensemester_kurzbz, $filter, $orgform_kurzbz);
}
/**
* @param integer $studiengang_kz
* @param string $studiengang_typ_kurzbz
* @param string $studiensemester_kurzbz (optional)
* @param string $filter (optional)
* @param string $orgform_kurzbz (optional)
*
* @return void
*/
protected function fetchPrestudents($studiengang_kz, $studiensemester_kurzbz = null, $filter = null, $orgform_kurzbz = null)
protected function fetchPrestudents($studiengang_typ_kurzbz, $studiensemester_kurzbz = null, $filter = null, $orgform_kurzbz = null)
{
$studiengang_kz = $this->getStudiengangKz($studiengang_typ_kurzbz);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$orgform_kurzbz = $this->getOrgformKurzbz($orgform_kurzbz);
if ($studiengang_kz === null)
show_404();
$stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
$selectRT = "
@@ -439,19 +449,21 @@ class Students extends FHCAPI_Controller
$this->studentlistlib->addSelect("'' AS verband");
$this->studentlistlib->addSelect("'' AS gruppe");
$query_studiensemester_kurzbz = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : '\'NULL\'';
$this->studentlistlib->addSelect($query_studiensemester_kurzbz . ' as query_studiensemester_kurzbz');
$this->addFilter($studiensemester_kurzbz);
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->decodeTagsJsonInResult($data);
$this->terminateWithSuccess($data);
}
public function getStudents(
$studiensemester_kurzbz,
$studiengang_kz,
$studiengang_typ_kurzbz,
$semester = null,
$verband = null,
$gruppe = null
@@ -459,18 +471,18 @@ class Students extends FHCAPI_Controller
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'studiengang_kz' => $studiengang_kz,
'studiengang_typ_kurzbz' => $studiengang_typ_kurzbz,
'semester' => $semester,
'verband' => $verband,
'gruppe' => $gruppe
));
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, $verband, $gruppe, null, null);
$this->fetchStudents($studiensemester_kurzbz, $studiengang_typ_kurzbz, $semester, $verband, $gruppe, null, null);
}
public function getStudentsOrgform(
$studiensemester_kurzbz,
$studiengang_kz,
$studiengang_typ_kurzbz,
$orgform_kurzbz,
$semester = null,
$verband = null,
@@ -479,37 +491,37 @@ class Students extends FHCAPI_Controller
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'studiengang_kz' => $studiengang_kz,
'studiengang_typ_kurzbz' => $studiengang_typ_kurzbz,
'orgform_kurzbz' => $orgform_kurzbz,
'semester' => $semester,
'verband' => $verband,
'gruppe' => $gruppe
));
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, $verband, $gruppe, null, $orgform_kurzbz);
$this->fetchStudents($studiensemester_kurzbz, $studiengang_typ_kurzbz, $semester, $verband, $gruppe, null, $orgform_kurzbz);
}
public function getStudentsSpezialgruppe(
$studiensemester_kurzbz,
$studiengang_kz,
$studiengang_typ_kurzbz,
$semester,
$gruppe_kurzbz
) {
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'studiengang_kz' => $studiengang_kz,
'studiengang_typ_kurzbz' => $studiengang_typ_kurzbz,
'semester' => $semester,
'gruppe_kurzbz' => $gruppe_kurzbz
));
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, null, null, $gruppe_kurzbz, null);
$this->fetchStudents($studiensemester_kurzbz, $studiengang_typ_kurzbz, $semester, null, null, $gruppe_kurzbz, null);
}
public function getStudentsOrgformSpezialgruppe(
$studiensemester_kurzbz,
$orgform_kurzbz,
$studiengang_kz,
$studiengang_typ_kurzbz,
$semester,
$gruppe_kurzbz
) {
@@ -517,17 +529,17 @@ class Students extends FHCAPI_Controller
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'orgform_kurzbz' => $orgform_kurzbz,
'studiengang_kz' => $studiengang_kz,
'studiengang_typ_kurzbz' => $studiengang_typ_kurzbz,
'semester' => $semester,
'gruppe_kurzbz' => $gruppe_kurzbz
));
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, null, null, $gruppe_kurzbz, $orgform_kurzbz);
$this->fetchStudents($studiensemester_kurzbz, $studiengang_typ_kurzbz, $semester, null, null, $gruppe_kurzbz, $orgform_kurzbz);
}
/**
* @param integer $studiengang_kz
* @param string $studiensemester_kurzbz
* @param string $studiengang_typ_kurzbz
* @param integer $semester (optional)
* @param string $verband (optional)
* @param integer $gruppe (optional)
@@ -538,13 +550,20 @@ class Students extends FHCAPI_Controller
*/
protected function fetchStudents(
$studiensemester_kurzbz,
$studiengang_kz,
$studiengang_typ_kurzbz,
$semester = null,
$verband = null,
$gruppe = null,
$gruppe_kurzbz = null,
$orgform_kurzbz = null
) {
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$studiengang_kz = $this->getStudiengangKz($studiengang_typ_kurzbz);
$orgform_kurzbz = $this->getOrgformKurzbz($orgform_kurzbz);
if ($studiengang_kz === null)
show_404();
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
@@ -556,6 +575,7 @@ class Students extends FHCAPI_Controller
$this->studentlistlib->addJoin("public.tbl_student s", "prestudent_id");
$this->studentlistlib->addSelect("'' AS priorisierung_relativ");
$this->studentlistlib->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz');
if ($gruppe_kurzbz !== null) {
$this->studentlistlib->addJoin('public.tbl_benutzergruppe g', 'uid', '', 'after_b');
@@ -594,10 +614,22 @@ class Students extends FHCAPI_Controller
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->decodeTagsJsonInResult($data);
$this->terminateWithSuccess($data);
}
protected function decodeTagsJsonInResult(&$data)
{
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED) {
array_walk($data, function($item, $key) {
if(isset($item->tags))
{
$item->tags = json_decode($item->tags);
}
});
}
}
/**
* @param string $prestudent_id
*
@@ -611,6 +643,8 @@ class Students extends FHCAPI_Controller
'prestudent_id' => $prestudent_id,
));
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
@@ -618,7 +652,7 @@ class Students extends FHCAPI_Controller
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$this->studentlistlib->addSelect("COALESCE(
v.semester::text,
CASE
@@ -638,7 +672,7 @@ class Students extends FHCAPI_Controller
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->decodeTagsJsonInResult($data);
$this->terminateWithSuccess($data);
}
@@ -655,6 +689,8 @@ class Students extends FHCAPI_Controller
'student_uid' => $student_uid,
));
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
@@ -664,14 +700,14 @@ class Students extends FHCAPI_Controller
$this->studentlistlib->addWhere('s.student_uid', $student_uid);
$this->addFilter($studiensemester_kurzbz);
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->decodeTagsJsonInResult($data);
$this->terminateWithSuccess($data);
}
@@ -689,6 +725,8 @@ class Students extends FHCAPI_Controller
'person_id' => $person_id,
));
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
@@ -699,13 +737,13 @@ class Students extends FHCAPI_Controller
$this->studentlistlib->addWhere('p.person_id', $person_id);
$this->addFilter($studiensemester_kurzbz);
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->decodeTagsJsonInResult($data);
$this->terminateWithSuccess($data);
}
@@ -721,6 +759,8 @@ class Students extends FHCAPI_Controller
'studiensemester_kurzbz' => $studiensemester_kurzbz
));
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$this->load->library('SearchLib', [ 'config' => 'searchstv' ]);
$this->load->library('form_validation');
@@ -755,6 +795,7 @@ class Students extends FHCAPI_Controller
END
) AS semester", false);
$this->studentlistlib->addSelect($this->PrestudentModel->escape($studiensemester_kurzbz) . ' as query_studiensemester_kurzbz');
if ($prestudent_ids && $student_uids) {
$this->studentlistlib->addWhere('tbl_prestudent.prestudent_id', $prestudent_ids);
@@ -773,7 +814,7 @@ class Students extends FHCAPI_Controller
$result = $this->studentlistlib->execute($studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->decodeTagsJsonInResult($data);
$this->terminateWithSuccess($data);
}
@@ -802,4 +843,55 @@ class Students extends FHCAPI_Controller
}
}
}
protected function getStudiengangKz($studiengang_typ_kurzbz)
{
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$result = $this->StudiengangModel->loadWhere([
'LOWER(CONCAT(typ, kurzbz)) =' => strtolower($studiengang_typ_kurzbz)
]);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
return null;
return current($data)->studiengang_kz;
}
protected function getStudiensemesterKurzbz($studiensemester_kurzbz)
{
if ($studiensemester_kurzbz === null)
return null;
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudiensemesterModel->loadWhere([
'LOWER(studiensemester_kurzbz) =' => strtolower($studiensemester_kurzbz)
]);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
return $studiensemester_kurzbz;
return current($data)->studiensemester_kurzbz;
}
protected function getOrgformKurzbz($orgform_kurzbz)
{
if ($orgform_kurzbz === null)
return null;
$this->load->model('codex/Orgform_model', 'OrgformModel');
$result = $this->OrgformModel->loadWhere([
'LOWER(orgform_kurzbz) =' => strtolower($orgform_kurzbz)
]);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
return $orgform_kurzbz;
return current($data)->orgform_kurzbz;
}
}
@@ -15,7 +15,9 @@ class Tags extends Tag_Controller
'addTag' => self::BERECHTIGUNG_KURZBZ,
'updateTag' => self::BERECHTIGUNG_KURZBZ,
'doneTag' => self::BERECHTIGUNG_KURZBZ,
'deleteTag' => self::BERECHTIGUNG_KURZBZ
'deleteTag' => self::BERECHTIGUNG_KURZBZ,
'getAllTags' => self::BERECHTIGUNG_KURZBZ,
'rebuildTagsForTypeId' => self::BERECHTIGUNG_KURZBZ,
]);
$this->config->load('stv');
@@ -45,4 +47,5 @@ class Tags extends Tag_Controller
{
parent::doneTag($this->config->item('stv_prestudent_tags'));
}
}
@@ -1,513 +0,0 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
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 verbände
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Verband extends FHCAPI_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['admin:r', 'assistenz:r'];
parent::__construct($permissions);
// Load Models
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
}
/**
* Remap calls:
* /
* /(studiengang_kz) => getStudiengang
* /(studiengang_kz)/(semester) => getSemester
* /(studiengang_kz)/(semester)/(verband) => getVerband
* /(studiengang_kz)/(org_form) => getStudiengang
* /(studiengang_kz)/(org_form)/(semester) => getSemester
* /(studiengang_kz)/(org_form)/(semester)/(verband) => getVerband
*
* @param string $method
* @param array $params (optional)
*
* @return void
*/
public function _remap($method, $params = [])
{
if ($method == '' || $method == 'index')
return $this->getBase();
// NOTE(chris): Test if access is allowed ($method is the Studiengang)
if (!$this->permissionlib->isBerechtigt('assistenz', 's', $method)
&& !$this->permissionlib->isBerechtigt('admin', 's', $method)
) {
return $this->_outputAuthError([$method => ['admin:r', 'assistenz:r']]);
}
$count = count($params);
if (!$count)
return $this->getStudiengang($method);
if ($count == 1) {
if (is_numeric($params[0]))
return $this->getSemester($method, $params[0]);
elseif ($params[0] == 'prestudent')
return $this->terminateWithSuccess($this->getStdSem($method . '/prestudent/', $method));
else
return $this->getStudiengang($method, $params[0]);
}
if ($count == 2) {
if (is_numeric($params[0]))
return $this->getVerband($method, $params[0], $params[1]);
elseif ($params[1] == 'prestudent')
return $this->terminateWithSuccess($this->getStdSem($method . '/' . $params[0] . '/prestudent/', $method));
else
return $this->getSemester($method, $params[1], $params[0]);
}
if ($count == 3 && !is_numeric($params[0]) && is_numeric($params[1]) && !is_numeric($params[2]))
return $this->getVerband($method, $params[1], $params[2], $params[0]);
show_404();
}
/**
* @return void
*/
protected function getBase()
{
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("v.studiengang_kz AS link");
$this->StudiengangModel->addSelect(
"CONCAT(kurzbzlang, ' (', UPPER(CONCAT(typ, kurzbz)), ') - ', tbl_studiengang.bezeichnung) AS name",
false
);
$this->StudiengangModel->addSelect('erhalter_kz');
$this->StudiengangModel->addSelect('typ');
$this->StudiengangModel->addSelect('kurzbz');
$this->StudiengangModel->addSelect('studiengang_kz');
$this->StudiengangModel->addSelect('studiengang_kz AS stg_kz');
$this->StudiengangModel->addOrder('erhalter_kz');
$this->StudiengangModel->addOrder('typ');
$this->StudiengangModel->addOrder('kurzbz');
$stgs = $this->permissionlib->getSTG_isEntitledFor('admin') ?: [];
$stgs = array_merge($stgs, $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []);
if (!$stgs)
$this->terminateWithSuccess([]);
$this->StudiengangModel->db->where_in('studiengang_kz', $stgs);
$result = $this->StudiengangModel->loadWhere(['v.aktiv' => true]);
$list = $this->getDataOrTerminateWithError($result);
if ($this->permissionlib->isBerechtigt('inout/uebersicht'))
$list[] = [
'name' => 'International',
'link' => 'inout',
'children' => [
[
'name' => 'Incoming',
'link' => 'inout/incoming',
'leaf' => true
],
[
'name' => 'Outgoing',
'link' => 'inout/outgoing',
'leaf' => true
],
[
'name' => 'Gemeinsame Studien',
'link' => 'inout/gemeinsamestudien',
'leaf' => true
]
]
];
$this->terminateWithSuccess($list);
}
/**
* @param integer $studiengang_kz
* @param string $orgform (optional)
*
* @return void
*/
protected function getStudiengang($studiengang_kz, $org_form = null)
{
$link = $studiengang_kz . '/';
if ($org_form !== null)
$link .= $org_form . '/';
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", semester) AS link", false);
$this->StudiengangModel->addSelect("CONCAT(
UPPER(CONCAT(typ, kurzbz)),
'-',
semester,
(
SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END
FROM public.tbl_lehrverband
WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester
ORDER BY verband, gruppe LIMIT 1
)
) AS name", false);
$this->StudiengangModel->addSelect('semester');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->StudiengangModel->addOrder('semester');
if ($org_form !== null) {
$this->StudiengangModel->addSelect("v.orgform_kurzbz");
$this->StudiengangModel->db->group_start();
$this->StudiengangModel->db->where('v.semester', 0);
$this->StudiengangModel->db->or_where('v.orgform_kurzbz', $org_form);
$this->StudiengangModel->db->group_end();
}
$result = $this->StudiengangModel->loadWhere([
'v.studiengang_kz' => $studiengang_kz,
'v.aktiv' => true
]);
$list = $this->getDataOrTerminateWithError($result);
array_unshift($list, [
'name' => 'PreStudent',
'link' => $link . 'prestudent',
'no_sem_reload' => true,
'stg_kz' => (int)$studiengang_kz,
'children' => $this->getStdSem($link . 'prestudent/', $studiengang_kz)
]);
if ($org_form === null) {
// NOTE(chris): if mischform show orgforms
$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("studiengang_kz AS stg_kz");
$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);
}
/**
* @param integer $studiengang_kz
* @param integer $semester
* @param string $orgform
*
* @return void
*/
protected function getSemester($studiengang_kz, $semester, $org_form = null)
{
$link = $studiengang_kz . '/';
if ($org_form !== null)
$link .= $org_form . '/';
$link .= $semester . '/';
$this->load->model('organisation/Gruppe_model', 'GruppeModel');
$this->GruppeModel->addDistinct();
$this->GruppeModel->addSelect("CONCAT(" . $this->GruppeModel->escape($link . 'grp/') . ", gruppe_kurzbz) AS link", false);
$this->GruppeModel->addSelect("CONCAT(gruppe_kurzbz, ' (', bezeichnung, ')') AS name", false);
$this->GruppeModel->addSelect("TRUE AS leaf", false);
$this->GruppeModel->addSelect('sort');
$this->GruppeModel->addSelect('gruppe_kurzbz');
$this->GruppeModel->addSelect($this->GruppeModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->GruppeModel->addOrder('sort');
$this->GruppeModel->addOrder('gruppe_kurzbz');
$where = [
'studiengang_kz' => $studiengang_kz,
'semester' => $semester,
'lehre' => true,
'sichtbar' => true,
'aktiv' => true,
'direktinskription' => false
];
if ($org_form !== null)
$where['orgform_kurzbz'] = $org_form;
$result = $this->GruppeModel->loadWhere($where);
$list = $this->getDataOrTerminateWithError($result);
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", verband) AS link", false);
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband ORDER BY gruppe LIMIT 1)) AS name", false);
$this->StudiengangModel->addSelect("CASE WHEN MAX(gruppe)='' OR MAX(gruppe)=' ' THEN TRUE ELSE FALSE END AS leaf");
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($semester) . ' AS semester');
$this->StudiengangModel->addSelect('verband');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->StudiengangModel->addOrder('verband');
$this->StudiengangModel->addGroupBy('link, name, verband');
$where = [
'v.studiengang_kz' => $studiengang_kz,
'v.semester' => $semester,
'v.verband !=' => '',
'v.aktiv' => true
];
if ($org_form !== null && $semester) // NOTE(chris): on semester 0 show all?
$where['v.orgform_kurzbz'] = $org_form;
$result = $this->StudiengangModel->loadWhere($where);
$result = $this->getDataOrTerminateWithError($result);
$list = array_merge($list, $result);
$this->terminateWithSuccess($list);
}
/**
* @param integer $studiengang_kz
* @param integer $semester
* @param integer $verband
* @param string $orgform
*
* @return void
*/
protected function getVerband($studiengang_kz, $semester, $verband, $org_form = null)
{
$link = $studiengang_kz . '/';
if ($org_form !== null)
$link .= $org_form . '/';
$link .= $semester . '/'. $verband . '/';
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", gruppe) AS link", false);
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, gruppe, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband AND gruppe=v.gruppe ORDER BY gruppe LIMIT 1)) AS name", false);
$this->StudiengangModel->addSelect("TRUE AS leaf", false);
$this->StudiengangModel->addSelect('v.semester');
$this->StudiengangModel->addSelect('v.verband');
$this->StudiengangModel->addSelect('gruppe');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->StudiengangModel->addOrder('gruppe');
$where = [
'v.studiengang_kz' => $studiengang_kz,
'v.semester' => $semester,
'v.verband' => $verband,
'v.gruppe !=' => '',
'v.aktiv' => true
];
if ($org_form !== null && $semester) // NOTE(chris): on semester 0 show all?
$where['v.orgform_kurzbz'] = $org_form;
$result = $this->StudiengangModel->loadWhere($where);
$list = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($list);
}
/**
* @param string $link
* @param integer $studiengang_kz
*
* @return array
*/
protected function getStdSem($link, $studiengang_kz)
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('system/Variable_model', 'VariableModel');
$result = $this->VariableModel->getVariables(getAuthUID(), ['number_displayed_past_studiensemester']);
$data = $this->getDataOrTerminateWithError($result);
$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');
$result = $this->StudiensemesterModel->load();
$studiensemester = $this->getDataOrTerminateWithError($result);
$result = [];
$studiengang_kz = (int)$studiengang_kz;
foreach ($studiensemester as $sem) {
$semlink = $link . $sem->studiensemester_kurzbz;
$intlink = $semlink . '/interessenten';
$result[] = [
'name' => $sem->studiensemester_kurzbz,
'link' => $semlink,
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Interessenten',
'link' => $intlink,
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Bewerbung nicht abgeschickt',
'link' => $intlink . '/bewerbungnichtabgeschickt',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Bewerbung abgeschickt, Status unbestätigt',
'link' => $intlink . '/bewerbungabgeschickt',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'ZGV erfüllt',
'link' => $intlink . '/zgv',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Status bestätigt',
'link' => $intlink . '/statusbestaetigt',
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Nicht zum Reihungstest angemeldet',
'link' => $intlink . '/statusbestaetigtrtnichtangemeldet',
'leaf' => true
],
[
'name' => 'Reihungstest angemeldet',
'link' => $intlink . '/statusbestaetigtrtangemeldet',
'leaf' => true
]
]
],
[
'name' => 'Nicht zum Reihungstest angemeldet',
'link' => $intlink . '/reihungstestnichtangemeldet',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Reihungstest angemeldet',
'link' => $intlink . '/reihungstestangemeldet',
'stg_kz' => $studiengang_kz,
'leaf' => true
]
]
],
[
'name' => 'Bewerber',
'link' => $semlink . '/bewerber',
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Nicht zum Reihungstest angemeldet',
'link' => $intlink . '/bewerberrtnichtangemeldet',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Reihungstest angemeldet',
'link' => $intlink . '/bewerberrtangemeldet',
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Teilgenommen',
'link' => $intlink . '/bewerberrtangemeldetteilgenommen',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Nicht teilgenommen',
'link' => $intlink . '/bewerberrtangemeldetnichtteilgenommen',
'stg_kz' => $studiengang_kz,
'leaf' => true
]
]
]
]
],
[
'name' => 'Aufgenommen',
'link' => $semlink . '/aufgenommen',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Warteliste',
'link' => $semlink . '/warteliste',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Absage',
'link' => $semlink . '/absage',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Incoming',
'link' => $semlink . '/incoming',
'stg_kz' => $studiengang_kz,
'leaf' => true
]
]
];
}
return $result;
}
}
@@ -37,6 +37,7 @@ class Tag extends API_Controller
if (isset($tag))
{
$this->TagModel->addJoin('public.tbl_notiz_typ', 'typ_kurzbz', 'typ_kurzbz');
$result = $this->TagModel->load($tag);
$this->response($result, REST_Controller::HTTP_OK);
@@ -14,11 +14,11 @@ class Mylv extends Auth_Controller
public function __construct()
{
parent::__construct([
'Student' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Studiensemester' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Lvs' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Info' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Pruefungen' => ['student/anrechnung_beantragen:r','user:r'] // TODO(chris): permissions?
'Student' => self::PERM_LOGGED,
'Studiensemester' => self::PERM_LOGGED,
'Lvs' => self::PERM_LOGGED,
'Info' => self::PERM_LOGGED,
'Pruefungen' => self::PERM_LOGGED
]);
}
@@ -1,78 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Studiensemester extends Auth_Controller
{
public function __construct()
{
// TODO(chris): access!
parent::__construct([
'index' => self::PERM_LOGGED,
'now' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED
]);
}
public function index()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addOrder('start');
$result = $this->StudiensemesterModel->load();
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
$this->outputJson($result);
}
public function now()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudiensemesterModel->getNearest();
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
$this->outputJson(getError($result));
}
$result = getData($result) ?: [];
if (count($result) != 1) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
$this->outputJsonError(count($result) ? 'Mehrere Studiensemester aktiv' : 'Kein Studiensemester aktiv');
} else {
$this->outputJsonSuccess(current($result)->studiensemester_kurzbz);
}
}
public function set()
{
$this->load->library('AuthLib');
$this->load->library('form_validation');
$_POST = json_decode(utf8_encode($this->input->raw_input_stream), true);
$this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required');
if ($this->form_validation->run() == false) {
$this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
return $this->outputJsonError($this->form_validation->error_array());
}
$stdsem = $this->input->post('studiensemester');
$this->load->model('system/Variable_model', 'VariableModel');
$result = $this->VariableModel->setVariable(getAuthUID(), 'semester_aktuell', $stdsem);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
return $this->outputJson($result);
}
$this->outputJsonSuccess(true);
}
}
+153 -73
View File
@@ -290,6 +290,38 @@ class AbgabetoolJob extends JOB_Controller
}
}
/**
* helper to tell apart an actually new/edited abgabetermin from an upload or a benotung, since all
* three write updatevon/updateamum on the same paabgabe row and the row itself keeps no change history.
* uploads and benotungen have their own notifications, reporting them as changed termine is what made
* betreuer/assistenz receive "Termine hinzugefügt oder bearbeitet" after a student uploaded a file.
*/
private function isNewOrEditedTermin($abgabe) {
// never updated, so the termin itself was created within the interval
if (empty($abgabe->updatevon)) {
return true;
}
// the student can only ever write abgabedatum by uploading -> notifyBetreuerMail/notifyStudentMail report those
if ($abgabe->student_uid === $abgabe->updatevon) {
return false;
}
// upload done by assistenz/betreuer on behalf of the student: abgabedatum is written on the day of the update
if (!empty($abgabe->abgabedatum) && !empty($abgabe->updateamum)
&& substr($abgabe->abgabedatum, 0, 10) === substr($abgabe->updateamum, 0, 10)) {
return false;
}
// typ and datum of a benoteter termin are locked (see Abgabe->postProjektarbeitAbgabe), so an update
// on it is either the benotung itself or a cosmetic edit - neither is a termin change
if ($abgabe->note !== null) {
return false;
}
return true;
}
public function notifyAssistenzAboutChangedAbgaben() {
$this->_ci->logInfo('Start job FHC-Core->notifyAssistenzAboutChangedAbgaben');
@@ -298,7 +330,7 @@ class AbgabetoolJob extends JOB_Controller
$relevantTypes = $this->_ci->config->item('RELEVANT_PAABGABETYPEN_SAMMELMAIL_ASSISTENZ');
// get all new or changed termine in interval
$result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSince($interval, $relevantTypes);
$retval = getData($result);
if(count($retval) == 0) {
@@ -314,7 +346,12 @@ class AbgabetoolJob extends JOB_Controller
if (isset($newOrChangedAbgabe->projektarbeit_id)) {
$projektarbeitId = $newOrChangedAbgabe->projektarbeit_id;
// If the 'projektarbeit_id' is not yet a key in $projektarbeiten,
// uploads and benotungen are no termin changes, they have their own notifications
if (!$this->isNewOrEditedTermin($newOrChangedAbgabe)) {
continue;
}
// If the 'projektarbeit_id' is not yet a key in $projektarbeiten,
// initialize it as an empty array.
if (!isset($projektarbeiten[$projektarbeitId])) {
$projektarbeiten[$projektarbeitId] = [];
@@ -325,6 +362,11 @@ class AbgabetoolJob extends JOB_Controller
}
}
if(count($projektarbeiten) == 0) {
$this->_ci->logInfo("Keine Emails an Assistenzen über neue oder veränderte Termine versandt");
return;
}
// for each projektarbeit fetch their assistenz and same them in their own dictionary to avoid too many mails
$assistenzMap = [];
// for each projektarbeit fetch their betreuer and save them in their own dictionary to avoid too many mails
@@ -515,14 +557,12 @@ class AbgabetoolJob extends JOB_Controller
if (isset($newOrChangedAbgabe->projektarbeit_id)) {
$projektarbeitId = $newOrChangedAbgabe->projektarbeit_id;
// check if the updatevon field is NOT the same as the student the projektarbeit is assigned to
// since uploading a file to a paabgabe is also putting updateamum & updatevon
// we have our own "student has uploaded a file" emailjob anyways
if($newOrChangedAbgabe->student_uid === $newOrChangedAbgabe->updatevon) {
// uploads and benotungen are no termin changes, they have their own notifications
if (!$this->isNewOrEditedTermin($newOrChangedAbgabe)) {
continue;
}
// If the 'projektarbeit_id' is not yet a key in $projektarbeiten,
// If the 'projektarbeit_id' is not yet a key in $projektarbeiten,
// initialize it as an empty array.
if (!isset($projektarbeiten[$projektarbeitId])) {
$projektarbeiten[$projektarbeitId] = [];
@@ -720,61 +760,112 @@ class AbgabetoolJob extends JOB_Controller
forEach ($betreuer_uids as $person_id => $abgaben) {
// $person_id is from betreuer
$result = $this->_ci->ProjektarbeitModel->getProjektbetreuerAnrede($person_id);
$data = getData($result)[0];
// resolve the recipient by the person_id the mail was grouped by. resolving it by
// projektarbeit_id + betreuerart of the first abgabe addressed the wrong person as soon as a
// projektarbeit had two betreuer of the same art
$result = $this->_ci->ProjektbetreuerModel->getBetreuerByPersonId($person_id);
$betreuerArr = getData($result);
$anrede = $data->anrede;
$anredeFillString = $data->anrede == "Herr" ? "r" : "";
$fullFormattedNameString = $data->first;
// sorting $abgaben array by datum
usort($abgaben, function ($a, $b) {
return strtotime($a->datum) <=> strtotime($b->datum);
});
$projektarbeit_titel = $abgaben[0]->titel;
// initialize the table and headers
$abgabenString = '
<table style="width: 100%; border-collapse: collapse; font-family: Arial, sans-serif; color: #333; margin-top: 15px; margin-bottom: 15px;">
<thead>
<tr style="background-color: #f2f2f2; text-align: left;">
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 15%;">Zieldatum</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 25%;">Studierende/r</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px;">Bezeichnung</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 15%;">Abgabedatum</th>
</tr>
</thead>
<tbody>';
foreach ($abgaben as $abgabe) {
// format the student name
$nameParts = [];
if (!empty($abgabe->titelpre)) $nameParts[] = $abgabe->titelpre;
$nameParts[] = $abgabe->vorname;
$nameParts[] = $abgabe->nachname;
if (!empty($abgabe->titelpost)) $nameParts[] = $abgabe->titelpost;
$studentFullName = implode(' ', $nameParts);
// format dates inline
$dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y');
$abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y');
// handle the optional Kurzbezeichnung
$kurzbzLine = !empty($abgabe->kurzbz) ? "<br/><small style='color: #666; font-style: italic;'>{$abgabe->kurzbz}</small>" : "";
$abgabenString .= "
<tr>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$dateEmailFormatted}</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$studentFullName}</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px;'>
<strong>{$abgabe->bezeichnung}</strong>{$kurzbzLine}
</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$abgabedatumFormatted}</td>
</tr>";
if(!$betreuerArr) {
$this->_ci->logInfo('Could not load Betreuer PersonID: "'.$person_id.'".');
continue;
}
$abgabenString .= '</tbody></table>';
$betreuer = $betreuerArr[0];
$email = $betreuer->uid ? $betreuer->uid."@".DOMAIN : $betreuer->private_email;
// in rare cases there are betreuer (often zweitbetreuer) without uid and without private email
if(!$email) {
$this->_ci->logInfo('Could not send Email for Betreuer PersonID: "'.$person_id.'".');
continue;
}
$anrede = $betreuer->anrede;
$anredeFillString = $betreuer->anrede == "Herr" ? "r" : "";
$fullFormattedNameString = $betreuer->first;
// a betreuer can supervise several projektarbeiten, so group the uploads and give each one its
// own section instead of printing one projektarbeit title above uploads of all of them
$abgabenProProjektarbeit = [];
forEach($abgaben as $abgabe) {
$abgabenProProjektarbeit[$abgabe->projektarbeit_id][] = $abgabe;
}
// start the container
$abgabenString = '<div style="font-family: Arial, sans-serif; color: #333;">';
forEach($abgabenProProjektarbeit as $projektarbeit_id => $projektarbeitAbgaben) {
// sorting $projektarbeitAbgaben array by datum
usort($projektarbeitAbgaben, function ($a, $b) {
return strtotime($a->datum) <=> strtotime($b->datum);
});
// format the student name
$s = $projektarbeitAbgaben[0];
$nameParts = [];
if (!empty($s->titelpre)) $nameParts[] = $s->titelpre;
$nameParts[] = $s->vorname;
$nameParts[] = $s->nachname;
if (!empty($s->titelpost)) $nameParts[] = $s->titelpost;
$studentFullName = implode(' ', $nameParts);
$projektarbeit_titel = $s->titel ?? 'Kein Titel vergeben';
// project header section
$abgabenString .= "
<div style='margin-top: 25px; padding: 12px; background-color: #f8f9fa; border-left: 4px solid #007bff; border-bottom: 1px solid #eee;'>
<strong style='font-size: 16px; color: #0056b3;'>Projekt: {$projektarbeit_titel}</strong><br/>
<div style='margin-top: 5px; font-size: 14px;'>
<strong>Studierende/r:</strong> {$studentFullName}
</div>
<span style='color: #666; font-size: 12px;'>
ID: {$projektarbeit_id} | Rolle: {$s->betreuerart_kurzbz} |
Stg: {$s->stgtyp}{$s->stgkz} ({$s->studiensemester_kurzbz})
</span>
</div>";
// start table
$abgabenString .= '
<table style="width: 100%; border-collapse: collapse; margin-bottom: 25px;">
<thead>
<tr style="background-color: #eee; text-align: left;">
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 20%;">Zieldatum</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px;">Bezeichnung</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 20%;">Abgabedatum</th>
</tr>
</thead>
<tbody>';
foreach ($projektarbeitAbgaben as $abgabe) {
// format dates inline
$dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y');
$abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y');
// handle the optional Kurzbezeichnung
$kurzbzLine = !empty($abgabe->kurzbz) ? "<br/><small style='color: #666; font-style: italic;'>{$abgabe->kurzbz}</small>" : "";
$abgabenString .= "
<tr>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$dateEmailFormatted}</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px;'>
<strong>{$abgabe->bezeichnung}</strong>{$kurzbzLine}
</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$abgabedatumFormatted}</td>
</tr>";
}
$abgabenString .= '</tbody></table>';
}
// close container
$abgabenString .= '</div>';
// the template prints one projektarbeit title, which only holds when the mail covers a single one
$paTitel = count($abgabenProProjektarbeit) === 1
? ($abgaben[0]->titel ?? 'Kein Titel vergeben')
: $this->p->t('abgabetool', 'c4mehrereProjektarbeiten');
$path = $this->_ci->config->item('URL_MITARBEITER');
$url = CIS_ROOT.$path;
@@ -783,28 +874,17 @@ class AbgabetoolJob extends JOB_Controller
'anrede' => $anrede,
'anredeFillString' => $anredeFillString,
'fullFormattedNameString' => $fullFormattedNameString,
'paTitel' => $projektarbeit_titel,
'paTitel' => $paTitel,
'abgabenString' => $abgabenString,
'linkAbgabetool' => $url
);
$result = $this->_ci->ProjektbetreuerModel->getBetreuerOfProjektarbeit($abgaben[0]->projektarbeit_id, $abgaben[0]->betreuerart_kurzbz);
$data = getData($result)[0];
$email = $data->uid ? $data->uid."@".DOMAIN : $data->private_email;
// in rare cases there are betreuer (often zweitbetreuer) without uid and without private email
if(!$email) {
$this->_ci->logInfo('Could not send Email for Betreuer PersonID: "'.$data->person_id.'".');
continue;
}
// send email with bundled info
sendSanchoMail(
'PaabgabeUpdatesBetSM',
$body_fields,
$email,
$this->p->t('abgabetool', 'changedAbgabeterminev2')
$this->p->t('abgabetool', 'c4newUploadsNotification')
);
$count++;
+1 -1
View File
@@ -125,7 +125,7 @@ class AntragJob extends JOB_Controller
$stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz;
}
$result = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id);
$result = $this->StudierendenantragModel->getStgAndDetails($antrag->studierendenantrag_id);
if (isError($result))
{
$this->logError(getError($result));
@@ -803,7 +803,7 @@ class ReihungstestJob extends JOB_Controller
{
if (!isset($studiensemester) || isEmptyString($studiensemester))
{
$this->logError("Studiensemster not passed as parameter");
$this->logError("Studiensemester not passed as parameter");
return;
}
+110
View File
@@ -0,0 +1,110 @@
<?php
if (!defined("BASEPATH")) exit("No direct script access allowed");
use \DateTime as DateTime;
class TagJob extends JOB_Controller
{
/**
* API constructor
*/
public function __construct()
{
parent::__construct();
// Configs
$this->load->config('stv');
// Library
$this->load->library('TagLib');
// Load Models
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('system/Notiztyp_model', 'NotiztypModel');
$this->loadPhrases([
'lehre'
]);
}
public function rebuildAutomatedTags()
{
$automatedTagsRes = $this->NotiztypModel->loadWhere(array('automatisiert' => true, 'taglib IS NOT NULL' => null));
$automatedTags = hasData($automatedTagsRes) ? getData($automatedTagsRes) : [];
$result = $this->StudiensemesterModel->getAktOrNextSemester();
if (isError($result))
{
$this->logInfo('Start Job rebuild Automated Tags');
$this->logError('Error occurred during retrieving studiensemester');
return $this->logInfo('End Job rebuild Automated Tags');
}
if (empty($result->retval) || !isset($result->retval[0])) {
$this->logInfo('Start Job rebuild Automated Tags');
$this->logError('No Studiensemester found');
return $this->logInfo('End Job rebuild Automated Tags');
}
$studiensemester_kurzbz = $result->retval[0]->studiensemester_kurzbz ?? null;
$params = array(
'studiensemester_kurzbz' => $studiensemester_kurzbz
);
$this->logInfo('Start Job rebuild Automated Tags ' . $studiensemester_kurzbz);
foreach($automatedTags as $autoTag)
{
// getPath: must not be lost
$filePath = APPPATH . 'libraries/' . $autoTag->taglib . '.php'; // APPPATH = application/
if(file_exists($filePath)) {
require_once($filePath);
} else {
$this->logInfo("File not found: " . $filePath);
continue;
}
$kurz_bz = $autoTag->typ_kurzbz;
// className without PATH (basename)
$className = basename($autoTag->taglib);
$obj = new $className();
$outputArray = $obj->getZuordnungIds($params);
$typeId = $outputArray->typeId;
$paramsTag = array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'kurzbz' => $kurz_bz,
'data' => $outputArray->data,
'typeId' => $typeId
);
$result = $this->taglib->updateAutomatedTags($paramsTag);
if (isError($result)) {
$this->logError('Error occurred during updateAutomatedTags ' . $kurz_bz);
continue;
}
$data = is_array($result) ? $result['retval'] : $result->retval;
//SUMMARY
$this->logInfo("Tag " . $result->retval['input']['tag'] . " | type_id " . $typeId . " --"
. " Count Recycled: " . $result->retval['summary']['recycled']
. " Count Added: ". $result->retval['summary']['added']
. " Count Deleted: ". $result->retval['summary']['deleted']);
//DETAILS
if($result->retval['results']['newTags'])
$this->logInfo("Tag " . $result->retval['input']['tag'] . "New tag(s): " . implode(', ', $result->retval['results']['newTags']));
if($result->retval['results']['deletedTagsIds'])
$this->logInfo("Tag " . $result->retval['input']['tag'] . "Deleted tags(s: " . implode(', ', $result->retval['results']['deletedTagsIds']));
if ($result->retval['results']['retaggedIds'])
$this->logInfo("Tag " . $result->retval['input']['tag'] . "Recycled tag(s): " . implode(', ', $result->retval['results']['retaggedIds']));
}
$this->logInfo( "End Job rebuild Automated Tags");
}
}
@@ -0,0 +1,60 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller generates javascript from snippets for tabulator columns
*/
class Tabulatorcolumns extends Auth_Controller
{
public function __construct()
{
parent::__construct([
'stv' => ['admin:r', 'assistenz:r'],
'lvverwaltung' => ['admin:r', 'assistenz:r']
]);
}
/**
* Render tabulator columns for config
*
* @param string $config
*
* @return void
*/
public function _remap($config)
{
$this->load->config($config);
$list_columns = $this->config->item('list_columns') ?: [];
$snippets = [
'jssnippets/tabulatorcolumns/' . $config . '.js'
];
foreach ($list_columns as $col) {
$snippets[] = $col['js'];
}
$this->output->set_content_type('application/javascript');
$this->load->view('jssnippets/tabulatorcolumns.js', [
'snippets' => $snippets
]);
}
}
@@ -25,7 +25,8 @@ class Studierendenantrag extends FHC_Controller
// Load language phrases
$this->loadPhrases([
'studierendenantrag'
'studierendenantrag',
'ui'
]);
$this->load->config('studierendenantrag');
+15 -3
View File
@@ -198,7 +198,19 @@ class Gradelist extends Auth_Controller
if (!isset($row_noten->found))
{
$result_lv = $this->LehrveranstaltungModel->load($row_noten->lehrveranstaltung_id);
$result_stg = $this->StudiengangModel->load($result_lv->retval[0]->studiengang_kz);
$studiengang_kz = null;
if (!empty($result_lv->retval) && isset($result_lv->retval[0]) && isset($result_lv->retval[0]->studiengang_kz))
{
$result_stg = $this->StudiengangModel->load($result_lv->retval[0]->studiengang_kz);
if (!empty($result_stg->retval) && isset($result_stg->retval[0]) && is_object($result_stg->retval[0]) && isset($result_stg->retval[0]->kurzbzlang))
{
$studiengang_kz = $result_stg->retval[0]->kurzbzlang;
}
}
$courses['semester'][$row_noten->studiensemester_kurzbz]['lvs_nonstpl'][] = array(
'lehrveranstaltung_id' => $row_noten->lehrveranstaltung_id,
'lehrtyp_kurzbz' => $result_lv->retval[0]->lehrtyp_kurzbz,
@@ -212,8 +224,8 @@ class Gradelist extends Auth_Controller
'semester' => $result_lv->retval[0]->semester,
'note' => $row_noten->note,
'datum' => $row_noten->benotungsdatum,
'zugeordnet' => true,
'studiengang_kurzbz' => $result_stg->retval[0]->kurzbzlang
'studiengang_kurzbz' => $studiengang_kz,
'zugeordnet' => true
);
if(!isset($courses['semester'][$row_noten->studiensemester_kurzbz]['data']['ectssumme_nonstpl']))
$courses['semester'][$row_noten->studiensemester_kurzbz]['data']['ectssumme_nonstpl'] = 0;
+110 -9
View File
@@ -7,7 +7,7 @@ class Tag_Controller extends FHCAPI_Controller
{
private $_uid;
const BERECHTIGUNG_KURZBZ = 'admin:rw';
const BERECHTIGUNG_KURZBZ = ['admin:rw'];
public function __construct($permissions)
{
@@ -15,10 +15,11 @@ class Tag_Controller extends FHCAPI_Controller
'getTag' => self::BERECHTIGUNG_KURZBZ,
'getTags' => self::BERECHTIGUNG_KURZBZ,
'addTag' => self::BERECHTIGUNG_KURZBZ,
'updateTag' => self::BERECHTIGUNG_KURZBZ,
'doneTag' => self::BERECHTIGUNG_KURZBZ,
'deleteTag' => self::BERECHTIGUNG_KURZBZ,
'getAllTags' => self::BERECHTIGUNG_KURZBZ,
'rebuildTagsForTypeId' => self::BERECHTIGUNG_KURZBZ,
];
$merged_permissions = array_merge($default_permissions, $permissions);
@@ -26,6 +27,10 @@ class Tag_Controller extends FHCAPI_Controller
parent::__construct($merged_permissions);
$this->_setAuthUID();
// Library
$this->load->library('TagLib');
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('system/Notiztyp_model', 'NotiztypModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
@@ -38,6 +43,8 @@ class Tag_Controller extends FHCAPI_Controller
public function getTag($readonly_tags = null)
{
$language = $this->_getLanguageIndex();
$index_bezeichnung_mehrsprachig = $language - 1;
$id = $this->input->get('id');
if (is_array($readonly_tags) && !isEmptyArray($readonly_tags))
@@ -62,14 +69,18 @@ class Tag_Controller extends FHCAPI_Controller
$this->NotizModel->addSelect(
"tbl_notiz.titel,
tbl_notiz.text,
array_to_json(bezeichnung_mehrsprachig::varchar[])->>". $language. " as bezeichnung,
array_to_json(bezeichnung_mehrsprachig::varchar[])->>". $index_bezeichnung_mehrsprachig . " as bezeichnung,
tbl_notiz.notiz_id,
tbl_notiz_typ.style,
tbl_notiz_typ.automatisiert,
tbl_notiz_typ.prioritaet,
tbl_notiz.erledigt as done,
tbl_notiz.insertamum,
tbl_notiz.updateamum,
(verfasserperson.vorname || ' ' || verfasserperson.nachname || ' ' || '(' || verfasserbenutzer.uid || ')') as verfasser,
(bearbeiterperson.vorname || ' ' || bearbeiterperson.nachname || ' ' || '(' || bearbeiterbenutzer.uid || ')') as bearbeiter
(bearbeiterperson.vorname || ' ' || bearbeiterperson.nachname || ' ' || '(' || bearbeiterbenutzer.uid || ')') as bearbeiter,
tbl_notiz.start,
tbl_notiz.ende
"
);
$this->NotizModel->addJoin('public.tbl_notiz_typ', 'public.tbl_notiz.typ = public.tbl_notiz_typ.typ_kurzbz');
@@ -82,18 +93,24 @@ class Tag_Controller extends FHCAPI_Controller
$notiz = $this->NotizModel->loadWhere(array('notiz_id' => $id));
$this->terminateWithSuccess(hasData($notiz) ? getData($notiz)[0] : array());
}
public function getTags($tags = null)
{
$language = $this->_getLanguageIndex();
$index_bezeichnung_mehrsprachig = $language - 1;
$this->NotiztypModel->addSelect(
'typ_kurzbz as tag_typ_kurzbz,
array_to_json(bezeichnung_mehrsprachig::varchar[])->>0 as bezeichnung,
"typ_kurzbz as tag_typ_kurzbz,
array_to_json(bezeichnung_mehrsprachig::varchar[])->>". $index_bezeichnung_mehrsprachig . " as bezeichnung,
style,
beschreibung,
tag
'
tag,
automatisiert,
prioritaet
"
);
$this->NotiztypModel->addOrder('prioritaet');
@@ -271,6 +288,90 @@ class Tag_Controller extends FHCAPI_Controller
$this->terminateWithSuccess($deleteNotiz);
}
public function getAllTags($readonly_tags = false)
{
$language = $this->_getLanguageIndex();
$index_bezeichnung_mehrsprachig = $language - 1;
$prestudent_id = $this->input->get('prestudent_id');
if (is_array($readonly_tags) && !isEmptyArray($readonly_tags))
{
$readonly_tags = $this->_filterTag($readonly_tags, true);
foreach ($readonly_tags as $key => $tag)
{
$readonly_tags[$key] = $this->NotizModel->db->escape($tag);
}
$tags = '(' . implode(',', $readonly_tags) . ')';
$this->NotizModel->addSelect("
CASE
WHEN tbl_notiz_typ.typ_kurzbz IN $tags
THEN TRUE
ELSE FALSE
END as readonly
");
}
$this->NotizModel->addSelect(
"tbl_notiz.titel,
tbl_notiz.text,
array_to_json(bezeichnung_mehrsprachig::varchar[])->>". $index_bezeichnung_mehrsprachig . " as bezeichnung,
tbl_notiz.notiz_id,
tbl_notiz_typ.style,
tbl_notiz_typ.automatisiert,
tbl_notiz_typ.prioritaet,
tbl_notiz.erledigt as done,
tbl_notiz.insertamum,
tbl_notiz.updateamum,
(verfasserperson.vorname || ' ' || verfasserperson.nachname || ' ' || '(' || verfasserbenutzer.uid || ')') as verfasser,
(bearbeiterperson.vorname || ' ' || bearbeiterperson.nachname || ' ' || '(' || bearbeiterbenutzer.uid || ')') as bearbeiter,
tbl_notiz.start,
tbl_notiz.ende
"
);
$this->NotizModel->addJoin('public.tbl_notiz_typ', 'public.tbl_notiz.typ = public.tbl_notiz_typ.typ_kurzbz');
$this->NotizModel->addJoin('public.tbl_benutzer verfasserbenutzer', 'tbl_notiz.verfasser_uid = verfasserbenutzer.uid', 'LEFT');
$this->NotizModel->addJoin('public.tbl_person verfasserperson', 'verfasserbenutzer.person_id = verfasserperson.person_id', 'LEFT');
$this->NotizModel->addJoin('public.tbl_benutzer bearbeiterbenutzer', 'tbl_notiz.bearbeiter_uid = bearbeiterbenutzer.uid', 'LEFT');
$this->NotizModel->addJoin('public.tbl_person bearbeiterperson', 'bearbeiterbenutzer.person_id = bearbeiterperson.person_id', 'LEFT');
$this->NotizModel->addJoin('public.tbl_notizzuordnung notizzuordnung', 'tbl_notiz.notiz_id = notizzuordnung.notiz_id');
$this->NotizModel->addOrder('done');
$this->NotizModel->addOrder('tbl_notiz_typ.prioritaet');
$notiz = $this->NotizModel->loadWhere(array('prestudent_id' => $prestudent_id));
$this->terminateWithSuccess(hasData($notiz) ? getData($notiz) : array());
}
public function rebuildTagsForTypeId()
{
$ids = $this->input->post('ids');
$typeId = $this->input->post('typeId');
$semester = $this->input->post('sem');
$idsSuccess = [];
$idsError = [];
$outputResult = [];
foreach ($ids as $id)
{
$result = $this->taglib->rebuildTagsForTypeId($typeId, $id, $semester);
if (isError($result))
$idsError[] = $id;
else
$idsSuccess[] = $id;
$outputResult[] = $result;
}
$this->terminateWithSuccess([$outputResult, $idsSuccess, $idsError]);
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
@@ -311,4 +412,4 @@ class Tag_Controller extends FHCAPI_Controller
));
}
}
}
+188
View File
@@ -0,0 +1,188 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Helper function to generate the default documentslist config for the
* grades tab.
*
* The resulting array consists of elements which are associative arrays
* that can have the following entries:
* title (required) on the first level this can be HTML code.
* permissioncheck (optional) an URL to an FHCAPI endpoint which returns
* true or false.
* link (optional) an URL that will be called if "action" and
* "children" are not defined.
* action (optional) an associative array that describes an
* POST action that will be called if "children" is
* not defined.
* It can have the following entries:
* - url (required) an URL to an FHCAPI endpoint.
* - post (optional) an associative array with the POST data to
* be sent.
* - response (optional) a string that will be displayed on success.
* children (optional) an array of child elements
*
* All strings that start with { and end with } in the URLs and the
* actions post parameter will be replaced with the corresponding
* attribute of the current dataset (e.G: {uid} will be replaced with the
* uid of the current dataset)
*
* @return array
*/
function gradesDocumentsList()
{
$ci =& get_instance();
$ci->load->library('PhrasesLib', array('stv'), 'p');
$permissioncheck = site_url("api/frontend/v1/documents/permissionAlternativeFormat/{studiengang_kz}");
$title_ger = $ci->p->t("global", "deutsch");
$title_eng = $ci->p->t("global", "englisch");
$title_ff = $ci->p->t("stv", "document_certificate");
$title_lv = $ci->p->t("stv", "document_coursecertificate");
$link_ff = "documents/export/" .
"zertifikat.rdf.php/" .
"Zertifikat" .
"?stg_kz={studiengang_kz_lv}" .
"&uid={uid}" .
"&ss={studiensemester_kurzbz}" .
"&lvid={lehrveranstaltung_id}";
$link_lv_ger = "documents/export/" .
"lehrveranstaltungszeugnis.rdf.php/" .
"LVZeugnis" .
"?stg_kz={studiengang_kz}" .
"&uid={uid}" .
"&ss={studiensemester_kurzbz}" .
"&lvid={lehrveranstaltung_id}";
$link_lv_eng = "documents/export/" .
"lehrveranstaltungszeugnis.rdf.php/" .
"LVZeugnisEng" .
"?stg_kz={studiengang_kz}" .
"&uid={uid}" .
"&ss={studiensemester_kurzbz}" .
"&lvid={lehrveranstaltung_id}";
$archive_url = "api/frontend/v1/documents/archiveSigned";
$archive_response = $ci->p->t("stv", "document_signed_and_archived");
$archive_post_ff = [
"xml" => "zertifikat.rdf.php",
"xsl" => "Zertifikat",
"stg_kz" => "{studiengang_kz_lv}",
"uid" => "{uid}",
"ss" => "{studiensemester_kurzbz}",
"lvid" => "{lehrveranstaltung_id}"
];
$archive_post_lv_ger = [
"xml" => "lehrveranstaltungszeugnis.rdf.php",
"xsl" => "LVZeugnis",
"stg_kz" => "{studiengang_kz}",
"uid" => "{uid}",
"ss" => "{studiensemester_kurzbz}",
"lvid" => "{lehrveranstaltung_id}"
];
$archive_post_lv_eng = [
"xml" => "lehrveranstaltungszeugnis.rdf.php",
"xsl" => "LVZeugnisEng",
"stg_kz" => "{studiengang_kz}",
"uid" => "{uid}",
"ss" => "{studiensemester_kurzbz}",
"lvid" => "{lehrveranstaltung_id}"
];
$list = [
[
'title' => '<i class="fa fa-download" title="' . $ci->p->t("stv", "document_download") . '"></i>',
'children' => [
[
'title' => $title_ff,
'link' => site_url($link_ff)
],
[
'title' => $title_lv,
'children' => [
[
'title' => $title_ger,
'link' => site_url($link_lv_ger),
'children' => [
[
'title' => 'PDF',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_ger)
],
[
'title' => 'DOC',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_ger . "&output=doc")
],
[
'title' => 'ODT',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_ger . "&output=odt")
]
]
],
[
'title' => $title_eng,
'link' => site_url($link_lv_eng),
'children' => [
[
'title' => 'PDF',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_eng)
],
[
'title' => 'DOC',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_eng . "&output=doc")
],
[
'title' => 'ODT',
'permissioncheck' => $permissioncheck,
'link' => site_url($link_lv_eng . "&output=odt")
]
]
]
]
]
]
],
[
'title' => '<i class="fas fa-archive" title="' . $ci->p->t("stv", "document_archive") . '"></i>',
'children' => [
[
'title' => $title_ff,
'action' => [
'url' => site_url($archive_url),
'post' => $archive_post_ff,
'response' => $archive_response
]
],
[
'title' => $title_lv,
'children' => [
[
'title' => $title_ger,
'action' => [
'url' => site_url($archive_url),
'post' => $archive_post_lv_ger,
'response' => $archive_response
]
],
[
'title' => $title_eng,
'action' => [
'url' => site_url($archive_url),
'post' => $archive_post_lv_eng,
'response' => $archive_response
]
]
]
]
]
]
];
return $list;
}
+24 -1
View File
@@ -111,7 +111,8 @@ function generateJSDataStorageObject($indexPage, $calledPath, $calledMethod)
'theme' => [
'name'=>$ci->config->item('theme_name'),
'modes'=>$ci->config->item('theme_modes'),
]
],
'domain' => DOMAIN
);
$toPrint = "\n";
@@ -270,6 +271,28 @@ function absoluteJsImportUrl($relurl)
return $url;
}
/*
* Generate Css File Include if Extension contains file
*
* @param $relativeFilePath path relative to Extension public/css dir
*/
function generateCSSsIncludeIfExtensionCssExists($relativeFilePath)
{
$fsiterator = new FilesystemIterator(FHCPATH . 'application/extensions');
foreach ($fsiterator as $fsitem)
{
if(preg_match('/^FHC-Core-/', $fsitem->getBasename()))
{
$extensionfile = 'public/extensions/' . $fsitem->getBasename()
. '/css/' . $relativeFilePath;
if(is_readable(FHCPATH . $extensionfile))
{
generateCSSsInclude($extensionfile);
}
}
}
}
/*
* Manipulate CI views includes Array to load
* - public/js/FhcApps.js via customJSs and
+178 -79
View File
@@ -17,7 +17,12 @@ class LektorLib
$this->_ci->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$this->_ci->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->_ci->load->model('person/Benutzer_model', 'BenutzerModel');
$this->_ci->load->model('ressource/Zeitsperre_model', 'ZeitsperreModel');
$this->_ci->load->model('ressource/Reservierung_model', 'ReservierungModel');
$this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
$this->_ci->load->library('PhrasesLib', array('lehre'));
$this->_ci->load->library('VariableLib', ['uid' => getAuthUID()]);
}
public function addLektorToLehreinheit($lehreinheit_id, $mitarbeiter_uid)
@@ -78,10 +83,13 @@ class LektorLib
public function updateLektorFromLehreinheit($lehreinheit_id, $mitarbeiter_uid, $new_data)
{
$old_uid = $mitarbeiter_uid;
$new_uid = isset($new_data['mitarbeiter_uid']) ? $new_data['mitarbeiter_uid'] : $mitarbeiter_uid;
$this->_ci->LehreinheitmitarbeiterModel->addSelect('lehre.tbl_lehreinheitmitarbeiter.*, lehre.tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.studiengang_kz');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id');
$lehreinheit_result = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
$lehreinheit_result = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $old_uid));
if (isError($lehreinheit_result)) return $lehreinheit_result;
@@ -89,27 +97,47 @@ class LektorLib
$lehreinheit = getData($lehreinheit_result)[0];
$semesterstunden_alt = $lehreinheit->semesterstunden;
$semesterstunden_neu = isset($new_data['semesterstunden']) ? $new_data['semesterstunden'] : $semesterstunden_alt;
$bismelden_neu = isset($new_data['bismelden']) ? $new_data['bismelden'] : $lehreinheit->bismelden;
$neue_stunden_eingerechnet = (bool)$bismelden_neu;
$alte_stunden_eingerechnet = (bool)$lehreinheit->bismelden;
$stundenplan_update = false;
//TODO kollision check, wird vorerst nicht implementiert -> nur über das FAS möglich
if (isset($new_data['mitarbeiter_uid']) && $new_data['mitarbeiter_uid'] !== $mitarbeiter_uid)
if ($old_uid !== $new_uid)
{
$this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
$this->_ci->StundenplandevModel->addGroupBy('stundenplandev_id');
$this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid');
$this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid');
$verplant = $this->_ci->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
if (hasData($verplant))
return error($this->_ci->phraseslib->t("lehre", "lektorbereitsverplant"));
$lehreinheit_data = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('mitarbeiter_uid' => $new_data['mitarbeiter_uid'], 'lehreinheit_id' => $lehreinheit_id));
$lehreinheit_data = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('mitarbeiter_uid' => $new_uid, 'lehreinheit_id' => $lehreinheit_id));
if (hasData($lehreinheit_data))
return error($this->_ci->phraseslib->t("lehre", "bereitzugeteilt"));
$this->_ci->StundenplandevModel->addGroupBy('stundenplandev_id');
$this->_ci->StundenplandevModel->addGroupBy('mitarbeiter_uid');
$verplant = $this->_ci->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $old_uid));
if (hasData($verplant))
{
$kollision = $this->hasKollision(getData($verplant), $new_uid);
$ignore_kollision = $this->_ci->variablelib->getVar('ignore_kollision');
if ($kollision === false || $ignore_kollision == 'true')
{
$stundenplan_update = true;
}
else if (is_array($kollision))
{
return error( "Änderung fehlgeschlagen! Die Änderung des Lektors führt zu ".count($kollision)." Kollision(en) im LV-Plan. Deaktivieren Sie die Kollisionspruefung oder wenden Sie sich an die LV-Planung!\n zB. $kollision[0]");
}
else
{
return error($kollision);
}
}
}
$warning = '';
if (isset($new_data['semesterstunden']))
if (($semesterstunden_neu !== '' && $semesterstunden_alt !== '') && (($semesterstunden_neu > $semesterstunden_alt) || $neue_stunden_eingerechnet))
{
$studiengang_result = $this->_ci->StudiengangModel->loadWhere(array('studiengang_kz' => $lehreinheit->studiengang_kz));
if (isError($studiengang_result)) return $studiengang_result;
@@ -120,7 +148,7 @@ class LektorLib
if (isError($studiensemester_result)) return $studiensemester_result;
$studiensemester = getData($studiensemester_result)[0];
$echter_dv_result = $this->_ci->DienstverhaeltnisModel->existsDienstverhaeltnis($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'echterdv');
$echter_dv_result = $this->_ci->DienstverhaeltnisModel->existsDienstverhaeltnis($new_uid, $studiensemester->start, $studiensemester->ende, 'echterdv');
$echter_dv = false;
@@ -129,83 +157,81 @@ class LektorLib
$echter_dv = true;
}
$neue_stunden_eingerechnet = isset($new_data['bismelden']) ? $new_data['bismelden'] : $lehreinheit->bismelden;
$alte_stunden_eingerechnet = $lehreinheit->bismelden;
$stundengrenze_result = $this->_ci->OrganisationseinheitModel->getStundengrenze($studiengang->oe_kurzbz, $echter_dv);
if (isError($stundengrenze_result)) return $stundengrenze_result;
if (($new_data['semesterstunden'] > $lehreinheit->semesterstunden) || $neue_stunden_eingerechnet)
$stundengrenze = getData($stundengrenze_result)[0];
$oe_result = $this->_ci->OrganisationseinheitModel->getChilds($stundengrenze->oe_kurzbz);
$oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array();
$semesterstunden_alt_sql = is_null($semesterstunden_alt) ? 0 : $semesterstunden_alt;
$semesterstunden_neu_sql = is_null($semesterstunden_neu) ? 0 : $semesterstunden_neu;
if ($alte_stunden_eingerechnet && $neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($semesterstunden_alt_sql) + {$this->_ci->LehreinheitmitarbeiterModel->db->escape($semesterstunden_neu_sql)}) as summe");
else if ($alte_stunden_eingerechnet && !$neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($semesterstunden_alt_sql)) as summe");
else if (!$alte_stunden_eingerechnet && $neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) + ({$this->_ci->LehreinheitmitarbeiterModel->db->escape($semesterstunden_neu_sql)})) as summe");
else if (!$alte_stunden_eingerechnet && !$neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden)) as summe");
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', $new_uid);
$this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $lehreinheit->studiensemester_kurzbz);
$this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true);
$this->_ci->LehreinheitmitarbeiterModel->db->where('lower(mitarbeiter_uid) NOT LIKE', '_dummy%');
if (count($oe_array) > 0)
{
$stundengrenze_result = $this->_ci->OrganisationseinheitModel->getStundengrenze($studiengang->oe_kurzbz, $echter_dv);
if (isError($stundengrenze_result)) return $stundengrenze_result;
$stundengrenze = getData($stundengrenze_result)[0];
$oe_result = $this->_ci->OrganisationseinheitModel->getChilds($stundengrenze->oe_kurzbz);
$oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array('');
if ($alte_stunden_eingerechnet && $neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($lehreinheit->semesterstunden) + {$this->_ci->LehreinheitmitarbeiterModel->db->escape($new_data['semesterstunden'])}) as summe");
else if ($alte_stunden_eingerechnet && !$neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) - ($lehreinheit->semesterstunden)) as summe");
else if (!$alte_stunden_eingerechnet && $neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden) + ({$this->_ci->LehreinheitmitarbeiterModel->db->escape($new_data['semesterstunden'])})) as summe");
else if (!$alte_stunden_eingerechnet && !$neue_stunden_eingerechnet)
$this->_ci->LehreinheitmitarbeiterModel->addSelect("(SUM(tbl_lehreinheitmitarbeiter.semesterstunden)) as summe");
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehreinheit', 'lehreinheit_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id');
$this->_ci->LehreinheitmitarbeiterModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$this->_ci->LehreinheitmitarbeiterModel->db->where('mitarbeiter_uid', (isset($new_data['mitarbeiter_uid']) ? $new_data['mitarbeiter_uid'] : $mitarbeiter_uid));
$this->_ci->LehreinheitmitarbeiterModel->db->where('studiensemester_kurzbz', $lehreinheit->studiensemester_kurzbz);
$this->_ci->LehreinheitmitarbeiterModel->db->where('bismelden', true);
$this->_ci->LehreinheitmitarbeiterModel->db->where('lower(mitarbeiter_uid) NOT LIKE', '_dummy%');
$this->_ci->LehreinheitmitarbeiterModel->db->where_in('tbl_studiengang.oe_kurzbz', $oe_array);
}
if(defined('FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE')
&& is_array(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE)
&& count(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) > 0)
{
$this->_ci->LehreinheitmitarbeiterModel->db->where_not_in('tbl_studiengang.oe_kurzbz', FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE);
}
if(defined('FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE')
&& is_array(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE)
&& count(FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE) > 0)
$summe_result = $this->_ci->LehreinheitmitarbeiterModel->load();
if (isError($summe_result)) return $summe_result;
if (!hasData($summe_result)) return error('Fehler beim Ermitteln der Gesamtstunden');
$summe = getData($summe_result)[0]->summe;
if ($summe > $stundengrenze->stunden)
{
if (!$echter_dv && (!$this->_ci->permissionlib->isBerechtigt('admin')))
{
$this->_ci->LehreinheitmitarbeiterModel->db->where_not_in('tbl_studiengang.oe_kurzbz', FAS_LV_LEKTORINNENZUTEILUNG_STUNDEN_IGNORE_OE);
if (!$this->LehrauftragAufFirma($new_uid))
return error("ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden NICHT gespeichert!\n\n");
}
else
{
$warning .= "ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden gespeichert!\n\n";
}
$summe_result = $this->_ci->LehreinheitmitarbeiterModel->load();
$stunden_limit_result = $this->getStundenInstitut($new_uid, $lehreinheit->studiensemester_kurzbz, $oe_array);
if (isError($summe_result)) return $summe_result;
if (!hasData($summe_result)) return error('Fehler beim Ermitteln der Gesamtstunden');
$summe = getData($summe_result)[0]->summe;
if ($summe > $stundengrenze->stunden)
if (hasData($stunden_limit_result))
{
if (!$echter_dv && (!$this->_ci->permissionlib->isBerechtigt('admin')))
$stunden_limit_array = getData($stunden_limit_result);
foreach ($stunden_limit_array as $stunden_limit)
{
if (!$this->LehrauftragAufFirma(isset($formData['mitarbeiter_uid']) ? $formData['mitarbeiter_uid'] : $mitarbeiter_uid))
return error("ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden NICHT gespeichert!\n\n");
}
else
{
$warning .= "ACHTUNG: Die maximal erlaubte Semesterstundenanzahl des Lektors von $summe Stunden ($stundengrenze->stunden) wurde ueberschritten!\nDaten wurden gespeichert!\n\n";
}
$stunden_limit_result = $this->getStundenInstitut($mitarbeiter_uid, $lehreinheit->studiensemester_kurzbz, $oe_array);
if (hasData($stunden_limit_result))
{
$stunden_limit_array = getData($stunden_limit_result);
foreach ($stunden_limit_array as $stunden_limit)
{
$warning .= $stunden_limit->summe . ' Stunden ' . $stunden_limit->bezeichnung . "\n";
}
$warning .= $stunden_limit->summe . ' Stunden ' . $stunden_limit->bezeichnung . "\n";
}
}
}
}
$benutzer_result = $this->_ci->BenutzerModel->load(array(isset($formData['mitarbeiter_uid']) ? $formData['mitarbeiter_uid'] : $mitarbeiter_uid));
$benutzer_result = $this->_ci->BenutzerModel->load(array($new_uid));
if (isError($benutzer_result)) return $benutzer_result;
@@ -227,12 +253,23 @@ class LektorLib
'bismelden'
);
$nullable_fields = array('stundensatz', 'semesterstunden', 'planstunden');
$updateData = array();
foreach ($updatableFields as $field)
{
$value = isset($new_data[$field]) ? $new_data[$field] : null;
if (!array_key_exists($field, $new_data))
{
continue;
}
if ($value !== null)
$value = $new_data[$field];
if (in_array($field, $nullable_fields))
{
$updateData[$field] = $value;
}
elseif ($value !== null)
{
$updateData[$field] = $value;
}
@@ -240,10 +277,24 @@ class LektorLib
$updateData['updatevon'] = getAuthUID();
$updateData['updateamum'] = date('Y-m-d H:i:s');
$result = $this->_ci->LehreinheitmitarbeiterModel->update(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid), $updateData);
$result = $this->_ci->LehreinheitmitarbeiterModel->update(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $old_uid), $updateData);
if (isError($result)) return $result;
if ($stundenplan_update)
{
$update_result = $this->_ci->StundenplandevModel->update([
'lehreinheit_id' => $lehreinheit_id,
'mitarbeiter_uid' => $old_uid,
], [
'mitarbeiter_uid' => $new_uid,
'updateamum' => date('Y-m-d H:i:s'),
'updatevon' => getAuthUID()
]);
if (isError($update_result)) return $update_result;
}
if ($warning !== '') return success(['warning' => $warning]);
return success('Erfolgreich geupdated');
@@ -347,4 +398,52 @@ class LektorLib
$this->_ci->LehreinheitmitarbeiterModel->addGroupBy('tbl_studiengang.bezeichnung');
return $this->_ci->LehreinheitmitarbeiterModel->load();
}
private function hasKollision($stunden, $mitarbeiter)
{
$kollision = array();
$ignore_zeitsperre = $this->_ci->variablelib->getVar('ignore_zeitsperre');
$ignore_reservierung = $this->_ci->variablelib->getVar('ignore_reservierung');
foreach ($stunden as $stunde)
{
$stundenplan_result = $this->_ci->StundenplandevModel->lektorHasStundenplandevEintrag($mitarbeiter, $stunde->datum, $stunde->stunde);
if (isError($stundenplan_result))
return $stundenplan_result;
if (hasData($stundenplan_result))
{
$stundenplan_result = getData($stundenplan_result)[0];
$kollision[] = "Kollision stundenplandev: $stundenplan_result->stundenplandev_id|$stundenplan_result->lektor|$stundenplan_result->ort_kurzbz|$stundenplan_result->stg_kurzbz-$stundenplan_result->semester$stundenplan_result->verband$stundenplan_result->gruppe$stundenplan_result->gruppe_kurzbz - $stundenplan_result->datum/$stundenplan_result->stunde";
}
else
{
if ($ignore_zeitsperre == 'false' && (!defined('KOLLISIONSFREIE_USER') || !in_array($mitarbeiter, unserialize(KOLLISIONSFREIE_USER))))
{
$zeitsperre_result = $this->_ci->ZeitsperreModel->checkIfZeitsperreExists($mitarbeiter, $stunde->datum, $stunde->stunde);
if (hasData($zeitsperre_result))
{
$zeitsperre_result = getData($zeitsperre_result)[0];
$kollision[] = "Kollision (Zeitsperre): $zeitsperre_result->zeitsperre_id|$zeitsperre_result->mitarbeiter_uid|$zeitsperre_result->zeitsperretyp_kurzbz - $zeitsperre_result->vondatum/$zeitsperre_result->vonstunde|$zeitsperre_result->bisdatum/$zeitsperre_result->bisstunde";
}
}
if ($ignore_reservierung == 'false' && (!defined('KOLLISIONSFREIE_USER') || !in_array($mitarbeiter, unserialize(KOLLISIONSFREIE_USER))))
{
$reservierung_result = $this->_ci->ReservierungModel->lektorHasReservierung($mitarbeiter, $stunde->datum, $stunde->stunde);
if (hasData($reservierung_result))
{
$reservierung_result = getData($reservierung_result)[0];
$kollision[] = "Kollision (Reservierung): $reservierung_result->reservierung_id|$reservierung_result->uid|$reservierung_result->ort_kurzbz|$reservierung_result->stg_kurzbz-$reservierung_result->semester$reservierung_result->verband$reservierung_result->gruppe$reservierung_result->gruppe_kurzbz - $reservierung_result->datum/$reservierung_result->stunde";
}
}
}
}
return isEmptyArray($kollision) ? false : $kollision;
}
}
+22 -3
View File
@@ -80,10 +80,12 @@ class StundenplanLib
if (isError($semester_range))
return $semester_range;
$semester_range = getData($semester_range);
$this->_ci->addMeta('semester_range', $semester_range);
$this->sortStudienSemester($semester_range);
$function_error = $this->applyLoadUeberSemesterHaelfte($semester_range);
$this->_ci->addMeta('nach_apply_semester_range', $semester_range);
if ($function_error)
return $function_error;
@@ -92,13 +94,13 @@ class StundenplanLib
if (isError($benutzer_gruppen))
return $benutzer_gruppen;
$benutzer_gruppen = getData($benutzer_gruppen);
$this->_ci->addMeta('spezialgruppen', $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);
$this->_ci->addMeta('studentlehrvebaende', $student_lehrverband);
$stundenplan_query = $this->_ci->StundenplanModel->getStundenplanQuery(
$start,
$end,
@@ -184,6 +186,21 @@ class StundenplanLib
return success($stundenplan_data);
}
public function getEventsByLE($lehreinheit_id, $start, $end, $stundenplan)
{
$this->_ci =& get_instance();
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
return $this->_ci->StundenplanModel->getStundenplanLE($lehreinheit_id, $start, $end, $stundenplan);
}
public function getEventsByLV($lehrveranstaltung_id, $start, $end, $stundenplan)
{
$this->_ci =& get_instance();
$this->_ci->load->model('ressource/Stundenplan_model', 'StundenplanModel');
return $this->_ci->StundenplanModel->getStundenplanLV($lehrveranstaltung_id, $start, $end, $stundenplan);
}
/**
* Get stundenplan for a room
*
@@ -615,6 +632,7 @@ class StundenplanLib
$result->semester = $item->semester;
$result->verband = $item->verband;
$result->gruppe = $item->gruppe;
$result->studiensemester_kurzbz = $item->studiensemester_kurzbz;
return $result;
},
$lehrverband_query_result);
@@ -784,7 +802,8 @@ class StundenplanLib
$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);
//$semester_range = $this->_ci->StudiensemesterModel->getByDateRange($start_date, $end_date);
$semester_range = $this->_ci->StudiensemesterModel->getContainingOrNearestByDateRange($start_date, $end_date);
if (isError($semester_range))
return $semester_range;
+392
View File
@@ -0,0 +1,392 @@
<?php
/**
* FH-Complete
*
* @package FHC-Helper
* @author FHC-Team
* @copyright Copyright (c) 2026 fhcomplete.net
* @license GPLv3
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
use \stdClass as stdClass;
class TagLib
{
/**
* Object initialization
*/
public function __construct()
{
$this->_ci =& get_instance();
// Configs
$this->_ci->load->config('stv');
// Models
$this->_ci->load->model('person/Notiz_model', 'NotizModel');
$this->_ci->load->model('system/Notiztyp_model', 'NotiztypModel');
$this->_ci->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
$this->_ci->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
// Libraries
$this->_ci->load->library('PermissionLib');
$this->_ci->load->library('PrestudentLib');
$this->batchUser = $this->_ci->config->item('userAutomatedTags');
}
public function updateAutomatedTags($paramsTag)
{
// ---------------------------------
// check params
// ---------------------------------
$required = ['kurzbz', 'data', 'typeId'];
foreach ($required as $key) {
if (!isset($paramsTag[$key])) {
return error('Missing Parameter: ' . $key);
}
}
$studiensemester_kurzbz = (isset ($paramsTag['studiensemester_kurzbz']) ? $paramsTag['studiensemester_kurzbz'] : null);
$tag = $paramsTag['kurzbz'];
$inputData = $paramsTag['data'];
$typeId = $paramsTag['typeId'];
// ---------------------------------
// prepare input
// ---------------------------------
$zeitraum = [];
$arrayIds = [];
foreach ($inputData as $item) {
$id = $item['id'];
$arrayIds[] = $id;
$zeitraum[$id] = [
'von' => $item['von'] ?? null,
'bis' => $item['bis'] ?? null
];
}
$arrayIds = array_unique($arrayIds);
$result = $this->_ci->StudiensemesterModel->load($studiensemester_kurzbz);
if (isError($result)) {
return $result;
}
$data = $result->retval[0] ?? null;
$von = $data->start ?? null;
$bis = $data->ende ?? null;
// ---------------------------------
// load existing tags
// ---------------------------------
$allTags = [];
$resultAllTags = $this->_ci->NotizModel->getAllTags($tag, $von, $bis);
if (isError($resultAllTags)) {
return $resultAllTags;
}
$allTagsData = getData($resultAllTags);
if (!empty($allTagsData)) {
foreach ($allTagsData as $item) {
$allTags[$item->$typeId] = $item->notiz_id;
}
}
// ---------------------------------
// map the data
// ---------------------------------
$toRecycle = [];
$toAdd = [];
$toDelete = [];
foreach ($arrayIds as $id) {
if (isset($allTags[$id])) {
$toRecycle[$id] = $allTags[$id];
} else {
$toAdd[] = $id;
}
}
foreach ($allTags as $id => $notizId) {
if (!in_array($id, $arrayIds)) {
$toDelete[$id] = $notizId;
}
}
// ---------------------------------
// recycle (update existing)
// ---------------------------------
$countRecycled = 0;
$retagged = [];
foreach ($toRecycle as $id => $notizId)
{
$this->_updateTag($notizId, $zeitraum[$id]['von'], $zeitraum[$id]['bis']);
$countRecycled++;
$retagged[] = $id;
}
// ---------------------------------
// ADD
// ---------------------------------
$countAdded = 0;
$tagged = [];
foreach ($toAdd as $id)
{
$this->_insertTag($typeId, $id, $tag, $zeitraum[$id]['von'], $zeitraum[$id]['bis']);
$countAdded++;
$tagged[] = $id;
}
// ---------------------------------
// delete
// ---------------------------------
$countDeleted = 0;
$deleted = [];
foreach ($toDelete as $id => $notizId)
{
$result = $this->_deleteTag($notizId);
if (isError($result)) {
return $result;
}
$countDeleted++;
$deleted[] = $id;
}
// ---------------------------------
// return
// ---------------------------------
return success([
'input' => [
'tag' => $tag,
'arrayIds' => $arrayIds
],
'summary' => [
'recycled' => $countRecycled,
'added' => $countAdded,
'deleted' => $countDeleted
],
'details' => [
'existingTags' => $allTags,
'toAdd' => $toAdd,
'toRecycle' => $toRecycle,
'toDelete' => $toDelete
],
'results' => [
'retaggedIds' => $retagged,
'newTags' => $tagged,
'deletedTagsIds' => $deleted
]
]);
}
public function updateAutomatedTagsForTypeId(array $params)
{
$return = null;
$notiz_id = null;
$von = $params['von'];
$bis = $params['bis'];
$tag = $params['kurzbz'];
$id = $params['id'];
$typeId = $params['typeId'];
$this->_ci->NotizModel->addSelect('nz.notiz_id');
$this->_ci->NotizModel->addSelect($typeId);
$this->_ci->NotizModel->addJoin('public.tbl_notizzuordnung nz', 'notiz_id');
$resultAllTags = $this->_ci->NotizModel->loadWhere([
'typ' => $tag,
$typeId => $id
]);
if(hasData($resultAllTags))
{
$notiz_id = $resultAllTags->retval[0]->notiz_id;
}
//RECYCLE
if ($notiz_id !== null)
{
$resultUpdateNotiz = $this->_updateTag($notiz_id, $von, $bis);
$return = ['recycled' => $resultUpdateNotiz];
}
else
//ADD
{
$resultInsertNotiz = $this->_insertTag($typeId, $id, $tag, $von, $bis);
$return = ['added' => $resultInsertNotiz];
}
return success($return);
}
/*
* main function for rebuild Tags for typeId
* */
public function rebuildTagsForTypeId($typeId, $id, $studiensemester_kurzbz)
{
$automatedTagsRes = $this->_ci->NotiztypModel->loadWhere(array('automatisiert' => true, 'taglib IS NOT NULL' => null));
$automatedTags = hasData($automatedTagsRes) ? getData($automatedTagsRes) : [];
$result = $this->_ci->StudiensemesterModel->load($studiensemester_kurzbz);
if (isError($result))
return error('Error occurred during retrieving studiensemester');
if (empty($result->retval) || !isset($result->retval[0])) {
return error('No studiensemester found');
}
$startSem = $result->retval[0]->start ?? null;
$endeSem = $result->retval[0]->ende ?? null;
$return = [];
foreach ($automatedTags as $autoTag)
{
// getPath: must not be lost
$filePath = APPPATH . 'libraries/' . $autoTag->taglib . '.php'; // APPPATH = application/
if (file_exists($filePath)) {
require_once($filePath);
} else {
echo "File not found: " . $filePath;
continue;
}
$className = basename($autoTag->taglib);
$kurz_bz = $autoTag->typ_kurzbz;
$obj = new $className();
$criteriaIsSet = $obj->isCriteriaSetFor([
'typeId' => $typeId,
'id' => $id,
'studiensemester_kurzbz' => $studiensemester_kurzbz
]);
if (hasData($criteriaIsSet))
{
$von = isset($criteriaIsSet->retval[0]->von) ? $criteriaIsSet->retval[0]->von : '';
$bis = isset($criteriaIsSet->retval[0]->bis) ? $criteriaIsSet->retval[0]->bis : '';
$params = [
'von' => $von,
'bis' => $bis,
'kurzbz' => $autoTag->typ_kurzbz,
'typeId' => $typeId,
'id' => $id,
];
$result = $this->updateAutomatedTagsForTypeId($params);
if (isError($result))
return error('Error occurred during updateAutomatedTags' . $kurz_bz);
$return[$kurz_bz] = $result;
}
else
{
//CHECK FOR DELETE
$params = [
'von' => $startSem,
'bis' => $endeSem,
'kurzbz' => $autoTag->typ_kurzbz,
'typeId' => $typeId,
'id' => $id,
];
$result = $this->_ci->NotizModel->checkIfExistingTag($kurz_bz, $typeId, $id, $startSem, $endeSem);
if (hasData($result))
{
$notizId = $result->retval[0]->notiz_id;
$this->_deleteTag($notizId);
$return[$kurz_bz] = ['deleted' => $notizId];
}
}
}
return success($return);
}
private function _insertTag($typeId, $id, $tag, $von, $bis)
{
$resultInsert = $this->_ci->NotizModel->insert([
'titel' => 'TAG',
'text' => 'AUTOMATED TAG',
'verfasser_uid' => $this->batchUser,
'erledigt' => false,
'insertamum' => date('Y-m-d H:i:s'),
'insertvon' => 'BatchJobTagAdd',
'typ' => $tag,
'start' => $von,
'ende' => $bis
]);
if (isError($resultInsert)) {
return error('Error inserting tag for ' . $typeId . ': ' . $id);
}
$notizId = $resultInsert->retval;
$resultZuordnung = $this->_ci->NotizzuordnungModel->insert([
'notiz_id' => $notizId,
$typeId => $id
]);
if (isError($resultZuordnung)) {
return error('Error inserting relation for ' . $typeId . ': ' . $id);
}
return $notizId;
}
private function _updateTag($notiz_id, $von, $bis)
{
$resultUpdateNotiz = $this->_ci->NotizModel->update(
[
'notiz_id' => $notiz_id
],
array(
'updateamum' => date('Y-m-d H:i:s'),
'updatevon' => 'BatchJobTagUpdate',
'start' => $von,
'ende' => $bis
));
if (isError($resultUpdateNotiz))
return error ('Error occurred during Update ' . $notiz_id);
return $notiz_id;
}
private function _deleteTag($notiz_id)
{
$result = $this->_ci->NotizzuordnungModel->delete([
'notiz_id' => $notiz_id
]);
if (isError($result)) {
return error('Error occurred during delete Notizzuordnung ' . $notiz_id);
}
$result = $this->_ci->NotizModel->delete([
'notiz_id' => $notiz_id
]);
if (isError($result)) {
return error('Error occurred during delete Notiz ' . $notiz_id);
}
return success([
'deleted' => $notiz_id
]);
}
}
+109 -48
View File
@@ -28,6 +28,7 @@ class StudentListLib
private $_allowedStgs = [];
private $_selects = [];
private $_joins = [];
private $_wheres = [];
/**
* Gets the CI instance, loads model and prepares default values
@@ -40,6 +41,8 @@ class StudentListLib
{
$this->_ci =& get_instance(); // get code igniter instance
$this->_ci->load->config('stv');
$this->_ci->load->model('crm/Prestudent_model', 'PrestudentModel');
if (isset($params['allowedStgs']))
@@ -47,8 +50,6 @@ class StudentListLib
// Add default SELECTs
$this->addSelect("b.uid");
if (defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
$this->addSelect('tag_data_agg.tags');
$this->addSelect('titelpre');
$this->addSelect('nachname');
$this->addSelect('vorname');
@@ -72,6 +73,13 @@ class StudentListLib
$this->addSelect('pls.status_kurzbz AS status');
$this->addSelect('pls.datum AS status_datum');
$this->addSelect('pls.bestaetigtam AS status_bestaetigung');
$this->addSelect("
CASE
WHEN pls.status_kurzbz IN ('Interessent','Aufgenommener','Bewerber','Wartender')
THEN pls.ausbildungssemester
ELSE v.semester
END AS semester_berechnet
");
$this->addSelect(
"(SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp='email' AND person_id=p.person_id AND zustellung LIMIT 1) AS mail_privat",
false
@@ -111,7 +119,7 @@ class StudentListLib
) prest
WHERE laststatus NOT IN ('Abbrecher', 'Abgewiesener', 'Absolvent')
AND priorisierung <= tbl_prestudent.priorisierung
) || ' (' || COALESCE(tbl_prestudent.priorisierung::text, ' '::text) || ')' AS priorisierung_relativ", false); // TODO(chris): overwrite in fetchStudents
) || ' (' || COALESCE(tbl_prestudent.priorisierung::text, ' '::text) || ')' AS priorisierung_relativ", false);
$this->addSelect('mentor');
$this->addSelect('b.aktiv AS bnaktiv');
$this->addSelect('unruly');
@@ -119,7 +127,7 @@ class StudentListLib
// Add default JOINs
$this->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
$this->addJoin('public.tbl_person p', 'person_id');
$this->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT'); // TODO(chris): overwrite in fetchStudents
$this->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT');
$this->addJoin('public.tbl_prestudentstatus pls', '
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
AND pls.prestudent_id=tbl_prestudent.prestudent_id
@@ -129,40 +137,14 @@ class StudentListLib
$this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid', 'LEFT');
$this->addJoin("v", "", ""); // Will be replaced later
$this->addJoin("ps", "", ""); // Will be replaced later
if (defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED) {
$this->_ci->load->config('stv');
$tags = $this->_ci->config->item('stv_prestudent_tags');
$whereTags = '';
if (is_array($tags) && !isEmptyArray($tags)) {
$tags = array_keys($tags);
foreach ($tags as $key => $tag) {
$tags[$key] = $this->_ci->PrestudentModel->escape($tag);
}
$whereTags = " AND nt.typ_kurzbz IN (" . implode(",", $tags) . ")";
}
$subQueryTag = "(
SELECT
tag.prestudent_id,
COALESCE(json_agg(tag ORDER BY tag.done), '[]'::json) AS tags
FROM (
SELECT DISTINCT ON (n.notiz_id)
n.notiz_id AS id,
nt.typ_kurzbz,
array_to_json(nt.bezeichnung_mehrsprachig)->>0 AS beschreibung,
n.text AS notiz,
nt.style,
n.erledigt AS done,
nz.prestudent_id
FROM public.tbl_notizzuordnung AS nz
JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id
JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz " . $whereTags . "
) AS tag
GROUP BY tag.prestudent_id
) AS tag_data_agg";
$this->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT');
// Add SELECTs and JOINs from config
$config = $this->_ci->config->item('list_columns') ?: [];
foreach ($config as $conf) {
$this->addSelect($conf['default']);
if (isset($conf['joins']))
foreach ($conf['joins'] as $join)
call_user_func_array([$this, 'addJoin'], $join);
}
}
@@ -249,11 +231,7 @@ class StudentListLib
*/
public function addWhere($key, $value = null, $escape = true)
{
if (!is_array($key) && is_array($value)) {
$this->_ci->PrestudentModel->db->where_in($key, $value, $escape);
} else {
$this->_ci->PrestudentModel->db->where($key, $value, $escape);
}
$this->_wheres[] = [$key, $value, $escape, false];
}
/**
@@ -267,11 +245,7 @@ class StudentListLib
*/
public function addOrWhere($key, $value = null, $escape = true)
{
if (!is_array($key) && is_array($value)) {
$this->_ci->PrestudentModel->db->or_where_in($key, $value, $escape);
} else {
$this->_ci->PrestudentModel->db->or_where($key, $value, $escape);
}
$this->_wheres[] = [$key, $value, $escape, true];
}
/**
@@ -283,8 +257,9 @@ class StudentListLib
*/
public function execute($studiensemester_kurzbz)
{
$stdsemEsc = $studiensemester_kurzbz ? $this->_ci->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
$this->addSelectAndJoinForTagsIfConfigured($studiensemester_kurzbz);
$stdsemEsc = $studiensemester_kurzbz ? $this->_ci->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
$this->addSelect(
"public.get_rolle_prestudent(
@@ -315,6 +290,20 @@ class StudentListLib
foreach ($this->_selects as $select)
$this->_ci->PrestudentModel->addSelect($select[0], $select[1]);
foreach ($this->_wheres as $where) {
if (!is_array($where[0]) && is_array($where[1])) {
if ($where[3])
$this->_ci->PrestudentModel->db->or_where_in($where[0], $where[1], $where[2]);
else
$this->_ci->PrestudentModel->db->where_in($where[0], $where[1], $where[2]);
} else {
if ($where[3])
$this->_ci->PrestudentModel->db->or_where($where[0], $where[1], $where[2]);
else
$this->_ci->PrestudentModel->db->where($where[0], $where[1], $where[2]);
}
}
$this->_ci->PrestudentModel->addOrder('nachname');
$this->_ci->PrestudentModel->addOrder('vorname');
@@ -325,6 +314,78 @@ class StudentListLib
//------------------------------------------------------------------------------------------------------------------
// Protected methods
/**
* Add Select and Join for Tags if configured
*
* @param string studiensemester_kurzbz
*
*/
protected function addSelectAndJoinForTagsIfConfigured($studiensemester_kurzbz)
{
if (defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED) {
$this->_ci->load->config('stv');
$tags = $this->_ci->config->item('stv_prestudent_tags');
$whereTags = '';
if (is_array($tags) && !isEmptyArray($tags)) {
$tags = array_keys($tags);
foreach ($tags as $key => $tag) {
$tags[$key] = $this->_ci->PrestudentModel->escape($tag);
}
$whereTags = " AND nt.typ_kurzbz IN (" . implode(",", $tags) . ")";
}
$studiensemester_kurzbz_escaped = $this->_ci->PrestudentModel->escape($studiensemester_kurzbz);
$subQueryTag = "(
SELECT
tag.prestudent_id,
COALESCE(json_agg(tag ORDER BY tag.done, tag.prioritaet), '[]'::json) AS tags
FROM (
SELECT DISTINCT ON (n.notiz_id)
n.notiz_id AS id,
nt.typ_kurzbz,
nt.bezeichnung_mehrsprachig[(
SELECT index
FROM tbl_sprache
WHERE sprache=" . $this->_ci->PrestudentModel->escape(getUserLanguage()) . "
)] AS beschreibung,
n.text AS notiz,
nt.style,
n.erledigt AS done,
nt.prioritaet AS prioritaet,
nt.automatisiert AS automatisiert,
nz.prestudent_id,
n.start,
n.ende
FROM public.tbl_notizzuordnung AS nz
JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id AND nz.prestudent_id IS NOT NULL
JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz " . $whereTags . "
WHERE
COALESCE(n.start, '1970-01-01') <= (
SELECT
ende
FROM
public.tbl_studiensemester
WHERE
studiensemester_kurzbz = " . $studiensemester_kurzbz_escaped . "
)
AND COALESCE(n.ende, '2170-12-31') >= (
SELECT
start
FROM
public.tbl_studiensemester
WHERE
studiensemester_kurzbz = " . $studiensemester_kurzbz_escaped . "
)
) AS tag
GROUP BY tag.prestudent_id
) AS tag_data_agg";
$this->addSelect('tag_data_agg.tags');
$this->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT');
}
}
/**
* Get alias of a table or select statement
*
@@ -0,0 +1,81 @@
<?php
/**
* Description of dd_auto
*
* @author ma0068
*/
class CoreDoubleDegreeTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('codex/Mobilitaet_model', 'MobilitaetModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$this->ci->MobilitaetModel->addJoin('bis.tbl_gsprogramm', 'gsprogramm_id');
$this->ci->MobilitaetModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->MobilitaetModel-> loadWhere(array(
'gsprogrammtyp_kurzbz' => 'Double',
'studiensemester_kurzbz' => $semester
));
$data = $result->retval;
$doubledegree_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => $item->start,
'bis' => $item->ende
];
}, $data);
return (object) array(
'data' => $doubledegree_data,
'typeId' => 'prestudent_id'
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$this->ci->MobilitaetModel->addSelect('prestudent_id');
$this->ci->MobilitaetModel->addSelect('start as von');
$this->ci->MobilitaetModel->addSelect('ende as bis');
$this->ci->MobilitaetModel->addJoin('bis.tbl_gsprogramm', 'gsprogramm_id');
$this->ci->MobilitaetModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->MobilitaetModel->loadWhere(array(
'gsprogrammtyp_kurzbz' => 'Double',
'studiensemester_kurzbz' => $semester,
'prestudent_id' => $prestudent_id
));
if(hasData($result))
{
//array mit prestudent_id, von und bis
return $result;
}
else
return null;
}
}
@@ -0,0 +1,81 @@
<?php
/**
* Description unruly
* Test for different typeId
*
* @author ma0068
*/
class CoreFiftyFiveTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('person/Person_model', 'PersonModel');
$this->ci-> load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'person_id' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$result = $this->ci->StudiensemesterModel->loadWhere(array(
'studiensemester_kurzbz' => $semester
));
$data = $result->retval[0];
$semVon = $data->start;
$semBis = $data->ende;
$result = $this->ci->PersonModel->getFiftyFivers($semVon, $semBis);
$data = $result->retval;
$fiftyFiveData = array_map(function($item) {
return [
'id' => $item->person_id
];
}, $data);
return (object) array(
'data' => $fiftyFiveData,
'typeId' => 'person_id'
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'person_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$person_id = $params['id'];
$typeId = $params['typeId'];
$result = $this->ci->StudiensemesterModel->loadWhere(array(
'studiensemester_kurzbz' => $semester
));
$data = $result->retval[0];
$semVon = $data->start;
$semBis = $data->ende;
$result = $this->ci->PersonModel->isFiftyFive($semVon, $semBis, $person_id);
if(hasData($result))
{
return $result;
}
else
return null;
}
}
@@ -0,0 +1,63 @@
<?php
/**
* Description of out_auto
*
* @author ma0068
*/
class CoreIncomingTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('codex/Bisio_model', 'BisioModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$result = $this->ci->BisioModel->getIncomingsOfSemester($semester);
$data = $result->retval;
$outgoing_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => $item->von,
'bis' => $item->bis
];
}, $data);
return (object) array(
'data' => $outgoing_data,
'typeId' => 'prestudent_id',
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$result = $this->ci->BisioModel->isPrestudentIncoming($semester, $prestudent_id);
if (hasData($result)) {
return $result;
}
else
return null;
}
}
@@ -0,0 +1,64 @@
<?php
/**
* Description of jgv_auto (Jahrgangsvertretung)
*
* @author ma0068
*/
class CoreJgvTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$result = $this->ci->BenutzerfunktionModel->getPrestudentsOfJgv($semester);
$data = $result->retval;
$jgv_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => $item->datum_von,
'bis' => $item->datum_bis
];
}, $data);
return (object) array(
'data' => $jgv_data,
'typeId' => 'prestudent_id'
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$result = $this->ci->BenutzerfunktionModel->isJgv($semester, $prestudent_id);
if(hasData($result))
{
return $result;
}
else
return null;
}
}
@@ -0,0 +1,112 @@
<?php
/**
* Description of zgv_auto
*
* @author ma0068
*/
class CoreMissingZgvTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('crm/Prestudent_model', 'PrestudentModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$this->ci->PrestudentModel->addJoin('public.tbl_prestudentstatus', 'prestudent_id');
$this->ci->PrestudentModel->addJoin('public.tbl_benutzer bn', 'person_id');
$this->ci->PrestudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$this->ci->PrestudentModel->db->group_start();
$this->ci->PrestudentModel->db->where('zgvdatum', null);
$this->ci->PrestudentModel->db->where('typ', 'b');
$this->ci->PrestudentModel->db->or_group_start();
$this->ci->PrestudentModel->db->where('zgvmadatum', null);
$this->ci->PrestudentModel->db->where('typ', 'm');
$this->ci->PrestudentModel->db->group_end();
$this->ci->PrestudentModel->db->group_end();
$result = $this->ci->PrestudentModel-> loadWhere(array(
'bn.aktiv' => true,
'studiensemester_kurzbz' => $semester
));
$data = $result->retval;
$zgvmissing_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => null,
'bis' => null
];
}, $data);
return (object) array(
'typeId' => 'prestudent_id',
'data' => $zgvmissing_data
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$this->ci->PrestudentModel->addSelect('prestudent_id');
$this->ci->PrestudentModel->addSelect('start as von');
$this->ci->PrestudentModel->addSelect('ende as bis');
$this->ci->PrestudentModel->addJoin('public.tbl_prestudentstatus', 'prestudent_id');
//add studiensemester also here for manual rebuild
$this->ci->PrestudentModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$this->ci->PrestudentModel->addJoin('public.tbl_benutzer bn', 'person_id');
$this->ci->PrestudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$this->ci->PrestudentModel->db->group_start();
$this->ci->PrestudentModel->db->where('zgvdatum', null);
$this->ci->PrestudentModel->db->where('typ', 'b');
$this->ci->PrestudentModel->db->or_group_start();
$this->ci->PrestudentModel->db->where('zgvmadatum', null);
$this->ci->PrestudentModel->db->where('typ', 'm');
$this->ci->PrestudentModel->db->group_end();
$this->ci->PrestudentModel->db->group_end();
$this->ci->PrestudentModel->db->limit(1);
$result = $this->ci->PrestudentModel-> loadWhere(array(
'bn.aktiv' => true,
'studiensemester_kurzbz' => $semester,
'prestudent_id' => $prestudent_id
));
if(hasData($result))
{
return $result;
}
else
return null;
}
}
@@ -0,0 +1,63 @@
<?php
/**
* Description of out_auto
*
* @author ma0068
*/
class CoreOutgoingTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('codex/Bisio_model', 'BisioModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$result = $this->ci->BisioModel->getOutgoingsOfSemester($semester);
$data = $result->retval;
$outgoing_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => $item->von,
'bis' => $item->bis
];
}, $data);
return (object) array(
'data' => $outgoing_data,
'typeId' => 'prestudent_id',
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$result = $this->ci->BisioModel->isPrestudentOutgoing($semester, $prestudent_id);
if (hasData($result)) {
return $result;
}
else
return null;
}
}
@@ -0,0 +1,80 @@
<?php
/**
* Description of prewh_auto
*
* @author ma0068
*/
class CorePreabbrecherTagLib
{
protected $ci;
const TYP_ABMELDUNG = ['Abmeldung', 'AbmeldungStgl'];
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('education/Studierendenantrag_model', 'StudierendenantragModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$this->ci->StudierendenantragModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$this->ci->StudierendenantragModel->db->where_in('typ', self::TYP_ABMELDUNG);
$this->ci->StudierendenantragModel->db->where('studiensemester_kurzbz', $semester);
$result = $this->ci->StudierendenantragModel->getWithLastStatusWhere([
'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_CREATED
]);
$data = $result->retval;
$prewiederholer_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => $item->start,
'bis' => $item->ende
];
}, $data);
return (object) array(
'data' => $prewiederholer_data,
'typeId' => 'prestudent_id',
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$this->ci->StudierendenantragModel->addSelect('prestudent_id');
$this->ci->StudierendenantragModel->addSelect('start as von');
$this->ci->StudierendenantragModel->addSelect('ende as bis');
$this->ci->StudierendenantragModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$this->ci->StudierendenantragModel->db->where_in('typ', self::TYP_ABMELDUNG);
$this->ci->StudierendenantragModel->db->where('studiensemester_kurzbz', $semester);
$this->ci->StudierendenantragModel->db->where('prestudent_id', $prestudent_id);
$result = $this->ci->StudierendenantragModel->getWithLastStatusWhere([
'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_CREATED
]);
if(hasData($result))
{
return $result;
}
else
return null;
}
}
@@ -0,0 +1,76 @@
<?php
/**
* Description of prewh_auto
*
* @author bambi
*/
class CorePrewiederholerTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$this->ci->PrestudentstatusModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->PrestudentstatusModel-> loadWhere(array(
'statusgrund_id' => 15,
'studiensemester_kurzbz' => $semester
));
$data = $result->retval;
$prewiederholer_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => $item->start,
'bis' => $item->ende
];
}, $data);
return (object) array(
'data' => $prewiederholer_data,
'typeId' => 'prestudent_id',
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$this->ci->PrestudentstatusModel->addSelect('prestudent_id');
$this->ci->PrestudentstatusModel->addSelect('start as von');
$this->ci->PrestudentstatusModel->addSelect('ende as bis');
$this->ci->PrestudentstatusModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->PrestudentstatusModel->loadWhere(array(
'statusgrund_id' => 15,
'studiensemester_kurzbz' => $semester,
'prestudent_id' => $prestudent_id
));
if(hasData($result))
{
return $result;
}
else
return null;
}
}
@@ -0,0 +1,79 @@
<?php
/**
* Description of dd_auto
*
* @author ma0068
*/
class CoreStbErhoehtTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('crm/Konto_model', 'KontoModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$this->ci->KontoModel->addJoin('public.tbl_prestudent', 'person_id');
$this->ci->KontoModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->KontoModel-> loadWhere(array(
'buchungstyp_kurzbz' => 'StudiengebuehrErhoeht',
'studiensemester_kurzbz' => $semester
));
$data = $result->retval;
$konto_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => $item->start,
'bis' => $item->ende
];
}, $data);
return (object) array(
'data' => $konto_data,
'typeId' => 'prestudent_id'
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$this->ci->KontoModel->addSelect('prestudent_id');
$this->ci->KontoModel->addSelect('start as von');
$this->ci->KontoModel->addSelect('ende as bis');
$this->ci->KontoModel->addJoin('public.tbl_prestudent', 'person_id');
$this->ci->KontoModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->KontoModel-> loadWhere(array(
'buchungstyp_kurzbz' => 'StudiengebuehrErhoeht',
'studiensemester_kurzbz' => $semester,
'prestudent_id' => $prestudent_id
));
if(hasData($result))
{
return $result;
}
else
return null;
}
}
@@ -0,0 +1,76 @@
<?php
/**
* Description of wiedereinstieg_auto
*
* @author ma0068
*/
class CoreUnterbrecherTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$this->ci->PrestudentstatusModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->PrestudentstatusModel-> loadWhere(array(
'status_kurzbz' => 'Unterbrecher',
'studiensemester_kurzbz' => $semester
));
$data = $result->retval;
$unterbrecher_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => $item->start,
'bis' => $item->ende
];
}, $data);
return (object) array(
'data' => $unterbrecher_data,
'typeId' => 'prestudent_id'
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$this->ci->PrestudentstatusModel->addSelect('prestudent_id');
$this->ci->PrestudentstatusModel->addSelect('start as von');
$this->ci->PrestudentstatusModel->addSelect('ende as bis');
$this->ci->PrestudentstatusModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->PrestudentstatusModel-> loadWhere(array(
'status_kurzbz' => 'Unterbrecher',
'studiensemester_kurzbz' => $semester,
'prestudent_id' => $prestudent_id
));
if(hasData($result))
{
return $result;
}
else
return null;
}
}
@@ -0,0 +1,76 @@
<?php
/**
* Description of wh_auto
*
* @author bambi
*/
class CoreWiederholerTagLib
{
protected $ci;
public function __construct()
{
$this->ci = get_instance();
$this->ci->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
}
public function getZuordnungIds(array $params)
{
if(!isset($params['studiensemester_kurzbz']))
{
return (object) array(
'idArray' => []
);
}
$semester = $params['studiensemester_kurzbz'];
$this->ci->PrestudentstatusModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->PrestudentstatusModel-> loadWhere(array(
'statusgrund_id' => 16,
'studiensemester_kurzbz' => $semester
));
$data = $result->retval;
$wiederholer_data = array_map(function($item) {
return [
'id' => $item->prestudent_id,
'von' => $item->start,
'bis' => $item->ende
];
}, $data);
return (object) array(
'typeId' => 'prestudent_id',
'data' => $wiederholer_data
);
}
public function isCriteriaSetFor(array $params)
{
if ( !isset($params['id'], $params['studiensemester_kurzbz'], $params['typeId']) || $params['typeId'] !== 'prestudent_id')
return false;
$semester = $params['studiensemester_kurzbz'];
$prestudent_id = $params['id'];
$this->ci->PrestudentstatusModel->addSelect('prestudent_id');
$this->ci->PrestudentstatusModel->addSelect('start as von');
$this->ci->PrestudentstatusModel->addSelect('ende as bis');
$this->ci->PrestudentstatusModel->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$result = $this->ci->PrestudentstatusModel->loadWhere(array(
'statusgrund_id' => 16,
'studiensemester_kurzbz' => $semester,
'prestudent_id' => $prestudent_id,
));
if(hasData($result))
{
return $result;
}
else
return null;
}
}
+192
View File
@@ -0,0 +1,192 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* LvVw Menu library
*/
class LvVwLib
{
protected $_ci = null;
public $config = [];
public function __construct()
{
// Get code igniter instance
$this->_ci =& get_instance();
// Load Tree-config
$this->_ci->load->config('treemenu/custom/lvvw');
$this->config = $this->_ci->config->item('root');
// Load Libraries
$this->_ci->load->library('treemenu/base/StgLib');
// Load Model
$this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
}
public function stg($path_template)
{
$permittedStgs = $this->getPermittedStudiengangKzs();
if (!$permittedStgs)
return [];
$this->_ci->StudiengangModel->addSelect("ARRAY['link', FORMAT('{" .
'"type": "verband",' .
'"id": "lv/%1$s",' .
'"gruppe_kurzbz": null,' .
'"semester": null,' .
'"verband": null,' .
'"gruppe": null,' .
'"lehrverband": true,' .
'"stg_kz": "%1$s"' .
"}', studiengang_kz)] AS draggable", false);
return $this->_ci->stglib->studiengang($path_template, $permittedStgs);
}
public function semester($path_template, $has_children, $stg)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
if (!$has_children)
$this->_ci->StudiengangModel->db->select('TRUE AS leaf', false);
$this->_ci->StudiengangModel->addSelect("ARRAY['link', FORMAT('{" .
'"type": "verband",' .
'"id": "lv/%1$s/%2$s",' .
'"gruppe_kurzbz": null,' .
'"semester": "%2$s",' .
'"verband": null,' .
'"gruppe": null,' .
'"lehrverband": true,' .
'"stg_kz": "%1$s"' .
"}', v.studiengang_kz, v.semester)] AS draggable", false);
return $this->_ci->stglib->semester($path_template, $stg->studiengang_kz);
}
public function verband($path_template, $stg, $semester)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
$this->_ci->StudiengangModel->addSelect("CASE WHEN MAX(gruppe)='' OR MAX(gruppe)=' ' THEN TRUE ELSE FALSE END AS leaf");
$this->_ci->StudiengangModel->addSelect("ARRAY['link', FORMAT('{" .
'"type": "verband",' .
'"id": "lv/%1$s/%2$s/%3$s",' .
'"gruppe_kurzbz": null,' .
'"semester": "%2$s",' .
'"verband": "%3$s",' .
'"gruppe": null,' .
'"lehrverband": true,' .
'"stg_kz": "%1$s"' .
"}', v.studiengang_kz, v.semester, v.verband)] AS draggable", false);
$this->_ci->StudiengangModel->addGroupBy('v.studiengang_kz, v.semester');
return $this->_ci->stglib->verband($path_template, $stg->studiengang_kz, $semester);
}
public function group($path_template, $stg, $semester, $verband)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
$this->_ci->StudiengangModel->db->select('TRUE AS leaf', false);
if ($verband === null) {
$this->_ci->StudiengangModel->addSelect("ARRAY['link', FORMAT('{" .
'"type": "verband",' .
'"id": "grp/%1$s/%2$s/%3$s",' .
'"gruppe_kurzbz": "%3$s",' .
'"semester": "%2$s",' .
'"verband": null,' .
'"gruppe": null,' .
'"lehrverband": false,' .
'"stg_kz": "%1$s"' .
"}', studiengang_kz, semester, gruppe_kurzbz)] AS draggable", false);
return $this->_ci->stglib->group($path_template, $stg->studiengang_kz, $semester);
}
$this->_ci->StudiengangModel->addSelect("ARRAY['link', FORMAT('{" .
'"type": "verband",' .
'"id": "lv/%1$s/%2$s/%3$s/%4$s",' .
'"gruppe_kurzbz": null,' .
'"semester": "%2$s",' .
'"verband": "%3$s",' .
'"gruppe": "%4$s",' .
'"lehrverband": true,' .
'"stg_kz": "%1$s"' .
"}', v.studiengang_kz, v.semester, v.verband, v.gruppe)] AS draggable", false);
return $this->_ci->stglib->verbandsgroup($path_template, $stg->studiengang_kz, $semester, $verband);
}
public function orgform($path_template, $stg)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
if (!$stg->mischform)
return [];
$this->_ci->StudiengangModel->db->select('TRUE AS leaf', false);
return $this->_ci->stglib->orgform($path_template, $stg->studiengang_kz);
}
protected function getPermittedStudiengangKzs()
{
$permittedStgs = $this->_ci->permissionlib->getSTG_isEntitledFor('admin') ?: [];
$permittedStgs = array_merge($permittedStgs, $this->_ci->permissionlib->getSTG_isEntitledFor('assistenz') ?: []);
return $permittedStgs;
}
protected function getStgFromUrl($stg)
{
$permittedStgs = $this->getPermittedStudiengangKzs();
if (!$permittedStgs)
return null;
$this->_ci->StudiengangModel->db->where_in('studiengang_kz', $permittedStgs);
$stg = $this->_ci->StudiengangModel->loadWhere([
'LOWER(CONCAT(typ, kurzbz)) =' => $stg
]);
if (!hasData($stg))
return null;
return current(getData($stg));
}
}
@@ -0,0 +1,257 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* StudVw Menu library
*/
class StudVwLib
{
protected $_ci = null;
public $config = [];
public $redirect_method = [
'interessenten' => 'filter',
'bewerbungnichtabgeschickt' => 'filter',
'bewerbungabgeschickt' => 'filter',
'zgv' => 'filter',
'statusbestaetigt' => 'filter',
'statusbestaetigtrtnichtangemeldet' => 'filter',
'statusbestaetigtrtangemeldet' => 'filter',
'reihungstestnichtangemeldet' => 'filter',
'reihungstestangemeldet' => 'filter',
'bewerber' => 'filter',
'bewerberrtnichtangemeldet' => 'filter',
'bewerberrtangemeldet' => 'filter',
'bewerberrtangemeldetteilgenommen' => 'filter',
'bewerberrtangemeldetnichtteilgenommen' => 'filter',
'aufgenommen' => 'filter',
'warteliste' => 'filter',
'absage' => 'filter',
'outgoing' => 'inout',
'shared_studies' => 'inout'
];
public function __construct()
{
// Get code igniter instance
$this->_ci =& get_instance();
// Load Tree-config
$this->_ci->load->config('treemenu/stg_base');
$this->config = $this->_ci->config->item('root');
// Load Libraries
$this->_ci->load->library('treemenu/base/StgLib');
// Load Model
$this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
}
public function stg($path_template)
{
$permittedStgs = $this->getPermittedStudiengangKzs();
if (!$permittedStgs)
return [];
return $this->_ci->stglib->studiengang($path_template, $permittedStgs);
}
public function prestudent($path_template, $stg)
{
// Check permission
if ($this->getStgFromUrl($stg) === null)
return [];
return [
[
'path' => sprintf($path_template, '1'),
'name' => ['lehre', 'prestudent'],
'no_sem_reload' => true
]
];
}
public function stdsem($path_template, $stg)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
return $this->_ci->stglib->studiensemester($path_template, $stg->studiengang_kz);
}
public function semester($path_template, $stg, $orgform)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
if ($orgform !== null) {
$orgform = $this->getOrgform($orgform);
if ($orgform === null)
return [];
$orgform = $orgform->orgform_kurzbz;
}
return $this->_ci->stglib->semester($path_template, $stg->studiengang_kz, $orgform);
}
public function verband($path_template, $stg, $semester, $orgform)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
if ($orgform !== null) {
$orgform = $this->getOrgform($orgform);
if ($orgform === null)
return [];
$orgform = $orgform->orgform_kurzbz;
}
$this->_ci->StudiengangModel->addSelect("CASE WHEN MAX(gruppe)='' OR MAX(gruppe)=' ' THEN TRUE ELSE FALSE END AS leaf");
return $this->_ci->stglib->verband($path_template, $stg->studiengang_kz, $semester, $orgform);
}
public function group($path_template, $stg, $semester, $verband, $orgform)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
if ($orgform !== null) {
$orgform = $this->getOrgform($orgform);
if ($orgform === null)
return [];
$orgform = $orgform->orgform_kurzbz;
}
$this->_ci->StudiengangModel->db->select('TRUE AS leaf', false);
if ($verband === null)
return $this->_ci->stglib->group($path_template, $stg->studiengang_kz, $semester, $orgform);
return $this->_ci->stglib->verbandsgroup($path_template, $stg->studiengang_kz, $semester, $verband, $orgform);
}
public function orgform($path_template, $stg)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
if (!$stg->mischform)
return [];
return $this->_ci->stglib->orgform($path_template, $stg->studiengang_kz);
}
public function incoming($has_children, $path_template, $stg)
{
if ($stg === null)
return $this->inout('incoming', $has_children, $path_template);
return $this->filter('incoming', $has_children, $path_template, $stg);
}
public function filter($original_method, $has_children, $path_template, $stg)
{
$stg = $this->getStgFromUrl($stg);
if ($stg === null)
return [];
// TODO(chris): phrasen
$item = [
'path' => sprintf($path_template, '1'),
'name' => ['treemenu', 'filter_' . $original_method]
];
if (!$has_children)
$item['leaf'] = true;
return [ $item ];
}
public function inout($original_method, $has_children, $path_template)
{
if (!$this->_ci->permissionlib->isBerechtigt('inout/uebersicht'))
return [];
// TODO(chris): phrasen
$item = [
'path' => sprintf($path_template, '1'),
'name' => ['treemenu', 'inout_' . $original_method]
];
if (!$has_children)
$item['leaf'] = true;
return [ $item ];
}
protected function getOrgform($orgform)
{
$this->_ci->load->model('codex/Orgform_model', 'OrgformModel');
$orgform = $this->_ci->OrgformModel->loadWhere([
'LOWER(orgform_kurzbz) =' => $orgform
]);
if (!hasData($orgform))
return null;
return current(getData($orgform));
}
protected function getPermittedStudiengangKzs()
{
$permittedStgs = $this->_ci->permissionlib->getSTG_isEntitledFor('admin') ?: [];
$permittedStgs = array_merge($permittedStgs, $this->_ci->permissionlib->getSTG_isEntitledFor('assistenz') ?: []);
return $permittedStgs;
}
protected function getStgFromUrl($stg)
{
$permittedStgs = $this->getPermittedStudiengangKzs();
if (!$permittedStgs)
return null;
$this->_ci->StudiengangModel->db->where_in('studiengang_kz', $permittedStgs);
$stg = $this->_ci->StudiengangModel->loadWhere([
'LOWER(CONCAT(typ, kurzbz)) =' => $stg
]);
if (!hasData($stg))
return null;
return current(getData($stg));
}
}
@@ -0,0 +1,313 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Stg Base library
*/
class StgLib
{
protected $_ci = null;
public function __construct()
{
// Get code igniter instance
$this->_ci =& get_instance();
}
public function studiengang($path_template, $permittedStgs = [])
{
$this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->_ci->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->_ci->StudiengangModel->addDistinct();
$this->_ci->StudiengangModel->addSelect("FORMAT(" . $this->_ci->StudiengangModel->escape($path_template) . ", LOWER(CONCAT(typ, kurzbz))) AS path");
$this->_ci->StudiengangModel->addSelect(
"CONCAT(kurzbzlang, ' (', UPPER(CONCAT(typ, kurzbz)), ') - ', tbl_studiengang.bezeichnung) AS name",
false
);
$this->_ci->StudiengangModel->addSelect("studiengang_kz AS title");
$this->_ci->StudiengangModel->addSelect("studiengang_kz AS search");
$this->_ci->StudiengangModel->addSelect('erhalter_kz');
$this->_ci->StudiengangModel->addSelect('typ');
$this->_ci->StudiengangModel->addSelect('kurzbz');
$this->_ci->StudiengangModel->addSelect('studiengang_kz');
$this->_ci->StudiengangModel->addSelect('studiengang_kz AS stg_kz');
$this->_ci->StudiengangModel->addOrder('erhalter_kz');
$this->_ci->StudiengangModel->addOrder('typ');
$this->_ci->StudiengangModel->addOrder('kurzbz');
if ($permittedStgs)
$this->_ci->StudiengangModel->db->where_in('studiengang_kz', $permittedStgs);
$result = $this->_ci->StudiengangModel->loadWhere(['v.aktiv' => true]);
return getData($result) ?: [];
}
public function semester($path_template, $studiengang_kz, $orgform_kurzbz = null)
{
$this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->_ci->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->_ci->StudiengangModel->addDistinct();
$this->_ci->StudiengangModel->addSelect("FORMAT(" . $this->_ci->StudiengangModel->escape($path_template) . ", semester) AS path", false);
$this->_ci->StudiengangModel->addSelect("CONCAT(
UPPER(CONCAT(typ, kurzbz)),
'-',
semester,
(
SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END
FROM public.tbl_lehrverband
WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester
ORDER BY verband, gruppe LIMIT 1
)
) AS name", false);
$this->_ci->StudiengangModel->addSelect('semester');
$this->_ci->StudiengangModel->addSelect('v.studiengang_kz AS stg_kz');
$this->_ci->StudiengangModel->addSelect("ARRAY['link-strict', 'student-collection'] AS droplink");
$this->_ci->StudiengangModel->addOrder('semester');
if ($orgform_kurzbz !== null) {
$this->_ci->StudiengangModel->addSelect($this->_ci->StudiengangModel->escape($orgform_kurzbz) . " AS orgform_kurzbz", false);
$this->_ci->StudiengangModel->addDistinct();
$this->_ci->StudiengangModel->db->group_start();
$this->_ci->StudiengangModel->db->where('v.semester', 0);
$this->_ci->StudiengangModel->db->or_where('v.orgform_kurzbz', $orgform_kurzbz);
$this->_ci->StudiengangModel->db->group_end();
}
$result = $this->_ci->StudiengangModel->loadWhere([
'studiengang_kz' => $studiengang_kz,
'v.aktiv' => true
]);
return getData($result) ?: [];
}
public function group($path_template, $studiengang_kz, $semester, $orgform_kurzbz = null)
{
$this->_ci->load->model('organisation/Gruppe_model', 'GruppeModel');
$this->_ci->GruppeModel->addDistinct();
$this->_ci->GruppeModel->addSelect("FORMAT(" . $this->_ci->GruppeModel->escape($path_template) . ", gruppe_kurzbz) AS path", false);
$this->_ci->GruppeModel->addSelect("CONCAT(gruppe_kurzbz, ' (', bezeichnung, ')') AS name", false);
$this->_ci->GruppeModel->addSelect('sort');
$this->_ci->GruppeModel->addSelect('gruppe_kurzbz');
$this->_ci->GruppeModel->addSelect($this->_ci->GruppeModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->_ci->GruppeModel->addSelect("ARRAY['link-strict', 'student-collection'] AS droplink");
$this->_ci->GruppeModel->addOrder('sort');
$this->_ci->GruppeModel->addOrder('gruppe_kurzbz');
$where = [
'studiengang_kz' => $studiengang_kz,
'semester' => $semester,
'lehre' => true,
'sichtbar' => true,
'aktiv' => true,
'direktinskription' => false
];
if ($orgform_kurzbz !== null)
$where['orgform_kurzbz'] = $orgform_kurzbz;
$result = $this->_ci->GruppeModel->loadWhere($where);
return getData($result) ?: [];
}
public function verband($path_template, $studiengang_kz, $semester, $orgform_kurzbz = null)
{
$this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->_ci->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->_ci->StudiengangModel->addSelect("FORMAT(" . $this->_ci->StudiengangModel->escape($path_template) . ", verband) AS path", false);
$this->_ci->StudiengangModel->addSelect("CONCAT(
UPPER(CONCAT(typ, kurzbz)),
'-',
semester,
verband,
(
SELECT
CASE
WHEN bezeichnung IS NULL OR bezeichnung=''
THEN ''::TEXT
ELSE CONCAT(' (', bezeichnung, ')')
END
FROM public.tbl_lehrverband
WHERE studiengang_kz=v.studiengang_kz
AND semester=v.semester
AND verband=v.verband
ORDER BY gruppe
LIMIT 1
)
) AS name", false);
$this->_ci->StudiengangModel->addSelect($this->_ci->StudiengangModel->escape($semester) . ' AS semester');
$this->_ci->StudiengangModel->addSelect('verband');
$this->_ci->StudiengangModel->addSelect($this->_ci->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->_ci->StudiengangModel->addSelect("ARRAY['link-strict', 'student-collection'] AS droplink");
$this->_ci->StudiengangModel->addOrder('verband');
$this->_ci->StudiengangModel->addGroupBy('path, name, verband');
$where = [
'v.studiengang_kz' => $studiengang_kz,
'v.semester' => $semester,
'v.verband !=' => '',
'v.aktiv' => true
];
if ($orgform_kurzbz !== null && $semester) // NOTE(chris): on semester 0 show all?
$where['v.orgform_kurzbz'] = $orgform_kurzbz;
$result = $this->_ci->StudiengangModel->loadWhere($where);
return getData($result) ?: [];
}
public function verbandsgroup($path_template, $studiengang_kz, $semester, $verband, $orgform_kurzbz = null)
{
$this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->_ci->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->_ci->StudiengangModel->addDistinct();
$this->_ci->StudiengangModel->addSelect("FORMAT(
" . $this->_ci->StudiengangModel->escape($path_template) . ",
gruppe
) AS path", false);
$this->_ci->StudiengangModel->addSelect("CONCAT(
UPPER(CONCAT(typ, kurzbz)),
'-',
semester,
verband,
gruppe,
(
SELECT
CASE
WHEN bezeichnung IS NULL OR bezeichnung=''
THEN ''::TEXT
ELSE CONCAT(' (', bezeichnung, ')')
END
FROM public.tbl_lehrverband
WHERE studiengang_kz=v.studiengang_kz
AND semester=v.semester
AND verband=v.verband
AND gruppe=v.gruppe
ORDER BY gruppe
LIMIT 1
)
) AS name", false);
$this->_ci->StudiengangModel->addSelect('v.semester');
$this->_ci->StudiengangModel->addSelect('v.verband');
$this->_ci->StudiengangModel->addSelect('gruppe');
$this->_ci->StudiengangModel->addSelect($this->_ci->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->_ci->StudiengangModel->addSelect("ARRAY['link-strict', 'student-collection'] AS droplink");
$this->_ci->StudiengangModel->addOrder('gruppe');
$where = [
'v.studiengang_kz' => $studiengang_kz,
'v.semester' => $semester,
'v.verband' => $verband,
'v.gruppe !=' => '',
'v.aktiv' => true
];
if ($orgform_kurzbz !== null && $semester) // NOTE(chris): on semester 0 show all?
$where['v.orgform_kurzbz'] = $orgform_kurzbz;
$result = $this->_ci->StudiengangModel->loadWhere($where);
return getData($result) ?: [];
}
public function orgform($path_template, $studiengang_kz)
{
$this->_ci->load->model('organisation/Studienordnung_model', 'StudienordnungModel');
$this->_ci->StudienordnungModel->addDistinct();
$this->_ci->StudienordnungModel->addSelect("FORMAT(
" . $this->_ci->StudienordnungModel->escape($path_template) . ",
LOWER(p.orgform_kurzbz)
) AS path");
$this->_ci->StudienordnungModel->addSelect("p.orgform_kurzbz AS name");
$this->_ci->StudienordnungModel->addSelect("studiengang_kz AS stg_kz");
$this->_ci->StudienordnungModel->addJoin('lehre.tbl_studienplan p', 'studienordnung_id');
$result = $this->_ci->StudienordnungModel->loadWhere([
'aktiv' => true,
'studiengang_kz' => $studiengang_kz,
'p.orgform_kurzbz !=' => 'DDP'
]);
return getData($result) ?: [];
}
public function studiensemester($path_template, $studiengang_kz)
{
$number_displayed_past_studiensemester = null;
$this->_ci->load->model('system/Variable_model', 'VariableModel');
$result = $this->_ci->VariableModel->getVariables(getAuthUID(), ['number_displayed_past_studiensemester']);
if (isError($result))
return [];
$data = getData($result);
if ($data && isset($data['number_displayed_past_studiensemester'])) {
$number_displayed_past_studiensemester = $data['number_displayed_past_studiensemester'];
} else {
$this->_ci->load->config('stv');
$number_displayed_past_studiensemester = $this->_ci->config->item('number_displayed_past_studiensemester_default');
}
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->_ci->StudiensemesterModel->addPlusMinus(null, $number_displayed_past_studiensemester);
$this->_ci->StudiensemesterModel->addSelect("studiensemester_kurzbz AS name");
$this->_ci->StudiensemesterModel->addSelect("FORMAT(
" . $this->_ci->StudiensemesterModel->escape($path_template) . ",
LOWER(studiensemester_kurzbz)
) AS path", false);
$this->_ci->StudiensemesterModel->addSelect($this->_ci->StudiensemesterModel->escape($studiengang_kz) . " AS stg_kz", false);
$this->_ci->StudiensemesterModel->addOrder('ende');
$result = $this->_ci->StudiensemesterModel->load();
return getData($result) ?: [];
}
}
@@ -13,6 +13,7 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
protected $dienstverhaeltnis_id;
protected $vertragsbestandteil_id;
protected $gehaltstyp_kurzbz;
protected $gehaltsanpassungtyp_kurzbz = '';
protected $von;
protected $bis;
protected $anmerkung;
@@ -21,6 +22,7 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
protected $valorisierungssperre;
protected $valorisierung;
protected $auszahlungen;
protected $gehaltstyp_bezeichnung;
protected $insertamum;
protected $insertvon;
@@ -39,6 +41,10 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
isset($data->dienstverhaeltnis_id) && $this->setDienstverhaeltnis_id($data->dienstverhaeltnis_id);
isset($data->vertragsbestandteil_id) && $this->setVertragsbestandteil_id($data->vertragsbestandteil_id);
isset($data->gehaltstyp_kurzbz) && $this->setGehaltstyp_kurzbz($data->gehaltstyp_kurzbz);
//isset($data->gehaltsanpassungtyp_kurzbz) && $this->setGehaltsanpassungtyp_kurzbz($data->gehaltsanpassungtyp_kurzbz);
if (!empty($data->gehaltsanpassungtyp_kurzbz)) {
$this->setGehaltsanpassungtyp_kurzbz($data->gehaltsanpassungtyp_kurzbz);
}
isset($data->von) && $this->setVon($data->von);
isset($data->bis) && $this->setBis($data->bis);
isset($data->anmerkung) && $this->setAnmerkung($data->anmerkung);
@@ -47,7 +53,8 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
isset($data->valorisierungssperre) && $this->setValorisierungssperre($data->valorisierungssperre);
isset($data->valorisierung) && $this->setValorisierung($data->valorisierung);
isset($data->auszahlungen) && $this->setAuszahlungen($data->auszahlungen);
isset($data->gehaltstyp_bezeichnung) && $this->setGehaltstyp_bezeichnung($data->gehaltstyp_bezeichnung);
isset($data->insertamum) && $this->setInsertamum($data->insertamum);
isset($data->insertvon) && $this->setInsertvon($data->insertvon);
isset($data->updateamum) && $this->setUpdateamum($data->updateamum);
@@ -75,6 +82,11 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
return $this->gehaltstyp_kurzbz;
}
public function getGehaltsanpassungtyp_kurzbz()
{
return $this->gehaltsanpassungtyp_kurzbz;
}
public function getVon()
{
return $this->von;
@@ -178,6 +190,13 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
return $this;
}
public function setGehaltsanpassungtyp_kurzbz($gehaltsanpassungtyp_kurzbz)
{
$this->markDirty('gehaltsanpassungtyp_kurzbz', $this->gehaltsanpassungtyp_kurzbz, $gehaltsanpassungtyp_kurzbz);
$this->gehaltsanpassungtyp_kurzbz = $gehaltsanpassungtyp_kurzbz;
return $this;
}
public function setVon($von)
{
$this->markDirty('von', $this->von, $von);
@@ -206,6 +225,10 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
$grundbetrag = number_format($grundbetrag, 2, '.', '');
}
$this->markDirty('grundbetrag', $this->grundbetrag, $grundbetrag);
if(in_array('grundbetrag', $this->modifiedcolumns))
{
$this->setBetrag_valorisiert($grundbetrag);
}
$this->grundbetrag = $grundbetrag;
return $this;
}
@@ -242,6 +265,13 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
return $this;
}
public function setGehaltstyp_bezeichnung($gehaltstyp_bezeichnung)
{
$this->markDirty('gehaltstyp_bezeichnung', $this->gehaltstyp_bezeichnung, $gehaltstyp_bezeichnung);
$this->gehaltstyp_bezeichnung = $gehaltstyp_bezeichnung;
return $this;
}
public function setInsertamum($insertamum)
{
$this->markDirty('insertamum', $this->insertamum, $insertamum);
@@ -284,6 +314,7 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
'dienstverhaeltnis_id' => $this->getDienstverhaeltnis_id(),
'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(),
'gehaltstyp_kurzbz' => $this->getGehaltstyp_kurzbz(),
'gehaltsanpassungtyp_kurzbz' => $this->getGehaltsanpassungtyp_kurzbz(),
'von' => $this->getVon(),
'bis' => $this->getBis(),
'anmerkung' => $this->getAnmerkung(),
@@ -312,6 +343,7 @@ class Gehaltsbestandteil extends AbstractBestandteil implements \JsonSerializabl
dienstverhaeltnis_id: {$this->getDienstverhaeltnis_id()}
vertragsbestandteil_id: {$this->getVertragsbestandteil_id()}
gehaltstyp_kurzbz: {$this->getGehaltstyp_kurzbz()}
gehaltsanpassungtyp_kurzbz: {$this->getGehaltsanpassungtyp_kurzbz()}
von: {$this->getVon()}
bis: {$this->getBis()}
anmerkung: {$this->getAnmerkung()}
+24 -19
View File
@@ -31,18 +31,20 @@ class Vertrag_model extends DB_Model
*/
public function save($person_id, $mitarbeiter_uid, $lehrveranstaltung_id, $lehreinheit_id, $projektarbeit_id = null, $vertragsstunden, $betrag, $studiensemester_kurzbz)
{
$person_id = (isset($person_id) && is_numeric($person_id))
$vertragstyp_kurzbz = (is_null($projektarbeit_id)) ? 'Lehrauftrag' : 'Betreuung';
$person_id = (isset($person_id) && is_numeric($person_id))
? $person_id
: show_error('peron_id must be set and numeric.');
$lehreinheit_id = (isset($lehreinheit_id) && is_numeric($lehreinheit_id))
? $lehreinheit_id
: show_error('lehreinheit_id must be set and numeric.');
$lehrveranstaltung_id = (isset($lehrveranstaltung_id) && is_numeric($lehrveranstaltung_id))
? $lehrveranstaltung_id
: show_error('lehrveranstaltung_id must be set and numeric.');
$projektarbeit_id = (isset($projektarbeit_id) && is_numeric($projektarbeit_id))
? $projektarbeit_id
: null;
$lehreinheit_id = (isset($lehreinheit_id) && is_numeric($lehreinheit_id))
? $lehreinheit_id
: (($vertragstyp_kurzbz == 'Betreuung') ? null : show_error('lehreinheit_id must be set and numeric.'));
$vertragsstunden = (isset($vertragsstunden) && is_numeric($vertragsstunden))
? $vertragsstunden
: 0;
@@ -53,7 +55,7 @@ class Vertrag_model extends DB_Model
? $mitarbeiter_uid
: show_error('mitarbeiter_uid must be set and a string value.');;
$vertragstyp_kurzbz = (is_null($projektarbeit_id)) ? 'Lehrauftrag' : 'Betreuung';
// First check if Vertrag already exists for that Lehrauftrag or for that Projektbetreuerauftrag
if ($vertragstyp_kurzbz == 'Lehrauftrag')
@@ -257,7 +259,7 @@ class Vertrag_model extends DB_Model
}
elseif ($vertragstyp_kurzbz == 'Betreuung')
{
$this->addSelect('lehreinheit_id');
$this->addSelect('lehreinheit_id, lehre.tbl_projektarbeit.lehrveranstaltung_id, lehre.tbl_projektarbeit.studiensemester_kurzbz');
$this->addJoin('lehre.tbl_projektbetreuer', 'vertrag_id');
$this->addJoin('lehre.tbl_projektarbeit', 'projektarbeit_id');
if ($result = $this->loadWhere(array('vertrag_id' => $vertrag_id)))
@@ -281,17 +283,22 @@ class Vertrag_model extends DB_Model
{
if ($result = getData($this->getLehreinheitID($vertrag_id)))
{
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->LehreinheitModel->addSelect($select);
if (!empty($result[0]->lehreinheit_id))
{
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->LehreinheitModel->addSelect($select);
if($result = $this->LehreinheitModel->load($result[0]->lehreinheit_id))
{
return success($result->retval);
}
else
{
return error('Fehler beim Laden der Lehreinheit');
if ($result = $this->LehreinheitModel->load($result[0]->lehreinheit_id))
{
return success($result->retval);
}
else
{
return error('Fehler beim Laden der Lehreinheit');
}
}
return success($result);
}
else
{
@@ -563,14 +570,13 @@ SELECT
null::integer as pruefung_id,
projektarbeit_id,
(tbl_projektbetreuer.stunden*tbl_projektbetreuer.stundensatz) as betrag1,
tbl_lehreinheit.studiensemester_kurzbz,
tbl_projektarbeit.studiensemester_kurzbz,
tbl_projektbetreuer.betreuerart_kurzbz,
(SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid)
as bezeichnung
FROM
lehre.tbl_projektbetreuer
JOIN lehre.tbl_projektarbeit USING(projektarbeit_id)
JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
WHERE
tbl_projektbetreuer.person_id=?
AND vertrag_id IS NULL
@@ -619,14 +625,13 @@ SELECT
null::integer as pruefung_id,
projektarbeit_id,
(tbl_projektbetreuer.stunden * tbl_projektbetreuer.stundensatz) as betrag,
tbl_lehreinheit.studiensemester_kurzbz,
tbl_projektarbeit.studiensemester_kurzbz,
tbl_projektbetreuer.betreuerart_kurzbz,
(SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid)
as bezeichnung, vertrag_id
FROM
lehre.tbl_projektbetreuer
JOIN lehre.tbl_projektarbeit USING(projektarbeit_id)
JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
WHERE
tbl_projektbetreuer.person_id=?
AND vertrag_id = ?
+106
View File
@@ -44,4 +44,110 @@ class Bisio_model extends DB_Model
else
return success("Bisio not found");
}
/**
* Gets outgoing students of certain Semester
* @param String studiensemester_kurzbz
* @return array of prestudent_ids
*/
public function getOutgoingsOfSemester($studiensemester_kurzbz)
{
$query = "
SELECT DISTINCT ps.prestudent_id, tbl_bisio.von, tbl_bisio.bis
FROM bis.tbl_bisio
JOIN public.tbl_student USING (student_uid)
JOIN public.tbl_prestudent ps USING (prestudent_id)
JOIN public.tbl_prestudentstatus pss ON (ps.prestudent_id = pss.prestudent_id)
JOIN public.tbl_studiensemester ss ON (pss.studiensemester_kurzbz = ss.studiensemester_kurzbz)
WHERE ss.studiensemester_kurzbz = ?
AND nation_code <> 'A'
AND (
tbl_bisio.von <= ss.ende
AND (
tbl_bisio.bis >= ss.start
OR tbl_bisio.bis IS NULL
)
)
";
return $this->execQuery($query, array($studiensemester_kurzbz));
}
/**
* Gets incoming students of certain Semester
* @param String studiensemester_kurzbz
* @return array of prestudent_ids
*/
public function getIncomingsOfSemester($studiensemester_kurzbz)
{
$query = "
SELECT DISTINCT ps.prestudent_id, tbl_bisio.von, tbl_bisio.bis
FROM bis.tbl_bisio
JOIN public.tbl_student USING (student_uid)
JOIN public.tbl_prestudent ps USING (prestudent_id)
JOIN public.tbl_prestudentstatus pss ON (ps.prestudent_id = pss.prestudent_id)
JOIN public.tbl_studiensemester ss ON (pss.studiensemester_kurzbz = ss.studiensemester_kurzbz)
WHERE ss.studiensemester_kurzbz = ?
AND nation_code = 'A'
AND (
tbl_bisio.von <= ss.ende
AND (
tbl_bisio.bis >= ss.start
OR tbl_bisio.bis IS NULL
)
)
";
return $this->execQuery($query, array($studiensemester_kurzbz));
}
public function isPrestudentOutgoing($studiensemester_kurzbz, $prestudent_id)
{
$query = "
SELECT
ps.prestudent_id, tbl_bisio.von, tbl_bisio.bis
FROM bis.tbl_bisio
JOIN public.tbl_student USING (student_uid)
JOIN public.tbl_prestudent ps USING (prestudent_id)
JOIN public.tbl_prestudentstatus pss ON (ps.prestudent_id = pss.prestudent_id)
JOIN public.tbl_studiensemester ss ON (pss.studiensemester_kurzbz = ss.studiensemester_kurzbz)
WHERE ss.studiensemester_kurzbz = ?
AND nation_code <> 'A'
AND (
tbl_bisio.von <= ss.ende
AND (
tbl_bisio.bis >= ss.start
OR tbl_bisio.bis IS NULL
)
)
AND ps.prestudent_id = ?
";
return $this->execQuery($query, array($studiensemester_kurzbz, $prestudent_id));
}
public function isPrestudentIncoming($studiensemester_kurzbz, $prestudent_id)
{
$query = "
SELECT
ps.prestudent_id, tbl_bisio.von, tbl_bisio.bis
FROM bis.tbl_bisio
JOIN public.tbl_student USING (student_uid)
JOIN public.tbl_prestudent ps USING (prestudent_id)
JOIN public.tbl_prestudentstatus pss ON (ps.prestudent_id = pss.prestudent_id)
JOIN public.tbl_studiensemester ss ON (pss.studiensemester_kurzbz = ss.studiensemester_kurzbz)
WHERE ss.studiensemester_kurzbz = ?
AND nation_code = 'A'
AND (
tbl_bisio.von <= ss.ende
AND (
tbl_bisio.bis >= ss.start
OR tbl_bisio.bis IS NULL
)
)
AND ps.prestudent_id = ?
";
return $this->execQuery($query, array($studiensemester_kurzbz, $prestudent_id));
}
}
+2 -1
View File
@@ -57,7 +57,7 @@ class Dokument_model extends DB_Model
$qry = " SELECT
a.akte_id,
a.bezeichnung,
dok.bezeichnung,
a.dokument_kurzbz,
a.titel_intern,
a.anmerkung_intern,
@@ -83,6 +83,7 @@ class Dokument_model extends DB_Model
inhalt
FROM
public.tbl_akte a
JOIN public.tbl_dokument dok ON (dok.dokument_kurzbz = a.dokument_kurzbz)
WHERE
a.person_id = ?
AND a.dokument_kurzbz NOT IN (
@@ -177,7 +177,7 @@ class Prestudentstatus_model extends DB_Model
* @param prestudent_id ID of the Prestudent.
* @param $status_kurzbz kurzbz of the status.
* @param $ausbildungssemester ausbildungssemester of the status.
* @param $studiensemester_kurzbz studiensemster of the status.
* @param $studiensemester_kurzbz studiensemester of the status.
*
* @return result object with all the status entries
*/
+1 -1
View File
@@ -204,7 +204,7 @@ class Student_model extends DB_Model
Events::trigger(
'generate_student_uid',
function ($value) use ($uid) {
function ($value) use (&$uid) {
$uid = $value;
},
$stgkzl,
@@ -719,7 +719,7 @@ EOSQL;
return "tag_data_agg AS (
SELECT
lehreinheit_id,
COALESCE(json_agg(tag ORDER BY done), '[]'::json) AS tags
COALESCE(json_agg(tag ORDER BY done, prioritaet), '[]'::json) AS tags
FROM (
SELECT DISTINCT ON (public.tbl_notiz.notiz_id)
tbl_notiz.notiz_id AS id,
@@ -728,7 +728,9 @@ EOSQL;
text AS notiz,
style,
erledigt AS done,
lehreinheit_id
lehreinheit_id,
prioritaet,
automatisiert
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
@@ -341,7 +341,7 @@ class Lehreinheitgruppe_model extends DB_Model
$this->db->where('lehreinheit_id', $lehreinheit_id);
$this->db->where('studiengang_kz', $gruppen_array->studiengang_kz);
if (!isEmptyString($gruppen_array->semester))
if (!isEmptyString((string)$gruppen_array->semester))
{
$this->db->where('semester', $gruppen_array->semester);
}
@@ -444,30 +444,37 @@ class Lehreinheitgruppe_model extends DB_Model
)
ELSE tbl_gruppe.beschreibung
END AS beschreibung");
$this->addSelect("CASE
WHEN tbl_lehreinheitgruppe.gruppe_kurzbz IS NULL THEN
(
SELECT EXISTS (
SELECT 1
FROM lehre.tbl_stundenplandev
WHERE lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id
AND studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz
AND semester = tbl_lehreinheitgruppe.semester
AND TRIM(COALESCE(verband, '')) = TRIM(tbl_lehreinheitgruppe.verband)
AND TRIM(COALESCE(gruppe, '')) = TRIM(tbl_lehreinheitgruppe.gruppe)
AND (gruppe_kurzbz IS NULL OR gruppe_kurzbz = '')
)
)
ELSE
$this->addSelect("
CASE
WHEN trim(COALESCE(tbl_lehreinheitgruppe.gruppe_kurzbz, '')) = '' THEN
(
SELECT EXISTS (
SELECT 1
FROM lehre.tbl_stundenplandev
WHERE lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id
AND gruppe_kurzbz = tbl_lehreinheitgruppe.gruppe_kurzbz
FROM lehre.tbl_stundenplandev sp
WHERE sp.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id
AND sp.studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz
AND sp.semester = tbl_lehreinheitgruppe.semester
AND trim(COALESCE(sp.verband, '')) = trim(COALESCE(tbl_lehreinheitgruppe.verband, ''))
AND trim(COALESCE(sp.gruppe, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe, ''))
AND trim(COALESCE(sp.gruppe_kurzbz, '')) = ''
)
)
END AS verplant");
ELSE
(
SELECT EXISTS (
SELECT 1
FROM lehre.tbl_stundenplandev sp
WHERE sp.lehreinheit_id = tbl_lehreinheitgruppe.lehreinheit_id
AND sp.studiengang_kz = tbl_lehreinheitgruppe.studiengang_kz
AND sp.semester = tbl_lehreinheitgruppe.semester
AND trim(COALESCE(sp.verband, '')) = trim(COALESCE(tbl_lehreinheitgruppe.verband, ''))
AND trim(COALESCE(sp.gruppe, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe, ''))
AND trim(COALESCE(sp.gruppe_kurzbz, '')) = trim(COALESCE(tbl_lehreinheitgruppe.gruppe_kurzbz, ''))
)
)
END AS verplant
");
$this->addJoin('tbl_studiengang', 'studiengang_kz', 'LEFT');
$this->addJoin('public.tbl_gruppe', 'gruppe_kurzbz', 'LEFT');
@@ -85,9 +85,18 @@ class Lehreinheitmitarbeiter_model extends DB_Model
public function getLektorenByLe($lehreinheit_id)
{
$this->addSelect('vorname, nachname, tbl_lehreinheitmitarbeiter.*, stundenplan.verplant');
$this->addSelect('tbl_person.vorname, tbl_person.nachname, tbl_lehreinheitmitarbeiter.*, stundenplan.verplant,
COALESCE(insertvonperson.vorname || \' \' || insertvonperson.nachname, tbl_lehreinheitmitarbeiter.insertvon) as insertvon,
COALESCE(updatevonperson.vorname || \' \' || updatevonperson.nachname, tbl_lehreinheitmitarbeiter.updatevon) as updatevon');
$this->addJoin('tbl_benutzer', 'uid = mitarbeiter_uid');
$this->addJoin('tbl_person', 'person_id');
$this->addJoin('tbl_benutzer insertvonbenutzer', 'insertvonbenutzer.uid = tbl_lehreinheitmitarbeiter.insertvon', 'LEFT');
$this->addJoin('tbl_person insertvonperson', 'insertvonperson.person_id = insertvonbenutzer.person_id', 'LEFT');
$this->addJoin('tbl_benutzer updatevonbenutzer', 'updatevonbenutzer.uid = tbl_lehreinheitmitarbeiter.updatevon', 'LEFT');
$this->addJoin('tbl_person updatevonperson', 'updatevonperson.person_id = updatevonbenutzer.person_id', 'LEFT');
$this->addJoin('(
SELECT 1 as verplant, lehreinheit_id, mitarbeiter_uid
@@ -1245,7 +1245,7 @@ class Lehrveranstaltung_model extends DB_Model
{
return "
SELECT
lehrveranstaltung_id, tbl_lehrveranstaltung.kurzbz as lv_kurzbz, tbl_lehrveranstaltung.bezeichnung as lv_bezeichnung, bezeichnung_english as lv_bezeichnung_english, studiengang_kz,
distinct on (lehrveranstaltung_id) 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,
@@ -1263,6 +1263,39 @@ class Lehrveranstaltung_model extends DB_Model
";
}
/**
* Gets lehrveranstaltungen of Studienplan of a certain lva_id set
* used if a bigger set of lva id is already available and it needs to be checked against a certain studienplan aswell
* @param $studienplan_id ID des Studienplans
* @param $lva_ids LVA_ID welche abgegleicht werden sollen
* @return array|null
*/
public function getLvsByStudienplanByLvaIDs($studienplan_id, $lva_ids)
{
$params = array($studienplan_id, $lva_ids);
$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 = ?
AND tbl_studienplan_lehrveranstaltung.lehrveranstaltung_id IN ?
";
$qry .= " ORDER BY stpllv_sort, semester, sort";
return $this->execQuery($qry, $params);
}
public function getAllOe($lv_id)
{
$qry = "SELECT DISTINCT oe_kurzbz
@@ -29,10 +29,14 @@ class Lvgesamtnote_model extends DB_Model
$this->addSelect("lv.bezeichnung AS lehrveranstaltung_bezeichnung");
$this->addSelect("lv.studiengang_kz");
$this->addSelect("UPPER(stg.typ || stg.kurzbz) AS studiengang");
$this->addSelect("person.vorname");
$this->addSelect("person.nachname");
$this->addJoin("lehre.tbl_note n", "note");
$this->addJoin("lehre.tbl_lehrveranstaltung lv", "lehrveranstaltung_id");
$this->addJoin("public.tbl_studiengang stg", "studiengang_kz");
$this->addJoin("public.tbl_benutzer benutzer", "uid = student_uid", "LEFT");
$this->addJoin("public.tbl_person person", "person_id", "LEFT");
$this->db->where($this->dbTable . ".freigabedatum <", "NOW()", false);
+10 -11
View File
@@ -50,8 +50,7 @@ class Paabgabe_model extends DB_Model
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 lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN public.tbl_studiengang ON(tbl_lehrveranstaltung.studiengang_kz=tbl_studiengang.studiengang_kz)
JOIN campus.tbl_paabgabetyp USING(paabgabetyp_kurzbz)
WHERE
@@ -66,16 +65,16 @@ class Paabgabe_model extends DB_Model
$query = "SELECT projektarbeit_id, paabgabe_id, paabgabetyp_kurzbz, fixtermin, datum, campus.tbl_paabgabe.kurzbz, campus.tbl_paabgabetyp.bezeichnung, campus.tbl_paabgabe.abgabedatum,
campus.tbl_paabgabe.insertvon, campus.tbl_paabgabe.insertamum, campus.tbl_paabgabe.updatevon, campus.tbl_paabgabe.updateamum,
campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid, tbl_projektarbeit.note, lehre.tbl_projektarbeit.titel,
campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid,
lehre.tbl_projektarbeit.note as projektarbeit_note, lehre.tbl_projektarbeit.titel,
UPPER(tbl_studiengang.typ) as stgtyp, UPPER(tbl_studiengang.kurzbz) as stgkz, public.tbl_studiengang.studiengang_kz,
public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_lehreinheit.studiensemester_kurzbz,
public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_projektarbeit.studiensemester_kurzbz,
public.tbl_person.anrede, public.tbl_person.titelpre, public.tbl_person.vorname, public.tbl_person.nachname, public.tbl_person.titelpost
FROM campus.tbl_paabgabe
JOIN campus.tbl_paabgabetyp USING (paabgabetyp_kurzbz)
JOIN lehre.tbl_projektarbeit USING (projektarbeit_id)
JOIN lehre.tbl_lehreinheit using(lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id)
JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN public.tbl_studiengang ON(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz)
JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid)
JOIN public.tbl_person USING (person_id)
@@ -91,9 +90,10 @@ class Paabgabe_model extends DB_Model
$queryParams = [$interval];
$query = "SELECT projektarbeit_id, paabgabe_id, paabgabetyp_kurzbz, fixtermin, datum, campus.tbl_paabgabe.kurzbz, campus.tbl_paabgabetyp.bezeichnung, campus.tbl_paabgabe.abgabedatum,
campus.tbl_paabgabe.insertvon, campus.tbl_paabgabe.insertamum, campus.tbl_paabgabe.updatevon, campus.tbl_paabgabe.updateamum,
campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid, tbl_projektarbeit.note, lehre.tbl_projektarbeit.titel,
campus.tbl_paabgabe.note, upload_allowed, beurteilungsnotiz, student_uid,
lehre.tbl_projektarbeit.note as projektarbeit_note, lehre.tbl_projektarbeit.titel,
UPPER(tbl_studiengang.typ) as stgtyp, UPPER(tbl_studiengang.kurzbz) as stgkz, public.tbl_studiengang.studiengang_kz,
public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_lehreinheit.studiensemester_kurzbz,
public.tbl_studiengang.oe_kurzbz as stg_oe_kurzbz, tbl_projektarbeit.studiensemester_kurzbz,
lehre.tbl_projektbetreuer.betreuerart_kurzbz, lehre.tbl_projektbetreuer.person_id,
public.tbl_person.anrede, public.tbl_person.titelpre, public.tbl_person.vorname, public.tbl_person.nachname, public.tbl_person.titelpost
@@ -101,8 +101,7 @@ class Paabgabe_model extends DB_Model
JOIN campus.tbl_paabgabetyp USING (paabgabetyp_kurzbz)
JOIN lehre.tbl_projektarbeit USING (projektarbeit_id)
JOIN lehre.tbl_projektbetreuer USING (projektarbeit_id)
JOIN lehre.tbl_lehreinheit using(lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung using(lehrveranstaltung_id)
JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
JOIN public.tbl_studiengang on(lehre.tbl_lehrveranstaltung.studiengang_kz = public.tbl_studiengang.studiengang_kz)
JOIN public.tbl_benutzer ON (public.tbl_benutzer.uid = student_uid)
JOIN public.tbl_person ON (public.tbl_benutzer.person_id = public.tbl_person.person_id)
@@ -25,7 +25,7 @@ class Projektarbeit_model extends DB_Model
{
$qry = "SELECT
pa.*, tbl_projekttyp.bezeichnung,
tbl_lehreinheit.studiensemester_kurzbz, tbl_lehrveranstaltung.lehrveranstaltung_id,
pa.studiensemester_kurzbz, pa.lehrveranstaltung_id,
tbl_firma.name AS firma_name,
(
SELECT
@@ -41,7 +41,6 @@ class Projektarbeit_model extends DB_Model
FROM
lehre.tbl_projektarbeit pa
JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_firma USING (firma_id)
WHERE
@@ -57,7 +56,7 @@ class Projektarbeit_model extends DB_Model
if (isset($studiensemester_kurzbz))
{
$qry .= ' AND tbl_lehreinheit.studiensemester_kurzbz=?';
$qry .= ' AND tbl_projektarbeit.studiensemester_kurzbz=?';
$params[] = $studiensemester_kurzbz;
}
@@ -134,7 +133,7 @@ class Projektarbeit_model extends DB_Model
projektarbeit_id,
lehre.tbl_projekttyp.bezeichnung as projekttypbezeichnung,
lehre.tbl_projekttyp.projekttyp_kurzbz as projekttypkurzbz,
lehre.tbl_lehreinheit.studiensemester_kurzbz,
lehre.tbl_projektarbeit.studiensemester_kurzbz,
lehre.tbl_lehrveranstaltung.studiengang_kz,
public.tbl_studiengang.kurzbzlang,
lehre.tbl_projektarbeit.note as note,
@@ -157,7 +156,6 @@ class Projektarbeit_model extends DB_Model
LEFT JOIN public.tbl_benutzer USING(person_id)
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
LEFT JOIN lehre.tbl_betreuerart USING(betreuerart_kurzbz)
LEFT JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING(lehrveranstaltung_id)
LEFT JOIN public.tbl_mitarbeiter ON(public.tbl_mitarbeiter.mitarbeiter_uid = public.tbl_benutzer.uid)
LEFT JOIN public.tbl_studiengang USING(studiengang_kz)
@@ -366,7 +364,7 @@ class Projektarbeit_model extends DB_Model
tbl_studiengang.typ, tbl_studiengang.kurzbz,
tbl_projektarbeit.projekttyp_kurzbz, tbl_projekttyp.bezeichnung,
tbl_projektarbeit.titel, tbl_projektarbeit.projektarbeit_id, tbl_projektarbeit.note,
student_benutzer.uid, tbl_student.matrikelnr, tbl_lehreinheit.studiensemester_kurzbz, public.tbl_student.student_uid,
student_benutzer.uid, tbl_student.matrikelnr, tbl_projektarbeit.studiensemester_kurzbz, public.tbl_student.student_uid,
lehre.tbl_projektarbeit.sprache,
lehre.tbl_projektarbeit.seitenanzahl,
@@ -430,7 +428,6 @@ class Projektarbeit_model extends DB_Model
LEFT JOIN public.tbl_benutzer student_benutzer ON student_benutzer.uid = lehre.tbl_projektarbeit.student_uid
LEFT JOIN public.tbl_person student_person ON student_benutzer.person_id = student_person.person_id
LEFT JOIN public.tbl_student ON student_benutzer.uid = public.tbl_student.student_uid
LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_studiengang ON public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
@@ -503,7 +500,7 @@ class Projektarbeit_model extends DB_Model
student_person.vorname AS student_vorname,
student_person.nachname AS student_nachname,
public.tbl_student.matrikelnr,
tbl_lehreinheit.studiensemester_kurzbz,
tbl_projektarbeit.studiensemester_kurzbz,
betreuer_benutzer.uid AS betreuer_benutzer_uid,
betreuer_person.titelpre AS betreuer_titelpre,
betreuer_person.vorname AS betreuer_vorname,
@@ -565,7 +562,6 @@ class Projektarbeit_model extends DB_Model
LEFT JOIN public.tbl_benutzer student_benutzer ON student_benutzer.uid = lehre.tbl_projektarbeit.student_uid
LEFT JOIN public.tbl_person student_person ON student_benutzer.person_id = student_person.person_id
LEFT JOIN public.tbl_student ON student_benutzer.uid = public.tbl_student.student_uid
LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_studiengang ON public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
@@ -633,7 +629,7 @@ class Projektarbeit_model extends DB_Model
student_person.vorname AS student_vorname,
student_person.nachname AS student_nachname,
public.tbl_student.matrikelnr,
tbl_lehreinheit.studiensemester_kurzbz,
tbl_projektarbeit.studiensemester_kurzbz,
betreuer_benutzer.uid AS betreuer_benutzer_uid,
betreuer_person.titelpre AS betreuer_titelpre,
betreuer_person.vorname AS betreuer_vorname,
@@ -695,7 +691,6 @@ class Projektarbeit_model extends DB_Model
LEFT JOIN public.tbl_benutzer student_benutzer ON student_benutzer.uid = lehre.tbl_projektarbeit.student_uid
LEFT JOIN public.tbl_person student_person ON student_benutzer.person_id = student_person.person_id
LEFT JOIN public.tbl_student ON student_benutzer.uid = public.tbl_student.student_uid
LEFT JOIN lehre.tbl_lehreinheit USING (lehreinheit_id)
LEFT JOIN lehre.tbl_lehrveranstaltung USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_studiengang ON public.tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
LEFT JOIN lehre.tbl_projekttyp USING (projekttyp_kurzbz)
@@ -269,4 +269,37 @@ class Projektbetreuer_model extends DB_Model
return $this->execQuery($qry, array($projektarbeit_id));
}
/**
* Gets anrede, name and mail address of a Betreuer by person_id.
* Same account preference as getAllBetreuerOfProjektarbeit, but not bound to a single Projektarbeit.
* @param int $person_id
* @return array success with one row or error
*/
public function getBetreuerByPersonId($person_id)
{
$qry = "SELECT DISTINCT ON (pers.person_id) pers.person_id, anrede,
trim(COALESCE(titelpre,'')||' '||COALESCE(vorname,'')||' '||COALESCE(nachname,'')||' '||COALESCE(titelpost,'')) as first,
ben.uid,
(
SELECT kontakt
FROM public.tbl_kontakt
WHERE kontakttyp = 'email'
AND person_id = pers.person_id
ORDER BY
CASE WHEN zustellung THEN 0 ELSE 1 END,
insertamum DESC NULLS LAST
LIMIT 1
) AS private_email
FROM public.tbl_person pers
LEFT JOIN public.tbl_benutzer ben USING (person_id)
LEFT JOIN public.tbl_mitarbeiter ma ON ben.uid = ma.mitarbeiter_uid
WHERE (ben.aktiv OR ben.aktiv IS NULL)
AND pers.person_id = ?
ORDER BY pers.person_id, CASE WHEN ma.mitarbeiter_uid IS NULL THEN 1 ELSE 0 END, /*Mitarbeiter account first*/
CASE WHEN ben.uid IS NULL THEN 1 ELSE 0 END, /*user with account first*/
ben.insertamum";
return $this->execReadOnlyQuery($qry, array($person_id));
}
}
@@ -188,6 +188,7 @@ class Studierendenantrag_model extends DB_Model
* Get the studiengang and ausbildungssemester the student was in
* for the studiensemester the antrag was committed for
*
*
* @param integer $antrag_id
*
* @return stdClass
@@ -242,6 +243,28 @@ class Studierendenantrag_model extends DB_Model
);
}
/**
* Get the studiengang and the studienplan the student is in
*
* @param integer $antrag_id
*
* @return stdClass
*/
public function getStgAndDetails($antrag_id)
{
$this->addSelect('p.studiengang_kz');
$this->addSelect('stg.orgform_kurzbz');
$this->addSelect('stg.bezeichnung');
$this->addJoin('public.tbl_prestudent p', 'prestudent_id');
$this->addJoin('public.tbl_studiengang stg', 'studiengang_kz');
$this->addLimit(1);
return $this->load(
$antrag_id
);
}
public function getStgEmail($antrag_id)
{
$this->addJoin('public.tbl_prestudent p', 'prestudent_id');
@@ -148,7 +148,7 @@ class Zeugnisnote_model extends DB_Model
*
* @return object
*/
public function getZeugnisnoten($student_uid, $studiensemester_kurzbz)
public function getZeugnisnoten($student_uid, $studiensemester_kurzbz, $lehrveranstaltung_id = null)
{
$params = array();
$where='';
@@ -163,6 +163,11 @@ class Zeugnisnote_model extends DB_Model
$where.=" AND vw_student_lehrveranstaltung.studiensemester_kurzbz= ?";
$params[] = $studiensemester_kurzbz;
}
if($lehrveranstaltung_id != null)
{
$where .= " AND vw_student_lehrveranstaltung.lehrveranstaltung_id = ?";
$params[] = $lehrveranstaltung_id;
}
$where2='';
@@ -176,6 +181,11 @@ class Zeugnisnote_model extends DB_Model
$where2 .= " AND studiensemester_kurzbz= ?";
$params[] = $studiensemester_kurzbz;
}
if($lehrveranstaltung_id != null)
{
$where2 .=" AND lehrveranstaltung_id = ?";
$params[] = $lehrveranstaltung_id;
}
$qry = "SELECT
a.*,
@@ -188,7 +198,10 @@ class Zeugnisnote_model extends DB_Model
lv.semester AS semester_lv,
lv.ects AS ects_lv,
lv.zeugnis,
lv.bezeichnung_english AS lehrveranstaltung_bezeichnung_english
lv.bezeichnung_english AS lehrveranstaltung_bezeichnung_english,
s.verband,
person.vorname,
person.nachname
FROM (
SELECT vw_student_lehrveranstaltung.lehrveranstaltung_id, uid,
vw_student_lehrveranstaltung.studiensemester_kurzbz, note, punkte, uebernahmedatum, benotungsdatum,
@@ -231,6 +244,8 @@ class Zeugnisnote_model extends DB_Model
ORDER BY sort
) a
LEFT JOIN public.tbl_student s ON (a.uid = s.student_uid)
LEFT JOIN public.tbl_benutzer benutzer ON benutzer.uid = s.student_uid
LEFT JOIN public.tbl_person person ON benutzer.person_id = person.person_id
LEFT JOIN public.tbl_studiengang stg1 ON (s.studiengang_kz = stg1.studiengang_kz)
LEFT JOIN lehre.tbl_lehrveranstaltung lv USING (lehrveranstaltung_id)
LEFT JOIN public.tbl_studiengang stg2 ON (lv.studiengang_kz = stg2.studiengang_kz)";
@@ -457,6 +457,7 @@ class Studiengang_model extends DB_Model
*/
public function getLeitung($studiengang_kz = null)
{
$this->addDistinct();
$this->addSelect('uid, studiengang_kz, oe_kurzbz, vorname, nachname, email, titelpre, titelpost, alias');
$this->addJoin('public.tbl_benutzerfunktion', 'oe_kurzbz');
$this->addJoin('public.tbl_benutzer', 'uid');
@@ -218,7 +218,7 @@ class Studiensemester_model extends DB_Model
*/
public function getByDate($date)
{
// gets the studiensemster of a date or the next closest previous studiensemester if a date is not within a studiensemester
// gets the studiensemester of a date or the next closest previous studiensemester if a date is not within a studiensemester
$query = "
SELECT studiensemester_kurzbz, start, ende
FROM public.tbl_studiensemester
@@ -229,6 +229,82 @@ class Studiensemester_model extends DB_Model
return $this->execQuery($query, array($date,$date,$date,$date));
}
/**
* Gets all Studiensemester where the range dates are contained
* or the nearest if date is not contained
* @param $from
* @param $to
* @return array|null
*/
public function getContainingOrNearestByDateRange($from, $to)
{
if (date_format(date_create($from), 'Y-m-d') > (date_format(date_create($to), 'Y-m-d')))
return success(array());
$query = <<<EOSQL
WITH semester_interval_startdate AS (
SELECT
s.*
FROM
public.tbl_studiensemester s
WHERE
{$this->db->escape($from)}::date BETWEEN s.start AND s.ende
ORDER BY
s.start DESC
LIMIT 1
),
semester_interval_enddate AS (
SELECT
s.*
FROM
public.tbl_studiensemester s
WHERE
{$this->db->escape($to)}::date BETWEEN s.start AND s.ende
ORDER BY
s.start DESC
LIMIT 1
),
nearest_semester_interval_startdate AS (
SELECT
LEAST(ABS(s.start - {$this->db->escape($from)}::date), ABS(s.ende - {$this->db->escape($from)}::date)) AS mindiff,
s.*
FROM
public.tbl_studiensemester s
WHERE
s.ende < {$this->db->escape($from)}::date
ORDER BY
1 ASC
LIMIT 1
),
nearest_semester_interval_enddate AS (
SELECT
LEAST(ABS(s.start - {$this->db->escape($to)}::date), ABS(s.ende - {$this->db->escape($to)}::date)) AS mindiff,
s.*
FROM
public.tbl_studiensemester s
WHERE
s.start > {$this->db->escape($to)}::date
ORDER BY
1 ASC
LIMIT 1
)
SELECT
COALESCE(
(SELECT studiensemester_kurzbz FROM semester_interval_startdate),
(SELECT studiensemester_kurzbz FROM nearest_semester_interval_startdate)
) AS studiensemester_kurzbz
UNION
SELECT
COALESCE(
(SELECT studiensemester_kurzbz FROM semester_interval_enddate),
(SELECT studiensemester_kurzbz FROM nearest_semester_interval_enddate)
) AS studiensemester_kurzbz
EOSQL;
return $this->execReadonlyQuery($query);
}
/**
* Gets all Studiensemester between two dates
* @param $from
@@ -348,5 +348,64 @@ class Benutzerfunktion_model extends DB_Model
return success($funktionJson);
}
/**
* Gets all Prestudents with details for a given Benutzerfunktion and optionally semester
*
* @param String $studiensemester_kurzbz
* @return object |null
*/
public function getPrestudentsOfJgv($semester)
{
$query = "
SELECT DISTINCT ps.prestudent_id, bf.datum_von, bf.datum_bis
FROM public.tbl_benutzerfunktion bf
JOIN public.tbl_benutzer bn USING (uid)
JOIN public.tbl_prestudent ps USING (person_id)
JOIN public.tbl_prestudentstatus pss ON (ps.prestudent_id = pss.prestudent_id)
JOIN public.tbl_studiensemester ss ON (pss.studiensemester_kurzbz = ss.studiensemester_kurzbz)
WHERE ss.studiensemester_kurzbz = ?
AND bf.funktion_kurzbz = 'jgv'
AND (
bf.datum_von <= ss.ende
AND (
bf.datum_bis >= ss.start
OR bf.datum_bis IS NULL
)
)
";
return $this->execQuery($query, array($semester));
}
/**
* Checks if a certain prestudent has the Benutzerfunktion jgv for a certain semester
*
* @param String $studiensemester_kurzbz
* @param $prestudent_id
* @return object |null
*/
public function isJgv($semester, $prestudent_id)
{
$query = "
SELECT ps.prestudent_id, ss.start as von, ss.ende as bis
FROM public.tbl_benutzerfunktion bf
JOIN public.tbl_benutzer bn USING (uid)
JOIN public.tbl_prestudent ps USING (person_id)
JOIN public.tbl_prestudentstatus pss ON (ps.prestudent_id = pss.prestudent_id)
JOIN public.tbl_studiensemester ss ON (pss.studiensemester_kurzbz = ss.studiensemester_kurzbz)
WHERE ss.studiensemester_kurzbz = ?
AND bf.funktion_kurzbz = 'jgv'
AND (
bf.datum_von <= ss.ende
AND (
bf.datum_bis >= ss.start
OR bf.datum_bis IS NULL
)
)
AND ps.prestudent_id = ?
";
return $this->execQuery($query, array($semester, $prestudent_id));
}
}
+55
View File
@@ -296,4 +296,59 @@ class Notiz_model extends DB_Model
return $this->loadWhere(array('anrechnung_id' => $anrechnung_id));
}
/**
* check if a given Tag for a certain notizzuordnung id is valid
*
* @param $tag typ_kurzbz to check
* @param $typeId typeId to check
* @param $id id to check
* @param $von start of time period or NULL
* @param $bis end of time period or NULL
*
* @return array
*/
public function checkIfExistingTag($tag, $typeId, $id, $von=null, $bis=null)
{
$query = "
SELECT *
FROM public.tbl_notiz
JOIN public.tbl_notizzuordnung nz USING (notiz_id)
WHERE typ = ?
AND {$typeId} = ?
AND (
start IS NULL
OR ende IS NULL
OR (start <= ? AND ende >= ?)
)
";
return $this->execQuery($query, [$tag, $id, $bis, $von]);
}
/**
* returns all existing tags of a certain tag within a time period
*
* @param $tag typ_kurzbz of tag
* @param $von start of time period or NULL
* @param $bis end of time period or NULL
*
* @return array
*/
public function getAllTags($tag, $von=null, $bis=null)
{
$query = "
SELECT *
FROM public.tbl_notiz
JOIN public.tbl_notizzuordnung nz USING (notiz_id)
WHERE typ = ?
AND (
start IS NULL
OR ende IS NULL
OR (start <= ? AND ende >= ?)
);
";
return $this->execQuery($query, array($tag, $bis, $von));
}
}
+50 -1
View File
@@ -149,7 +149,7 @@ class Person_model extends DB_Model
* @param $filter Term to search for.
* @return DB-result
*/
public function searchPerson($filter)
public function searchPerson($filter, $mode=null)
{
$this->addSelect('vorname, nachname, gebdatum, person_id, titelpre, titelpost');
$this->addSelect("CASE
@@ -161,6 +161,26 @@ class Person_model extends DB_Model
THEN 'Student'
ELSE 'Person'
END AS status");
if($mode == 'mitMaUid')
{
$this->addSelect("(
SELECT m.mitarbeiter_uid
FROM public.tbl_benutzer b
JOIN public.tbl_mitarbeiter m
ON b.uid = m.mitarbeiter_uid
WHERE b.person_id = tbl_person.person_id
LIMIT 1
)
AS uid");
$this->addOrder('uid, lower(nachname), lower(vorname)');
}
else
{
$this->addOrder('lower(nachname), lower(vorname)');
}
$result = $this->loadWhere(
'lower(nachname) like '.$this->db->escape('%'.mb_strtolower($filter).'%')."
OR lower(vorname) like ".$this->db->escape('%'.$filter.'%')."
@@ -433,4 +453,33 @@ class Person_model extends DB_Model
return $this->execReadOnlyQuery($qry, [$person_id]);
}
//just a test function for a person_id tag
//alle personen die innerhalb dieses Zeitraumens 55 werden
public function getFiftyFivers($von, $bis)
{
$qry = "
SELECT
p.person_id
FROM public.tbl_person p
WHERE p.gebdatum >= DATE ? - INTERVAL '55 years'
AND p.gebdatum <= DATE ? - INTERVAL '55 years';
";
return $this->execReadOnlyQuery($qry, [$von, $bis]);
}
//just a test function for a person_id tag
//check if Person gets 55 in this time
public function isFiftyFive($von, $bis, $person_id)
{
$qry = "
SELECT
p.person_id
FROM public.tbl_person p
WHERE p.gebdatum >= DATE ? - INTERVAL '55 years'
AND p.gebdatum <= DATE ? - INTERVAL '55 years'
AND p.persond_id = ?;
";
return $this->execReadOnlyQuery($qry, [$von, $bis, $person_id]);
}
}
@@ -135,4 +135,15 @@ class Reservierung_model extends DB_Model
return $this->execQuery($query, [$uid, $uid]);
}
public function lektorHasReservierung($uid, $datum, $stunde)
{
$qry = "SELECT reservierung_id, uid, stg_kurzbz, ort_kurzbz, semester, verband, gruppe, gruppe_kurzbz, datum, stunde
FROM lehre.vw_reservierung
WHERE uid = ?
AND datum = ?
AND stunde = ?";
return $this->execReadOnlyQuery($qry, [$uid, $datum, $stunde]);
}
}
@@ -333,6 +333,68 @@ class Stundenplan_model extends DB_Model
", [$start_date, $end_date, $lv_id]);
}
public function getStundenplanLE($lehreinheit, $start_date, $end_date, $stundenplan)
{
$qry = "
WITH lehreinheiten AS (
SELECT lehreinheit_id FROM lehre.tbl_lehreinheit WHERE lehreinheit_id = ?
), " . $this->getStundenplanCTE($stundenplan) . "
SELECT *
FROM stundenplanentries
";
return $this->execReadOnlyQuery($qry, array($lehreinheit, $start_date, $end_date));
}
public function getStundenplanLV($lehrveranstaltung_id, $start_date, $end_date, $stundenplan)
{
$qry = "
WITH lehreinheiten AS (
SELECT lehreinheit_id
FROM lehre.tbl_lehreinheit
JOIN tbl_studiensemester USING(studiensemester_kurzbz)
WHERE lehrveranstaltung_id = ?
AND tbl_studiensemester.start >= ? AND tbl_studiensemester.ende <= ?
), " . $this->getStundenplanCTE($stundenplan) . "
SELECT *
FROM stundenplanentries
";
return $this->execReadOnlyQuery($qry, array($lehrveranstaltung_id, $start_date, $end_date, $start_date, $end_date));
}
private function getStundenplanCTE($stundenplan)
{
return "entries AS (
SELECT
datum, min(stunde) as stunde_beginn, max(stunde) as stunde_ende,
array_agg(DISTINCT(
CASE WHEN gruppe_kurzbz is not null THEN gruppe_kurzbz
ELSE (UPPER(stg_typ || stg_kurzbz) || COALESCE(semester,'0') || COALESCE(verband,'') || COALESCE(gruppe,''))
END)) as gruppen_kuerzel,
array_agg(DISTINCT CONCAT(vorname || ' ' || nachname)) as lektorname,
array_agg(DISTINCT stundenplan.ort_kurzbz) as ort_kurzbz,
array_agg(DISTINCT titel) as titel,
lehrfach_bez, stundenplan.lehreinheit_id, lehrveranstaltung_id
FROM lehre.vw_$stundenplan as stundenplan
JOIN public.tbl_mitarbeiter ON stundenplan.uid = tbl_mitarbeiter.mitarbeiter_uid
JOIN tbl_benutzer ON tbl_mitarbeiter.mitarbeiter_uid = tbl_benutzer.uid
JOIN tbl_person USING(person_id)
JOIN lehreinheiten ON stundenplan.lehreinheit_id = lehreinheiten.lehreinheit_id
WHERE datum >= ? AND datum <= ?
GROUP BY datum, unr, stundenplan.lehreinheit_id, lehrveranstaltung_id, lehrfach_bez, lehrfach_bez
ORDER BY datum, min(stunde), unr, lehreinheit_id
),
stundenplanentries AS (
SELECT
entries.*,
stundeb.beginn AS beginn,
stundee.ende AS ende
FROM entries
JOIN lehre.tbl_stunde stundeb ON stundeb.stunde = entries.stunde_beginn
JOIN lehre.tbl_stunde stundee ON stundee.stunde = entries.stunde_ende
)";
}
/**
* queries Stundenplan and filters by assigned ma_kurzbz, very similar to get by LVA
*
@@ -542,11 +604,17 @@ class Stundenplan_model extends DB_Model
{
foreach($semester_date_range as $sem_date => $sem_date_range)
{
if(!array_key_exists($sem_date,$studentlehrverbaende) || count($studentlehrverbaende[$sem_date]) == 0)
if(!array_key_exists($sem,$studentlehrverbaende) || count($studentlehrverbaende[$sem]) == 0)
{
continue;
}
foreach($studentlehrverbaende[$sem_date] as $key=>$lehrverband)
$studlvbds = array_filter(
$studentlehrverbaende[$sem],
function($value) use ($sem_date) {
return $value->studiensemester_kurzbz === $sem_date;
}
);
foreach($studlvbds as $key=>$lehrverband)
{
$query .= "(((sp.studiengang_kz = ".$this->escape($lehrverband->studiengang_kz)." AND sp.semester = ".$this->escape($lehrverband->semester)." AND sp.verband = ".$this->escape($lehrverband->verband)." AND sp.gruppe = ".$this->escape($lehrverband->gruppe)." AND sp.datum BETWEEN ".$this->escape($sem_date_range->start)." AND ".$this->escape($sem_date_range->ende).")";
// Eintraege fuer den ganzen Verband
@@ -241,4 +241,15 @@ class Stundenplandev_model extends DB_Model
return $this->delete(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
}
public function lektorHasStundenplandevEintrag($uid, $datum, $stunde)
{
$qry = "SELECT stundenplandev_id, lektor, stg_kurzbz, ort_kurzbz, semester, verband, gruppe, gruppe_kurzbz, datum, stunde
FROM lehre.vw_stundenplandev
WHERE uid = ?
AND datum = ?
AND stunde = ?";
return $this->execReadOnlyQuery($qry, [$uid, $datum, $stunde]);
}
}
@@ -61,4 +61,40 @@ class Zeitsperre_model extends DB_Model
return $this->execQuery($qry);
}
public function checkIfZeitsperreExists($uid, $datum, $stunde)
{
$this->db->select("*");
$this->db->where('mitarbeiter_uid', $uid);
$this->db->where('zeitsperretyp_kurzbz !=', 'ZVerfueg');
$this->db->group_start();
$this->db->where('vondatum <', $datum);
$this->db->or_group_start();
$this->db->where('vondatum', $datum);
$this->db->group_start();
$this->db->where('vonstunde <=', $stunde);
$this->db->or_where('vonstunde IS NULL', null, false);
$this->db->group_end();
$this->db->group_end();
$this->db->group_end();
$this->db->group_start();
$this->db->where('bisdatum >', $datum);
$this->db->or_group_start();
$this->db->where('bisdatum', $datum);
$this->db->group_start();
$this->db->where('bisstunde >=', $stunde);
$this->db->or_where('bisstunde IS NULL', null, false);
$this->db->group_end();
$this->db->group_end();
$this->db->group_end();
return $this->load();
}
}
@@ -0,0 +1,83 @@
<?php
class Tabulator_preset_model extends DB_Model
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->dbTable = 'public.tbl_tabulator_presets';
$this->pk = ['preset_id'];
$this->hasSequence = true;
$this->load->model('person/Benutzer_model', 'BenutzerModel');
}
public function getTabulatorPreset($presetId)
{
$query = "
SELECT *
FROM public.tbl_tabulator_presets
WHERE preset_id = ?
LIMIT 1
";
return $this->execQuery($query, array($presetId));
}
public function getTabulatorPresetsByUserAndTable($uid, $tableName)
{
$query = '
SELECT *
FROM public.tbl_tabulator_presets
WHERE benutzer_uid = ?
AND table_name = ?
ORDER BY preset_id ASC
';
return $this->execQuery($query, array($uid, $tableName));
}
public function createTabulatorPreset($uid, $tableName, $presetName, $preset)
{
$presetCreationResult = $this->insert([
"benutzer_uid" => $uid,
"table_name" => $tableName,
"preset_name" => $presetName,
"preset_json" => json_encode($preset),
]);
if (isError($presetCreationResult))
{
return error('Something went wrong during preset creation!');
}
return success($presetCreationResult->retval);
}
public function updateTabulatorPreset($presetId, $preset)
{
$presetUpdateResult = $this->update(["preset_id" => $presetId], ["preset_json" => json_encode($preset)]);
if (isError($presetUpdateResult))
{
return error('Something went wrong during preset update!');
}
return success($presetUpdateResult->retval);
}
public function deleteTabulatorPreset($presetId)
{
$presetDeletionReseult = $this->delete(["preset_id" => $presetId]);
if (isError($presetDeletionReseult))
{
return error('Something went wrong during preset deletion!');
}
return success($presetDeletionReseult->retval);
}
}

Some files were not shown because too many files have changed in this diff Show More