Compare commits

...

1318 Commits

Author SHA1 Message Date
Harald Bamberger f57dc6785b Merge branch 'master' into feature-63428/Infomail_Foto 2025-09-30 13:47:04 +02:00
Harald Bamberger 81e705f297 Merge branch 'feature-63430_63431/bugfixes_checkbox_dual_and_setAbsolvent_with_user_schuhch' 2025-09-30 13:22:48 +02:00
Harald Bamberger 9a74ab9c63 add empty option to zgvnation, zgvmanation, zgvdoktornation, berufstaetigkeit_code and ausbildungcode. to not violate fk set empty value for those to null in backend 2025-09-30 13:19:18 +02:00
Harald Bamberger 8fdabcb317 handle boolean values explicitly 2025-09-30 12:22:12 +02:00
Harald Bamberger 93fa0ed180 deleteStatus fix isMeldestichtagErreicht comparison, add modal-dialog-scrollable class to status modal 2025-09-30 10:51:14 +02:00
Harald Bamberger 3551172c0b reenable meldestichtag check 2025-09-30 09:33:07 +02:00
Harald Bamberger 795378bf40 Merge branch 'master' into feature-63430_63431/bugfixes_checkbox_dual_and_setAbsolvent_with_user_schuhch 2025-09-30 09:13:10 +02:00
Andreas Österreicher 9db14effdc Merge branch 'feature-67500/AnwesenheitenNanotuning' 2025-09-29 11:13:04 +02:00
Harald Bamberger 8403384cc2 Merge branch 'feature-59258/Studierendenverwaltung_Kontakttypen' 2025-09-29 08:05:22 +02:00
Harald Bamberger 4a55b73461 do not query hidden contacts or the hidden contact type from db, remove hidden contact type filtering from frontend code 2025-09-29 08:03:04 +02:00
Harald Bamberger 159904b8ad Merge branch 'master' into feature-59258/Studierendenverwaltung_Kontakttypen 2025-09-26 15:00:00 +02:00
Harald Bamberger 245e4a3028 Merge branch 'feature-62462/FHC4_Studierendenverwaltung_Delete_Photo' 2025-09-26 14:37:55 +02:00
Harald Bamberger 0df9cf769f strip data image base64 prefix before storing foto, show dummy profile img when foto is null in DetailsHeader 2025-09-26 14:33:20 +02:00
Harald Bamberger 464b99b3f9 Merge branch 'master' into feature-62462/FHC4_Studierendenverwaltung_Delete_Photo 2025-09-26 14:29:32 +02:00
Johann Hoffmann a021c85920 schönere phrasen 2025-09-25 17:23:03 +02:00
Harald Bamberger 6047b19f47 do not show contacts with type hidden in cis4 profile 2025-09-25 17:19:19 +02:00
Harald Bamberger e5778acf9d Merge branch 'feature-63437/cis4_iframe_component' 2025-09-25 16:15:17 +02:00
Harald Bamberger 58b942f044 fix typo in template_kurzbz 2025-09-25 16:14:09 +02:00
Harald Bamberger 2ef2948a6e prevent strange effects when switching between content_types 2025-09-25 16:02:43 +02:00
ma0048 5efad50b62 added missing iframe component 2025-09-23 08:31:00 +02:00
Harald Bamberger eaec76c3d2 Merge branch 'master' into feature-63437/cis4_iframe_component 2025-09-22 17:03:42 +02:00
Andreas Österreicher b5d44de0b4 Merge branch 'feature-66843/infocenter_studentenverwaltung_verlinkung' 2025-09-22 14:15:49 +02:00
Andreas Österreicher 60d09bd2a7 Merge branch 'bug-67504/notizcontroller_delete' 2025-09-22 14:10:17 +02:00
Andreas Österreicher 2b91ae87c0 Merge branch 'feature-61714/infocenter_hinweis_wenn_die_selbe_person_bereits_einen_aufrechten_status_im_selben_studiengang_hat' 2025-09-22 14:07:54 +02:00
Andreas Österreicher efcc4b8ea5 Merge branch 'feature-62331/infocenter_anmerkung_zur_bewerbung_weiterleiten' 2025-09-22 13:59:13 +02:00
ma0048 c69877ed85 bug beim loeschen von einer notiz mit doc 2025-09-22 13:41:58 +02:00
Andreas Österreicher f97951966c Merge branch 'deploy_22_09_25_lvverwaltung' 2025-09-22 10:49:15 +02:00
ma0048 ef56af6337 lv teil hinzufuegen beim semesterwechsel das richtige semester preselecten
lv teil kopieren nur bei lv teilen anzeigen
2025-09-22 09:40:37 +02:00
Andreas Österreicher 3f5801f6ed Menüpunkt für LV-Verwaltung im Vilesci hinzugefügt 2025-09-22 09:26:13 +02:00
Harald Bamberger 41143a6dfc profile functions use tbl_benutzerfunktion.beschreibung in column description, format date columns in profile tabulators, fix vuejs dev version warnings 2025-09-19 10:58:53 +02:00
Harald Bamberger 0577f3f8b9 Cis4 Profile only show current userfunctions with description from tbl_funktion 2025-09-18 18:46:11 +02:00
ma0048 41dbd83bdb phrases
tags als default entfernt
master gemerged
2025-09-18 15:27:04 +02:00
ma0048 6a31eade8b Merge branch 'feature-60973/komponente_fuer_lehrfaecherverteilung' into deploy_22_09_25_lvverwaltung
# Conflicts:
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2025-09-18 15:04:01 +02:00
ma0048 57531d956d gruppen in eigenen tab verschoben
styling
phrases
2025-09-18 13:18:44 +02:00
Harald Bamberger 5b42c438d0 Merge branch 'master' into feature-62462/FHC4_Studierendenverwaltung_Delete_Photo 2025-09-18 07:47:53 +02:00
Andreas Österreicher e80cfc207e Merge branch 'feature-63370/AnwesenheitenMicrotuning' 2025-09-17 14:59:49 +02:00
Harald Bamberger af94cb1e40 Merge branch 'feature-63455/Studierendenverwaltung_Tab_Reihenfolge' 2025-09-17 14:25:04 +02:00
Harald Bamberger 8ae5ce27ce Merge branch 'bug-67033/Stv_Verband_Auswahl_springt' 2025-09-17 14:08:37 +02:00
Harald Bamberger bbfaf447f5 remove dependency to library from pv extension and do not delete salary history when gb is deleted since foreign key is configured on delete set null 2025-09-17 12:13:15 +02:00
ma0048 dff8223d3e sortierung der tags 2025-09-17 11:04:10 +02:00
Harald Bamberger 7e40e34212 remove DMS_PATH from original user filename 2025-09-16 17:40:27 +02:00
Harald Bamberger fe8bdbd0e4 Merge branch 'feature-67041/CIS4_Profilupdate_bugfixes' 2025-09-16 13:55:16 +02:00
Harald Bamberger cef581178c show documents in status view 2025-09-16 13:52:52 +02:00
Harald Bamberger 34eb373061 adapt phrase profilUpdateInformationMessage 2025-09-16 13:39:15 +02:00
Harald Bamberger cb5623d228 label and layout for documents 2025-09-16 13:32:28 +02:00
Harald Bamberger 379270c296 consider person foto_sperre in advanced cis search 2025-09-16 11:57:27 +02:00
Harald Bamberger 7f7488e61e add fileupload to edit address for meldezettel upload 2025-09-16 11:45:49 +02:00
Harald Bamberger 9e6ae4f5a4 add phrase lehre/termineImLvPlan 2025-09-15 11:31:35 +02:00
Harald Bamberger c498119b6c fix cis4 cms link replacement in general content type when switching via vue router from one content to another 2025-09-15 11:08:33 +02:00
Andreas Österreicher e589aff1f3 Merge branch 'feature-66956/MobilityOnline_Incoming_LV_Uebernahme_optimieren' 2025-09-15 10:16:20 +02:00
Harald Bamberger bdfd3d86de Merge branch 'feature-62450/MyLv_VueRouter_Semester' 2025-09-15 07:24:53 +02:00
Harald Bamberger 2c60dcb0a9 Merge branch 'master' into feature-62450/MyLv_VueRouter_Semester 2025-09-15 07:20:28 +02:00
Harald Bamberger edf2eca348 Merge branch 'feature-62450/Drag_Drop_Dashboard_Chrome' 2025-09-15 07:01:06 +02:00
Harald Bamberger bc318e79f5 Merge branch 'master' into feature-62450/Drag_Drop_Dashboard_Chrome 2025-09-15 06:56:10 +02:00
Harald Bamberger f0d9a43733 fix LvPlan not rendering Events in timeGrid correctly 2025-09-13 11:08:19 +02:00
Harald Bamberger 1adf1622db Merge branch 'feature-67041/CIS4_Profilupdate' 2025-09-12 16:10:38 +02:00
Harald Bamberger 92ba45a84d cleanup Controller, move api functions to api controller, use api in tabulator, fix card refresh in profile right column, fix sancho mails 2025-09-12 16:09:03 +02:00
Johann Hoffmann b8d197d923 deleted entschuldigung email betreff 2025-09-12 13:50:25 +02:00
Andreas Österreicher 3cbec91c2a Merge branch 'feature-66982/Zeitaufzeichnung_Berufsschule' 2025-09-12 09:41:18 +02:00
Andreas Österreicher 012ae4ac62 Berufsschule für Lehrlinge als aktivität hinzugefügt in der
Zeitaufzeichnung
2025-09-12 09:39:06 +02:00
chfhtw 0ae0ceb5d9 Bugfix: Stv Verband springt 2025-09-11 16:14:20 +02:00
Harald Bamberger 087fb6a702 Merge branch 'feature-63370/AnwesenheitenMicrotuning' 2025-09-11 13:24:37 +02:00
Harald Bamberger 20f7c2e841 Merge branch 'master' into feature-63370/AnwesenheitenMicrotuning 2025-09-11 13:06:46 +02:00
Harald Bamberger 849a850e71 Merge branch 'feature-67026/CIS4_Zugriffe_loggen' 2025-09-11 12:57:07 +02:00
Harald Bamberger b7d9edc85d Merge branch 'master' into feature-67026/CIS4_Zugriffe_loggen 2025-09-11 12:56:46 +02:00
Harald Bamberger c9f8df8d98 Merge branch 'feature-63463/CIS_NEU_Logout' 2025-09-11 12:52:36 +02:00
Harald Bamberger 41773fb6f0 Merge branch 'master' into feature-63463/CIS_NEU_Logout 2025-09-11 12:52:09 +02:00
Harald Bamberger 632e7d74e5 add validation 2025-09-11 11:25:18 +02:00
Alexei Karpenko 06a41e24d6 Lehreinheit model getLesForLv method: only getting necessary fields to save memory 2025-09-10 17:39:32 +02:00
Harald Bamberger af32f65015 store routeinfo and advanced search info in db 2025-09-10 17:10:24 +02:00
Andreas Österreicher 4c3f9e42b9 Bankimport hinzugefügt 2025-09-10 14:29:58 +02:00
Johann Hoffmann c9425a0061 'fileuploaddatum' phrase => 'FileUpload-Datum' 2025-09-10 11:20:32 +02:00
Johann Hoffmann b95dd49d0e assistenz uploaddatum -> antragsdatum; added new column 'fileuploaddatum'; 2025-09-10 10:44:43 +02:00
Harald Bamberger 14d49d87b3 also clear browser basic auth via additional fhclogout cookie in private/logout.php 2025-09-10 07:51:09 +02:00
Johann Hoffmann 708e03bda3 raumsuche phrasenpromise; lvMenu phrasenkeys; lv component property bezeichnung_eng so template can find it; 2025-09-09 11:31:19 +02:00
Johann Hoffmann 20f936c22c 'emails an studierende' add phrasenkey for responsive translations lvmenu 2025-09-09 09:54:33 +02:00
Johann Hoffmann eee9d6b691 raumsuche phrasen change & fix; fhcapi -> api; lvMenu try to use phrasenkey for responsiveness instead of the already looked up phrase; tried investigating news carousel bug, not sure if bug or feature - at least declared non changing variables as const; 2025-09-08 17:28:09 +02:00
Johann Hoffmann d015b208fc dont reassign event.lektor inside computed property depending on event.lektor 2025-09-08 14:35:20 +02:00
Johann Hoffmann 56e74fc365 fix phrasesLib init so reference in lvMenuBuild event doesnt break 2025-09-08 11:59:25 +02:00
Andreas Österreicher 5889bdb6ea Merge branch 'feature-63359/StV_API_error_clustering' 2025-09-04 14:40:24 +02:00
Andreas Österreicher 6fb06397be Merge branch 'master' into feature-63359/StV_API_error_clustering 2025-09-04 14:32:10 +02:00
Andreas Österreicher a1f305aa51 Merge branch 'feature-61672/svnr_im_fas_ausblenden_bei_studierenden' 2025-09-04 14:17:09 +02:00
Andreas Österreicher 8bba492ec1 Check for existing Folder before loading possible routes 2025-09-04 13:36:14 +02:00
Johann Hoffmann 2c3754b33f more tooltips so people can avoid reading the wiki 2025-09-03 13:51:41 +02:00
ma0048 d027e62e75 neu hinzugefuegter tag an erster stelle 2025-09-03 11:21:08 +02:00
Andreas Österreicher edce5716fd Merge branch 'feature-63370/AnwesenheitenMicrotuning' 2025-09-02 15:50:45 +02:00
Andreas Österreicher 8e4f2143f2 Merge branch 'feature-61742/UHSTAT_Staatenlos_Meldung_geht_nicht2' 2025-09-02 15:15:40 +02:00
Alexei Karpenko 0782de0550 uhstat form: moved constant down for better readability 2025-09-02 15:09:15 +02:00
Alexei Karpenko 022fb26e92 uhstat1 form: removed staatenlos code from dropdowns 2025-09-02 15:08:58 +02:00
Andreas Österreicher e0a3df5d06 Merge branch 'feature-66775/UHSTAT_1_mit_normalem_login' 2025-09-02 14:59:52 +02:00
ma0048 396251b061 lvverwaltung einschraenkung bei den tags
erledigte tags werden in der header suche nicht beruecksichtigt
2025-09-02 13:35:15 +02:00
Johann Hoffmann fa6d651b21 phrasen & permissionLib/Phrases reference $param in lvMenuBuild event 2025-09-01 16:48:24 +02:00
ma0048 34528bb014 iframe content hinzugefuegt 2025-08-29 13:19:00 +02:00
Andreas Österreicher f18de90c67 Merge branch 'nscbrandb-env_routes' 2025-08-29 12:11:06 +02:00
Andreas Österreicher 014d2b68ae Merge branch 'bug-66817/ku_udfs' 2025-08-29 11:41:15 +02:00
Andreas Österreicher 4bc58ee946 Merge branch 'feature-66852/raum_content_anzeige_im_alten_cis' 2025-08-29 11:23:38 +02:00
nscbrandb d17f87be09 also take environment config into account 2025-08-29 10:35:27 +02:00
ma0048 7df383f45e hinzugefuegte spann class caps durch den parser entfernt 2025-08-28 08:36:20 +02:00
Alexei Karpenko 1d634a2530 uhstat form: bewerbungstool user data is loaded if there is a login, normal logged in user data otherwise. renamed methods, removed unnecessary model loads 2025-08-27 16:23:58 +02:00
chfhtw 1024fc6cab Don't overwrite object => work with copies 2025-08-27 14:41:50 +02:00
ma0048 9a35ee5945 raum content im alten cis wieder auf tablesorter 2025-08-27 11:48:35 +02:00
chfhtw 2d2bbd1bb3 Bootstrap Modal Component: forward shown-bs-modal event 2025-08-27 10:20:41 +02:00
chfhtw 41d26246aa Form Input Component: add name & use autocomplete that was loaded in the CI View 2025-08-27 10:19:39 +02:00
ma0048 7e6643c0ff phrase typo 2025-08-27 09:51:34 +02:00
Andreas Österreicher e366556992 Dienstverhinderung für Volksschultag hinzugefügt 2025-08-26 16:05:06 +02:00
chfhtw f1c9e641bb API: feedback for stv status dropdown 2025-08-26 14:25:29 +02:00
chfhtw 1ef884de8c API: return results on multicall 2025-08-26 14:25:04 +02:00
ma0048 045b764d65 studentenverwaltung im infocenter verlinkt 2025-08-26 12:40:27 +02:00
Andreas Österreicher d7c56ad05d Merge branch 'master' into feature-61672/svnr_im_fas_ausblenden_bei_studierenden 2025-08-26 08:58:01 +02:00
Andreas Österreicher d8eac58ab1 Merge branch 'feature-61672/svnr_aus_infocenter_tool_entfernen' 2025-08-26 08:45:05 +02:00
Andreas Österreicher c6d04c7490 Merge branch 'master' into feature-61672/svnr_aus_infocenter_tool_entfernen 2025-08-26 08:43:22 +02:00
Andreas Österreicher ce432d4c43 Merge branch 'master' into feature-61672/svnr_im_fas_ausblenden_bei_studierenden 2025-08-26 08:36:36 +02:00
Andreas Österreicher 866d95c4b8 Merge branch 'feature-62681/mc1_vorlage_v2025_07' 2025-08-25 14:12:54 +02:00
Andreas Österreicher 1025a8b461 Removed Duplicate Phrase 2025-08-25 11:19:20 +02:00
Andreas Österreicher 67290a5af8 Merge branch 'feature-61592/AnwesenheitenFinetuning' 2025-08-25 11:10:34 +02:00
Alexei Karpenko 531fae8ab5 enabled filling out UHSTAT1 form for logged in students 2025-08-23 16:46:26 +02:00
chfhtw 11868d9496 StV: tab final ordering 2025-08-21 15:00:18 +02:00
chfhtw fb9f2e86fc StV: tab ordering 2025-08-21 13:46:30 +02:00
Harald Bamberger ad83228396 do not terminatewithsuccess in function called in db transaction because this results in the transaction being rollbacked 2025-08-19 17:34:23 +02:00
Harald Bamberger 905a2dadff terminate with error if receiver person_id or prestudent_id is not found 2025-08-19 17:18:57 +02:00
Harald Bamberger 1c86a6ad55 add validation callback wrapper method 2025-08-19 16:05:47 +02:00
Harald Bamberger a482016dee modal-dialog-scrollable 2025-08-19 13:58:41 +02:00
Harald Bamberger 2198ea95e4 use form.post instead of form.send since latter expects a promise 2025-08-19 13:51:09 +02:00
Harald Bamberger ef80a19a24 allow negative studiengang_kz in prestudent and orgform urls 2025-08-19 13:22:59 +02:00
Johann Hoffmann c5001f87bd modal header flex container for buttons (close, expand); 2025-08-19 11:03:23 +02:00
Harald Bamberger ba7f59de24 Merge branch 'bug-63358/CIS4_Kalendar_Widget_Deutsch_English_Tagesname_schalten_nicht_um' 2025-08-19 10:56:34 +02:00
Johann Hoffmann 9707258e62 Merge remote-tracking branch 'origin/master' into feature-61592/AnwesenheitenFinetuning
# Conflicts:
#	public/js/components/Bootstrap/Modal.js
#	system/phrasesupdate.php
2025-08-19 09:43:30 +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
chfhtw f50171ad9a Calender: track locale change for day & list mode 2025-08-18 15:38:35 +02:00
chfhtw 42a81a4558 API error clustering 2025-08-18 13:06:59 +02:00
SimonGschnell f695d8b66a update(Dashboard Widget Drag): shows hidden widget when dragging the widget on the dashboard 2025-08-18 10:21:18 +02:00
Harald Bamberger 6d7429eb8e Merge branch 'feature-62779/xul_abloese_haustechnik_schluesselverwaltung' 2025-08-14 18:10:36 +02:00
Harald Bamberger b9e3c47be9 Merge branch 'master' into feature-62779/xul_abloese_haustechnik_schluesselverwaltung 2025-08-14 18:03:36 +02:00
Harald Bamberger 5119858c12 Merge branch 'feature-63411/Notizen_Anzahl_im_Tab_Header_anzeigen' 2025-08-14 17:52:47 +02:00
Harald Bamberger ed00c8d0ae add permission for new function in Core_Notizcontroller to NotizPerson Controller 2025-08-14 16:45:52 +02:00
Harald Bamberger 83d98c258e stv Notiz Controller add permission for new function getCountNotes 2025-08-14 16:36:00 +02:00
ma0068 a42e70e2fe comment out check Bismeldestichtag for deleteStatus 2025-08-14 16:28:20 +02:00
Harald Bamberger aaf9e8c885 revert to popupModal to stay consistent with other stv tabs 2025-08-14 16:16:53 +02:00
ma0068 729618cbe7 Tab Status: change format for Date for Check Bismeldestichtag 2025-08-14 15:38:03 +02:00
Harald Bamberger aa3e1ad1d1 Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' into feature-63411/Notizen_Anzahl_im_Tab_Header_anzeigen 2025-08-14 15:24:42 +02:00
Harald Bamberger 1092463beb show count of notes in tab title 2025-08-14 15:23:42 +02:00
SimonGschnell e46f46c95b update(Dashboard grid): doesnt allow the user to drag a widget outside of the grid boundaries 2025-08-14 15:07:38 +02:00
ma0068 4d78abf9ec Tab Prestudent: use false for boolean and null for other variables for update if field is empty 2025-08-14 13:15:10 +02:00
Harald Bamberger 33fbbde99f Merge branch 'master' into feature-63411/Notizen_Anzahl_im_Tab_Header_anzeigen 2025-08-14 12:32:07 +02:00
Harald Bamberger 79506319a0 Merge branch 'master' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-08-14 12:31:47 +02:00
Harald Bamberger a51f587da7 match negative studiengang_kz explicitly 2025-08-14 10:29:16 +02:00
Harald Bamberger e11ff91b53 use (:any) for studiengang_kz since it can be negative 2025-08-13 18:45:58 +02:00
Harald Bamberger d4f5a7c92f add missing helper js file 2025-08-13 16:37:28 +02:00
ma0068 34a239a823 Set Foto to null instead of empty String when Deleted 2025-08-13 14:54:43 +02:00
SimonGschnell 645da5a5bf fix(Dashboard drag&drop): ensures dragend events trigger correctly in chrome 2025-08-13 12:09:34 +02:00
Harald Bamberger 50b2334e5c work in progess, calc tabs title suffix when component is not rendered 2025-08-13 10:38:30 +02:00
Harald Bamberger e7f58ca1ba Merge branch 'master' into feature-62779/xul_abloese_haustechnik_schluesselverwaltung 2025-08-13 07:33:13 +02:00
Harald Bamberger 3749955d5b Merge branch 'master' into feature-60973/komponente_fuer_lehrfaecherverteilung 2025-08-13 07:03:59 +02:00
SimonGschnell 4eab58177a update(disabled widget background): updates the background of disabled widgets in the dashboard by giving them more opacity 2025-08-12 11:41:14 +02:00
SimonGschnell 3e69495842 fix(Dashboard drag&drop): behavior of dragged widgets when they exceed the grid limits, and ensures all widget clones are always deleted 2025-08-12 09:53:45 +02:00
Harald Bamberger 2402693116 Merge branch 'master' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-08-12 09:07:19 +02:00
Harald Bamberger 5e7514ffff Merge branch 'feature-63400/studentenverwaltung_phrases' 2025-08-12 09:02:40 +02:00
ma0048 57bc4d7b92 load phraseslib in students 2025-08-12 08:51:55 +02:00
Harald Bamberger 80f1edca8f Merge branch 'master' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-08-11 15:25:16 +02:00
chfhtw 3fad0fd69a CSS fix primevue/bootstrap box-sizing 2025-08-11 13:00:26 +02:00
SimonGschnell 8e6a103340 update(MyLv remove comment): removes unnecessary comment from the FHC.js file 2025-08-11 11:33:37 +02:00
Harald Bamberger c8c3361783 use getAktOrNextSemester instead of getNearest to use next semester in summer 2025-08-11 11:26:01 +02:00
SimonGschnell 03397b7272 update(MyLv VueRouter History): update the currentSemester based on the studiensemester param of the VueRouter history 2025-08-11 11:17:59 +02:00
SimonGschnell 3c3038362a update(MyLv VueRouter Studiensemester): adds the Studiensemester to the url of the vue router in the mylv view 2025-08-11 10:38:26 +02:00
ma0068 c109d84492 Tab Details: bugfix: show Zugangscode 2025-08-11 10:13:42 +02:00
ma0048 9ae78f2de6 master gemerged 2025-08-11 09:23:18 +02:00
chfhtw f6432cdcd0 accummulate multiple setFeedback calls in Form/Valdation 2025-08-08 12:26:51 +02:00
chfhtw 04cce2af4c CSS fix primevue box-sizing 2025-08-08 12:26:39 +02:00
Harald Bamberger 8c797fb212 Personal LVPlan: generate download links also for employees not only for students 2025-08-07 15:34:23 +02:00
ma0068 b2d8b81ab5 Changes for Tab Notes
- change layout to classicFas to enable input note with one click less
- extend Tab component: add headerSuffix
- show count of messages in header
2025-08-07 15:30:04 +02:00
Harald Bamberger 73d269d54b adapt media breakpoints for degree programs view 2025-08-07 14:42:59 +02:00
Harald Bamberger d071d0d9fe fix theme switch position in chrome based browsers 2025-08-07 14:25:22 +02:00
Harald Bamberger 8494033bda CIS4 Dashboard: add workaround for chrome fireing event dragend when styles are manipulated during dragging 2025-08-07 13:35:47 +02:00
ma0048 2b7f56622c Merge branch 'master' into feature-60973/komponente_fuer_lehrfaecherverteilung
# Conflicts:
#	application/models/education/Lehrveranstaltung_model.php
#	application/models/organisation/Studienplan_model.php
#	application/models/person/Notiz_model.php
#	application/models/ressource/Mitarbeiter_model.php
#	public/js/components/Stv/Studentenverwaltung.js
#	public/js/components/Stv/Studentenverwaltung/Verband.js
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2025-08-07 11:03:05 +02:00
Harald Bamberger 4f2499862f scale height of images in news widget 2025-08-07 09:45:19 +02:00
Harald Bamberger 8048b9d9c3 use light text color in language selector 2025-08-07 09:30:57 +02:00
Harald Bamberger 954cd16d10 use getAktOrNextSemester to determine preselected semester 2025-08-07 09:21:12 +02:00
Harald Bamberger 9e3ebca0a4 fix vue warning duplicate attribute class 2025-08-07 09:20:24 +02:00
Harald Bamberger 2faafea462 Merge branch 'rc1_FHC4_C4' 2025-08-06 11:15:07 +02:00
Harald Bamberger 9ad2198b02 update phrase Stundenplan => LV-Plan, Feiertag => Ferien / Feiertag, Holiday => Holidays 2025-08-06 11:14:37 +02:00
Harald Bamberger 8104d77399 improve styling of deactivated lines in stv students list 2025-08-06 11:07:59 +02:00
chfhtw c96db9f573 reworked StV favorites (only 1st tier version) 2025-08-06 11:06:57 +02:00
ma0068 42a40072fa show all errors in one alert
- refactor Dropdown.js: use new factory for overwriting errors
- move functionaliy to show Errors and InfoAlerts to Api.js
- extend FhcAlert (primeVue) with slot for toast for ability to use html
2025-08-06 10:55:58 +02:00
Johann Hoffmann 0605baf68f capitalize tab phrases; style&phrase change for Attendance Check Date Datepicker; Picture col min width icrease so the title is readable in english; 2025-08-06 10:45:37 +02:00
chfhtw 49ddf568e1 filter component: keep column visibility on reload 2025-08-06 08:46:02 +02:00
Harald Bamberger 9de0a41035 move Theme plugin to plugins folder 2025-08-05 18:36:07 +02:00
Harald Bamberger 8a1cbd754d Merge branch 'merge_C4_25999_61235_61730' into rc1_FHC4_C4 2025-08-05 16:32:50 +02:00
Harald Bamberger 555a4f01c2 Merge branch 'feature-40128/Mehrere_Suchergebnisse_für_selbe_Person' into rc1_FHC4_C4 2025-08-05 16:12:57 +02:00
chfhtw 603622a3f1 LvPlan use computed for lv title 2025-08-05 14:38:59 +02:00
chfhtw 6391e58f74 Bugfix: negation of instanceof 2025-08-05 14:37:57 +02:00
chfhtw aded9067e5 remove id-attribute from calendar renderer templates 2025-08-05 14:37:36 +02:00
Harald Bamberger e241b586a8 use currentSemester instead of defaultSemester because of vuerouter 2025-08-05 13:28:15 +02:00
Harald Bamberger 133e1f08f6 use currentSemester instead of defaultSemester 2025-08-05 12:20:29 +02:00
Harald Bamberger 41a46aa7b2 add component name, cssclass name, replace old delete api call with new one 2025-08-05 11:59:07 +02:00
Harald Bamberger 70274eef3a remove console.log 2025-08-05 11:33:25 +02:00
Harald Bamberger c728f60ec5 fix cherry picked Archiv.js 2025-08-05 11:28:18 +02:00
Alexei Karpenko b4a1720a94 Studierendenverwaltung archiv: removed tabulator columns from computed 2025-08-05 11:13:44 +02:00
Alexei Karpenko d33f493543 Studentenverwaltung archive: switched to new api factory 2025-08-05 11:09:38 +02:00
Andreas Österreicher db30fa0d96 Sorting Akte Results if creation date is the same 2025-08-05 09:42:00 +02:00
chfhtw 043c9fd5f3 split LvPlan into MyLvPlan (personal calendar) and LvPlan (lv calendar) 2025-08-05 09:33:11 +02:00
chfhtw 8f44a8b33e use for-loop instead of reduce to get rid of Firefox ESR 128 Workaround 2025-08-05 09:31:20 +02:00
Andreas Österreicher 2a9432d076 Merge branch 'rc1_FHC4_C4' of github.com:FH-Complete/FHC-Core into rc1_FHC4_C4 2025-08-05 09:26:11 +02:00
Andreas Österreicher 72bb465ecf Fixed Document Archive und Signature 2025-08-05 09:25:34 +02:00
chfhtw 30cc798c0b Endpoint to get lv details 2025-08-05 08:35:37 +02:00
Harald Bamberger 52e0535312 use existing phrase 2025-08-05 07:21:09 +02:00
Harald Bamberger 459d445f2f trigger search when searchfield gets focus a searchstr is there and the searchresult is empty 2025-08-05 06:59:21 +02:00
Andreas Österreicher ecc7e4672f Styling in Navigation Component korrigiert 2025-08-04 17:34:19 +02:00
Andreas Österreicher b8de311015 Umlaute in Navigation Component gefixed 2025-08-04 17:33:52 +02:00
Andreas Österreicher f57e27fae0 Merge branch 'rc1_FHC4_C4' of github.com:FH-Complete/FHC-Core into rc1_FHC4_C4 2025-08-04 17:20:16 +02:00
Andreas Österreicher 0516fa2ff5 Alert CSS fixed, Legacy Icons aus Alerts entfernt 2025-08-04 17:19:44 +02:00
Harald Bamberger cba5b39e29 searchcis do not search for organisationeinheittyp_kurzbz Container 2025-08-04 16:28:31 +02:00
Harald Bamberger cc91fe7588 searchcis only students and employees with active useraccount 2025-08-04 16:17:38 +02:00
Andreas Österreicher e9807a210b Removed Error Logs 2025-08-04 16:00:53 +02:00
Andreas Österreicher 4a69204384 Bugfix for Firefox ESR 128 Bug where Reduce Function is not always available 2025-08-04 15:53:22 +02:00
chfhtw 9b396088c3 Refactor LvPlan endpoints to be more granular 2025-08-04 14:09:27 +02:00
chfhtw b76bdfa431 Close calendar modal on unmount 2025-08-04 14:08:59 +02:00
Harald Bamberger e727c03a42 fix current simple search with modified searchbar, let action always emit actionexecuted event on click to close search in combination with vue router 2025-08-04 13:42:51 +02:00
Harald Bamberger 648dca3eba Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' into rc1_FHC4_C4 2025-08-04 13:06:53 +02:00
Harald Bamberger 8bcd0961f6 remove unused empty file 2025-08-04 13:06:32 +02:00
Harald Bamberger 384dcd8411 Merge branch 'feature-62018/C4_Weiterleiten_zu_CIS4_nach_CIS_Login_unter_bestimmten_Bedingungen' into rc1_FHC4_C4 2025-08-04 10:54:37 +02:00
Harald Bamberger 9cbb612c8f Merge branch 'feature-63192/FHC4-Studierendenverwaltung_Semsterauswahl_fuer_mehrere_Tabs_anpassen' into rc1_FHC4_C4 2025-08-04 10:22:44 +02:00
Harald Bamberger 42e31af94c Merge branch 'merge_C4_25999_61235_61730' into rc1_FHC4_C4 2025-08-04 10:20:45 +02:00
Harald Bamberger 89c64cadc7 calc current Studiensemester by start_date, to avoid gap and error msg during summer 2025-08-04 10:20:11 +02:00
ma0048 be24190636 studiensemester auswahl abhaengig von url 2025-08-04 10:15:07 +02:00
chfhtw 502942deb3 Remove template from slot 2025-08-04 09:28:50 +02:00
Harald Bamberger 405f7a551e Merge branch 'merge_C4_25999_61235_61730' into rc1_FHC4_C4 2025-08-04 09:17:09 +02:00
chfhtw 02a52d1aee Bugfix: forward both params in LvPlan update:date and update:mode events 2025-08-04 08:44:27 +02:00
Harald Bamberger 6714432c30 handle no existing stgs from url 2025-08-01 18:02:01 +02:00
Harald Bamberger 9999cb47c2 use extende Verband component from branch feature/60973, add route for studiengang kuerzel in url, adapt for switching studiengang also via url 2025-08-01 17:32:54 +02:00
Harald Bamberger 5329fadbac add searchresultlink function to generate urls with current studiensemester in extended search 2025-08-01 17:25:30 +02:00
Harald Bamberger a429b20823 Merge branch 'feature-63192/FHC4-Studierendenverwaltung_Semsterauswahl_fuer_mehrere_Tabs_anpassen' into rc1_FHC4_C4 2025-08-01 16:26:01 +02:00
Harald Bamberger 37b67641ef Merge branch 'feature-40128/Mehrere_Suchergebnisse_für_selbe_Person' into rc1_FHC4_C4 2025-08-01 16:19:23 +02:00
Harald Bamberger 66caf47d98 Merge branch 'merge_C4_25999_61235_61730' into rc1_FHC4_C4 2025-08-01 15:54:22 +02:00
Harald Bamberger 497e839963 Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' into rc1_FHC4_C4 2025-08-01 15:48:49 +02:00
chfhtw 219507ffa3 Shareable calendar components 2025-08-01 15:22:34 +02:00
chfhtw e326c9483d correct default value for calender date prop 2025-08-01 15:10:04 +02:00
Harald Bamberger cf073d04b4 remove console.log 2025-08-01 12:27:00 +02:00
Harald Bamberger 8472813246 Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' into feature-63192/FHC4-Studierendenverwaltung_Semsterauswahl_fuer_mehrere_Tabs_anpassen 2025-08-01 12:24:02 +02:00
Harald Bamberger 472fceaf62 changes to support studiensemester_kurz as part of the url 2025-08-01 12:22:27 +02:00
Harald Bamberger 247de82e81 add config number_displayed_past_studiensemester_default and use it in api endpoint 2025-08-01 11:59:29 +02:00
ma0048 5d07879ebd org form hinzugefuegt im stree
gruppe autocomplete auch auf die bezeichnung
getalloe sql angepasst
2025-08-01 11:44:23 +02:00
ma0068 66e27b3bb2 Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' of github.com:FH-Complete/FHC-Core into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-08-01 10:55:29 +02:00
ma0068 1cb637cb7f Tab Betriebsmittel: change type kaution to text, edit validations and add translations 2025-08-01 10:55:11 +02:00
Johann Hoffmann 913b218fca phrasenupdate Stundenplan -> LV-Plan; tooltip update/remove; 2025-08-01 10:53:15 +02:00
Harald Bamberger 5a9972a85f Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' into feature-63192/FHC4-Studierendenverwaltung_Semsterauswahl_fuer_mehrere_Tabs_anpassen 2025-07-31 17:03:31 +02:00
Harald Bamberger 0d514ad482 Merge branch 'master' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-07-31 17:01:04 +02:00
ma0068 562eb0a890 remove selectable from tables with not selectable rows 2025-07-31 17:00:11 +02:00
Harald Bamberger 38fe68362d use correct function in routing 2025-07-31 16:40:33 +02:00
ma0068 6217309c6f add infotext to reload button filtercomponent
tab archive: add infotext to reload button, edit and delete button
2025-07-31 16:34:24 +02:00
chfhtw 7755e2c7a6 searchbar: code quality 2025-07-31 15:20:05 +02:00
ma0068 9c1eb35e88 Tab Contact: Phrase for Validation Length PLZ 2025-07-31 11:18:37 +02:00
chfhtw 25da0d6865 cleanup - remove old/unused searchbar files 2025-07-31 11:12:58 +02:00
chfhtw 9a231d4bb4 name for searchbar components 2025-07-31 11:09:09 +02:00
chfhtw 9c3c8cd186 status sorting in mergedperson search results 2025-07-31 10:33:25 +02:00
ma0068 c4bb543c0a HeaderDetails: delete empty space before titelpost 2025-07-31 09:37:13 +02:00
ma0048 4d3ad0008e deleted automated added import 2025-07-31 09:33:11 +02:00
chfhtw bc7c811227 searchbar: filter btn accessisible (real button) 2025-07-31 09:29:43 +02:00
chfhtw 9a5790edf0 searchbar: better layout for clear button 2025-07-31 09:24:33 +02:00
ma0048 f9f0748b89 studiensemester_kurzbz aus dem fronted beruecksichtigen
extendedHeaderFilter suche in mehreren spalten moeglich
getAllOe sql abfrage richtig gestellt
2025-07-31 09:10:11 +02:00
Harald Bamberger 2f10a3a3e9 adapt single person routes, old and new js api files and frontend usage 2025-07-31 07:50:17 +02:00
ma0068 f12db529e0 Tab Notizen: remove clipContents 2025-07-31 07:40:07 +02:00
Harald Bamberger c876179762 adapt Students api endpoints, use ci routing, adapt frontend 2025-07-30 18:15:09 +02:00
Harald Bamberger fa97116ec4 replace backend var semester_aktuell with api parameter in grades, student and status endpoints, adapt old and new js api definitions, adapt frontend, add validation method to studiensemester_model 2025-07-30 18:09:56 +02:00
ma0068 16db622bc9 Tab Details
- add anrede to modelValue
- add Validations Alias and Lehrverbandsgruppe
- add Phrase invalidAlias
- add translation to validation Integer for field semester
2025-07-30 17:55:59 +02:00
chfhtw 2755a194eb searchbar remove redundant cssclass option 2025-07-30 15:12:20 +02:00
chfhtw ee13cfadba Use labels for types in CIS & StV searchbar 2025-07-30 12:33:48 +02:00
chfhtw 79720a77c2 searchbar: allow labels for types 2025-07-30 11:23:48 +02:00
chfhtw a7698b9af8 searchbar clear button stretch height 2025-07-30 11:23:00 +02:00
ma0068 ba23a6496c Tab Exam: change layout to fitDataStretchFrozen 2025-07-30 11:22:39 +02:00
ma0068 4e7ae928b5 Tab Details: add missing person attributes to modelValue.. second try 2025-07-30 11:19:21 +02:00
ma0068 62aa022c69 Tab Details: add missing person attributes to modelValue 2025-07-30 11:13:46 +02:00
chfhtw cb1ff2ef1a remove unused function 2025-07-30 11:03:42 +02:00
chfhtw 91624a3e53 searchbar clear button, searchbar z-indexes 2025-07-30 09:42:47 +02:00
chfhtw 1005963179 Each searchbar it's own config 2025-07-29 16:52:29 +02:00
Andreas Österreicher 386ae59428 Archivierung von MC Zertifikaten/Zeugnissen 2025-07-29 16:46:12 +02:00
chfhtw 30b895ad04 use renderers in search config 2025-07-29 16:07:15 +02:00
chfhtw 868c15f47d use teaching units for calendar 2025-07-29 15:47:17 +02:00
chfhtw b0f8b316af Use renderers in roominformation component 2025-07-29 15:36:29 +02:00
chfhtw 3cd00a5e5f Cleanup 2025-07-29 15:27:09 +02:00
Harald Bamberger ee5391f11a place timeinterval left of eventtext, add missing success wrapper in stundenplanlib 2025-07-29 14:27:46 +02:00
Harald Bamberger 602a572518 max height for all-day container, rearange zeitraum / frist in lehreinheit modal 2025-07-29 13:48:54 +02:00
chfhtw 2442c16eeb Calendar header CSS 2025-07-29 13:24:49 +02:00
ma0068 c1ca8c78af bugfix field gsstudientyp_kurzbz 2025-07-29 13:13:15 +02:00
ma0068 d262c5106c add zgv-fields to allow null values for update 2025-07-29 11:52:36 +02:00
chfhtw fd04b26af4 code quality 2025-07-29 11:40:40 +02:00
chfhtw 31fb649cac Bugfix: moodle start/end dates lost timezones and end time 2025-07-29 11:40:24 +02:00
chfhtw d76a5965db CSS improvements Calendar 2025-07-29 08:54:16 +02:00
Harald Bamberger 4d1c4bf7ab add css rules to show vue-datepicker svg icons inside of elements with bootstrap input-group or primevue p-component css class 2025-07-28 15:04:15 +02:00
ma0068 dcb9fad0d2 remove not existing tinymce-plugin linktitle 2025-07-28 12:11:45 +02:00
ma0068 cc0572b386 use endpoint for Messages, refactor component Vorlagendropdown to fhcapi 2025-07-28 11:44:06 +02:00
chfhtw 5e0ef4ebab Fix send mode on date update and vice versa to fix multiple router pushes 2025-07-28 09:39:32 +02:00
ma0068 24df22ba24 enable text-input zgv-master and enable remove dates ZGV 2025-07-28 08:40:45 +02:00
ma0068 e2df03debf Tab Prestudent: ZGVFields: Add Autocomplete function with strike through for not active entries 2025-07-25 14:05:37 +02:00
chfhtw 1b8ab88820 Fix: Browser back 2025-07-25 13:31:56 +02:00
chfhtw d59b623cb4 Bugfix: Return no events instead of error if the student is/was not enrolled in a timeframe 2025-07-25 13:17:41 +02:00
ma0068 58a85432ca enable text-input in datepicker 2025-07-25 10:50:48 +02:00
chfhtw 76248175f7 News padding not hardcoded in Dashboard Item Container but in the News CSS 2025-07-25 09:33:27 +02:00
chfhtw d101b53d3d Calendar: ResizeObserver for compact day mode 2025-07-25 09:27:56 +02:00
ma0068 53e395aca4 Tab Notizen, Messages: use HTML-Entities
Tab Abschlussprüfung, Prestudent, Pruefung, Dokument: Phrasen
2025-07-24 14:40:48 +02:00
chfhtw 611a6204cd compare AllDayEvents to whole day 2025-07-24 14:15:20 +02:00
ma0048 1d63b8de44 schluesselverwaltung & kontaktdatenverwaltung gui hinzugefuegt
betriebsmittel einschraenkung ueber prop moeglich (nur anzeige)
2025-07-24 11:18:58 +02:00
chfhtw c0e2a156d5 Merge branch 'merge_C4_25999_61235_61730_calendar' into merge_C4_25999_61235_61730 2025-07-24 10:46:23 +02:00
chfhtw d5f2f3d787 add luxon to composer.lock 2025-07-24 10:45:53 +02:00
Harald Bamberger d024d57ef5 fix carousel switching to wrong index, news widget styling 2025-07-24 10:21:50 +02:00
chfhtw 3a8984a8c3 CSS improvements for events 2025-07-24 09:39:47 +02:00
chfhtw ccb4a72ae4 CSS changes 2025-07-24 09:32:18 +02:00
ma0048 96cb546b68 permission check bug fixed 2025-07-23 14:14:03 +02:00
ma0068 715b48c39f Tab Nachrichten: Relationmessage Id, Letzte Änderung, Status in capital letters 2025-07-23 13:41:24 +02:00
chfhtw 6994591a10 better CSS file arrangement 2025-07-23 13:39:34 +02:00
ma0068 b1fe60aab0 Tab Anrechnungen: Add Phrasen Status, Notiz hinzufügen 2025-07-23 11:57:56 +02:00
SimonGschnell 92bd09355b update(News widget): adds number padding for the date and the time stamp in the news widget 2025-07-23 11:25:13 +02:00
SimonGschnell ae725c08a9 update(News und Paginator styling): updates how the news widget is highlighted and adds paginator css overwrites 2025-07-23 11:18:38 +02:00
ma0068 0be83eedef Start Translation ErrorMessage 2025-07-23 11:17:47 +02:00
chfhtw 8f73404307 truncate past-markings in month mode 2025-07-23 10:50:57 +02:00
chfhtw 66fd2e65a4 add css class today 2025-07-23 10:42:12 +02:00
chfhtw d648f79ca5 Correct click source for list mode 2025-07-23 09:38:31 +02:00
chfhtw 4ead590732 Fix: negation of instanceof in Lehreinheit modalContent Renderer 2025-07-23 09:25:16 +02:00
chfhtw 132ab686c9 get rid of Dashboard warnings 2025-07-23 09:24:16 +02:00
chfhtw 36fd2dcd90 cleanup 2025-07-23 09:23:29 +02:00
chfhtw 72df2cb79c Implementation CIS => LvPlanWidget 2025-07-23 08:56:23 +02:00
SimonGschnell db07f33e3c update(Cis Modals): makes modals scrollable by default and uses fhc-primary for the card-header and fhc-secondary for the card-footer 2025-07-22 16:20:18 +02:00
ma0068 07ba21ff3e Tab Details: reload DetailHeader after update Detaisl 2025-07-22 16:03:00 +02:00
SimonGschnell 1b2d5ff6c6 update(News widget styling): makes card-header of the news content sticky so that the white left and right buttons don't appear in front of a white background 2025-07-22 15:43:03 +02:00
ma0068 a13deed13f Tab Aufnahmetermine: bugfix updateAufnahmetermin 2025-07-22 14:07:44 +02:00
SimonGschnell 6c57c17eb5 update(News Widget 1 spaltig): adds padding and updates colors of the time and content when hovered 2025-07-22 13:50:34 +02:00
SimonGschnell 9ddb9f46fd refactor(Cis4 News Widget Responsive): changes the responsive column layouts for the news widget 2025-07-22 13:30:25 +02:00
chfhtw ad080e61b2 Implementation CIS => RoomInformation 2025-07-22 13:14:56 +02:00
chfhtw 0a9f4023b3 add component class 2025-07-22 10:50:34 +02:00
chfhtw f9a45a4917 LvPlan Now-background 2025-07-22 10:45:51 +02:00
SimonGschnell 9855a0b45d fix(News widget style): updates the content style of the news when rendering new news content 2025-07-22 10:37:45 +02:00
SimonGschnell 117a284dc4 update(News Widget/Content stylings): updates the style of the news widget and single news view 2025-07-22 09:47:45 +02:00
chfhtw fa090153f2 LvPlan.js Remove unused prop 2025-07-22 09:22:03 +02:00
chfhtw b4f1a8a56c Renderer Lehreinheit: get LvMenu inside the component 2025-07-22 09:19:51 +02:00
chfhtw a0721fcd9a LvPlan.js remove unused imports 2025-07-22 09:19:00 +02:00
chfhtw 4524b9bcdc Bugfix invalid end-tag 2025-07-22 09:18:31 +02:00
ma0068 9d809cf843 Tab Dokumente
- Refactor Mapping for List Accepted for correct view Akzeptiertdatum and AkzeptiertVon
- Delete Testoutputs dokument_kurzbz List NotAccpeted
- Correct ColumnName for NachreichungAm
- Change Order Columns Uploaddatum, akzeptiertVon
2025-07-21 16:33:26 +02:00
Harald Bamberger 7726850193 quick fix equal-int comparison resulting in an error if search string is numeric but out of range of integer column 2025-07-21 16:14:16 +02:00
chfhtw 91bb167c42 Implementation CIS => LV Plan 2025-07-21 15:40:51 +02:00
chfhtw 20e8964274 Comment 2025-07-21 15:38:35 +02:00
chfhtw f1971659b4 Loading Events 2025-07-21 15:33:35 +02:00
chfhtw 4e4a7a3880 Bugfix handle events outside of grid bounds 2025-07-21 15:30:34 +02:00
chfhtw ff104461af Bugfix missing template ref 2025-07-21 15:08:42 +02:00
chfhtw e25687be52 Bugfix start index of grid-line 2025-07-21 15:08:25 +02:00
chfhtw f1e28cec4e Bugfix eventloader 2025-07-21 14:10:23 +02:00
chfhtw f4f59b2fff Bugfix check textnodes 2025-07-21 13:49:52 +02:00
ma0068 5ed2595222 Tab Konto: change Dateformat to localeString
- Tabulator: column Buchungsdatum
- Modal: newCounter
- Modal: editCounter
- Tabulator: actionSlot: selected
2025-07-21 13:10:43 +02:00
chfhtw 90c30f21c1 Autoscroll 2025-07-21 11:34:58 +02:00
Harald Bamberger 4ae1ab88dc documents accepted tabulator bump persitence_id 2025-07-21 08:51:16 +02:00
SimonGschnell 07d610d60f update(PrimeVue Paginator darkmode): overwrites the background of the paginator component in primevue 2025-07-21 08:15:31 +02:00
SimonGschnell a22041007c update(Cis css): updates utility classes for primary colors 2025-07-21 08:15:31 +02:00
Harald Bamberger d122a5e72d use correct phrase for column name 2025-07-21 07:57:18 +02:00
ma0048 9fa23a1471 fixed check permission 2025-07-17 16:21:23 +02:00
Harald Bamberger 952f98de82 Merge branch 'master' into merge_C4_25999_61235_61730 2025-07-17 11:21:47 +02:00
chfhtw 8191c5e19f CSS update 2025-07-16 16:47:12 +02:00
ma0068 2f5a7addbd Tab Details: Bugfix use cleanedFeedback to avoid empty alerts because of updateam, updatevon in result.data 2025-07-16 15:11:20 +02:00
chfhtw 78a735f277 Event popup inside calendar component 2025-07-16 13:52:45 +02:00
chfhtw 26b40866fc CSS updates 2025-07-16 13:51:37 +02:00
SimonGschnell 99f9509134 refactor(Cis4 Wave Accessability): adds accessability attributes to the searchbar components 2025-07-16 12:56:49 +02:00
ma0068 c36459b508 Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' of github.com:FH-Complete/FHC-Core into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-07-16 11:44:55 +02:00
ma0068 1ff3f7b66d Display current semester status in Detail Header
- adapt function get
- adapt functions getPrestudents, get Students, get Prestudent, getStudent, get Person
- add Phrase Student auswaehlen
2025-07-16 11:41:23 +02:00
SimonGschnell ba3914c1c3 refactor(Cis4 Wave Accessability): adds more accessability attributes to the cis4 views 2025-07-16 11:08:00 +02:00
SimonGschnell f210bb8bbd refactor(NewsWidget responsive):updates the resonsive classes of the newsWidget 2025-07-16 11:06:47 +02:00
chfhtw 90b944a047 configureable "no-events" message 2025-07-16 09:57:03 +02:00
chfhtw 0aef00bd9e use Timezone 2025-07-16 08:58:02 +02:00
SimonGschnell a737dc20dc refactor(Layout Lvplan widget): margin adjustment 2025-07-15 14:59:45 +02:00
SimonGschnell 81280a5e91 refactor(Studium accessibility): adds accessability attributes to the studium component 2025-07-15 14:29:26 +02:00
SimonGschnell 2222199b95 refactor(ProfilUpdate components accessability): adds accessability attribute to profil update components 2025-07-15 14:17:44 +02:00
SimonGschnell 133a611d0e update(Profil Modal attribute rename): refactor of attributes and styles 2025-07-15 13:35:38 +02:00
chfhtw 08404a9440 all-day-events not in scrollable part 2025-07-15 13:35:13 +02:00
SimonGschnell c69be4762e refactor(renderer components accessibility) adds the aria accessibility attributes and tooltips to the renderer components of the LvPlan 2025-07-15 13:19:47 +02:00
SimonGschnell c91b2481eb refactor(Modal component): don't pass the properies to the v-bind of the bootstrap modal (title prop was added as an attribute to modal div, creating a tooltip) 2025-07-15 13:16:39 +02:00
Harald Bamberger c3d0f03704 remove unnecessary addMetas, add table alias to fix Prestudent Filters in StvTree 2025-07-15 13:06:08 +02:00
SimonGschnell 9e06f1468a refactor(Location change FHC Core Event): changes the location of the Events for the FHCore App to the original folder 2025-07-15 12:01:46 +02:00
chfhtw 77e5dfeb9a add Luxon 2025-07-15 11:18:01 +02:00
chfhtw da9f00fff0 add Calendar 2025-07-15 11:17:49 +02:00
Harald Bamberger 4872792890 prevent cis search from searching in private email addresses and phone numbers 2025-07-14 16:19:13 +02:00
Harald Bamberger 7aa074cdf6 use uselanguge when searching cms content, remove flags from cms content results, use cms and dms searchtypes in cis4 2025-07-14 15:51:42 +02:00
ma0068 cb48c1e5e3 Tab Details: add tbl_benutzer to update logic 2025-07-14 15:48:37 +02:00
SimonGschnell 9fe7dd069f refactor(LvPlan Lektoren in LV Ansicht): passt die Ansicht der Lektoren in den LVs des LvPlan an wenn mehrere Lektoren vorhanden sind 2025-07-14 15:23:57 +02:00
Harald Bamberger 3ed2bb4d78 add uid@DOMAIN to emails result for prestudent and student, mergedperson render student only results, add searchresult_inaktiv css class to inactive users 2025-07-14 15:16:21 +02:00
Harald Bamberger a1fe2e1b4b fix SearchLib bug, add searchtypes config studentcis and active_organisationunit, use new searchtype in cis4 searchoptions and searchbar result rendering 2025-07-14 13:57:37 +02:00
ma0068 c9cced3f61 bugfix firma_id: define default as null instead of empty string 2025-07-14 13:09:52 +02:00
ma0068 9d341cc045 getFunction for Student: restrict select attributes for person, update mitarbeiter model 2025-07-14 10:23:05 +02:00
Harald Bamberger c89b88ec1b prevent loading huge list of lvs when deleting an lv 2025-07-11 17:46:54 +02:00
ma0068 22afddc2ae add changes for detail header of Vertragsverwaltung 2025-07-11 14:21:56 +02:00
SimonGschnell 1bf49ad7ab fix(Profillib): data handling fix 2025-07-11 11:50:53 +02:00
Harald Bamberger 31fbaaa017 remove unnessecary 0byte files 2025-07-11 11:30:13 +02:00
SimonGschnell 28e42163a1 fix(Profil fotoStatus): changes how fotoStatus is evaluated for different views 2025-07-11 11:10:35 +02:00
SimonGschnell 75a93523e0 refactor(Profil endpoint): changes how the parameter is passed to the profil endpoint 2025-07-11 11:01:18 +02:00
SimonGschnell c2cc1c5870 fix(Profil viewData): fixes little data conversion error in the endpoint 2025-07-11 09:14:34 +02:00
ma0048 5bda4db592 unr beim kopieren setzen
gruppen anzeige direktinskription rausgefillert
datatree aufklappen bug gefixed
kurzbz bei den icons statt eigene spalte
2025-07-11 07:33:10 +02:00
SimonGschnell 2deef8039d update(LvPlan color contrast): changes the colors for some of the text in the lvplan component for more contrast 2025-07-10 14:32:26 +02:00
SimonGschnell dba435dafb fix(VueDatepicker darkmode): updates the dark mode property of the vueDatePicker if the theme is switched to light or dark mode 2025-07-10 12:10:39 +02:00
SimonGschnell 6f3759d95d update(Wave accessability): updates aria labels for accessability 2025-07-10 11:47:51 +02:00
SimonGschnell 129b8b2e49 refactor(LvPlan Widget renderer component): adds the renderer component to the lvplan widget 2025-07-10 11:47:22 +02:00
ma0068 7039719700 Tab Messages: show reply button only if not disabled 2025-07-10 11:31:24 +02:00
ma0068 08a394cad0 add eventListener to prevent bootstrap dialog from blocking focusin in tinymce linking popup 2025-07-10 09:47:09 +02:00
ma0068 8138e23e71 set tabulator_row overflow just jor abschlusspruefung to visible 2025-07-10 09:12:01 +02:00
SimonGschnell d526a770c5 refactor(Wave accessability changes): changes color contrasts and fixes other little bugs 2025-07-09 13:35:21 +02:00
SimonGschnell 8ce672d914 refactor(Profil Library): exports Profil functions in its own library to reuse functionalities 2025-07-08 13:33:00 +02:00
Harald Bamberger 1a0374bf18 fix stv list filters 2025-07-08 11:07:07 +02:00
Harald Bamberger 3f9564b686 anrechnungen notiz layout cleanup, use tabulator layout fitDataStretchFrozen 2025-07-07 16:21:04 +02:00
Harald Bamberger e4fc936991 Merge branch 'master' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-07-07 15:52:11 +02:00
Harald Bamberger 2262169699 filter component set default height only if no height attribute is set in tabulatoroptions. remove reactivedata default setting and old todo comments 2025-07-07 15:47:34 +02:00
ma0068 ddea3afde4 Adaptions FHC-Alert
- restructure plugins Api, FhcAlert ans Phrasen to use Phrasen in Fhc-Alert
– fix behaviour alert warning: show always clossing cross, and symbol
- fix behaviour alert error: add scrolling to Text MessageError
- phrases alerts
2025-07-07 15:36:12 +02:00
kindlm 411fd8d056 Merge remote-tracking branch 'origin/master' 2025-07-07 14:25:47 +02:00
kindlm ca9eea6134 Merge branch 'TesttoolAdminOptimierungen' 2025-07-07 14:25:26 +02:00
kindlm b1ab0ddf18 Zeilenumbruch, wenn Fragen-Liste zu lang 2025-07-07 14:23:59 +02:00
Harald Bamberger cfe76e09b1 AntragJob StglSammelmail an alle Stgleiter senden 2025-07-07 11:47:06 +02:00
ma0048 7bd0b39f77 resetting currentTreeLevel 2025-07-07 11:14:02 +02:00
ma0068 4937c1190a bugfix: warning html-tags 2025-07-07 11:13:37 +02:00
SimonGschnell 5280943099 fix(Studium):checks if the query of the data in the studium endpoints returns an array otherwise return empty array to avoid breaking the endpoint 2025-07-07 10:11:10 +02:00
ma0048 aca49114be anmerkung zur bewerbung weiterleiten 2025-07-07 09:56:34 +02:00
ma0048 5b2b715a16 userstory 61241: bugs behoben 2025-07-07 08:59:36 +02:00
Johann Hoffmann 101636e9fc timeline tooltip 2025-07-04 11:31:13 +02:00
ma0068 88adb8b139 Tab Messages: fix input Variables in TinyMCE 2025-07-04 07:43:21 +02:00
kindlm d47fd105ed Merge remote-tracking branch 'origin/master' 2025-07-03 17:37:27 +02:00
kindlm a0e4c3d93b GUI-Optimierung Testtool-Admin Seite
- Vorschau vs. Derzeit
- Tab-Zeichen wird bei Tab-Taste eingefügt
- Parse-Error wird bei nicht-wohlgeformtem XML angezeigt
- Button um MathML größer anzuzeigen
2025-07-03 17:37:16 +02:00
Harald Bamberger d48865d2a1 only show lvs with lehre flag true in degree programs overview 2025-07-03 16:37:45 +02:00
Harald Bamberger c8e7adc074 alter ferien query to get overlapping events e.g. summer holidays 2025-07-03 16:17:31 +02:00
Johann Hoffmann 475290e3ef yet another phrase 2025-07-03 15:47:06 +02:00
SimonGschnell b46c0147a0 update(Filter Component): uses fhc-text instead of text-dark for the filter icon of the filter component 2025-07-03 15:30:38 +02:00
SimonGschnell e659e8e12c update(Profil Tabulator Columns):preloads phrasen for the tabulator tables, otherwise the column titles are not displayed 2025-07-03 15:30:02 +02:00
Harald Bamberger 014a034ce8 add VB function to get last vb stunden before altersteilzeit 2025-07-03 14:53:53 +02:00
Johann Hoffmann 7fc98bd6a4 tooltip update 2025-07-03 13:23:47 +02:00
Johann Hoffmann 919471d067 phrasen adjustment & error catch cases 2025-07-03 11:32:00 +02:00
Johann Hoffmann 4b26067380 moar anw phrasen 2025-07-02 15:20:17 +02:00
ma0068 ac1335a50d Notizen as Modal 2025-07-02 14:53:44 +02:00
SimonGschnell 5ddc4749fa update(Accessability changes):adds aria-label to empty buttons and more accessability changes 2025-07-02 14:35:07 +02:00
ma0048 31f0be35c8 selbe person auch wenn nicht abbrecher 2025-07-02 12:53:54 +02:00
SimonGschnell bf1dac3fd9 update(LvPlan Feiertage): checks if the query result is array before performing array operations and returns success status instead of raw data 2025-07-02 08:55:30 +02:00
ma0068 9315503ec1 Header: use comma in name only if posttitel exists 2025-07-01 15:46:09 +02:00
ma0068 c353e854e8 Tab Anrechnungen/Exemptions
- bugfix handle overflow in textfield of Notiz
- bugfix delete: remove anrechnung_id also from lehre.tbl_anrechnung_anrechnungstatus
- redesign Notizen of Anrechnungen: header with title Lehrveranstaltungen
- add reload functionality to update count of notizen in action buttons
2025-07-01 14:32:33 +02:00
Harald Bamberger e9614e8ca8 add css classes searchbar_label and searchbar_value to improve responsiveness of results in Cis4 2025-07-01 12:12:48 +02:00
Harald Bamberger 34220a8f39 add alt text to profile picture 2025-06-30 17:10:13 +02:00
Harald Bamberger 986d1cfb5f add aria-label to skip link and raumsuche tabulator links, move skip link to html body, change raumsuche h2 to h1 2025-06-30 17:02:45 +02:00
SimonGschnell 83ac1abcf6 update(LvPlan Events): overflow css fix for the LvPlan Events 2025-06-30 15:27:15 +02:00
SimonGschnell 9c30b5438f update(StundenplanLib StundenplanQuery): removes the ort_kurzbz from the group by because the ort_kurzbz should be grouped in the aggregate function 2025-06-30 15:27:15 +02:00
Harald Bamberger ed17e87afd dbupdate create Cis40 dashboard if it does not exist, 61730_Dashboard_Anpassungen only output message if something was updated 2025-06-30 14:51:42 +02:00
SimonGschnell 5b10c87e9b update(LvPlan Feiertage):if loggedin person does not have a studiengang, only consider studiengang 0 2025-06-30 14:31:05 +02:00
Johann Hoffmann 1c73fdc83c phrasen 2025-06-30 13:12:21 +02:00
Harald Bamberger 98f1cd7465 Merge branch 'feature-61795/FHC4_STudierendenverwaltung_Mobilitaeten_Update' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-06-30 11:49:59 +02:00
SimonGschnell 1c29bcd685 feature(LvPlan Feiertage): adds endpoint to fetch feiertage and adds renderer components for the feiertage in the LvPlan 2025-06-30 11:40:18 +02:00
ma0068 414e4c9565 Tab Abschlusspruefung: add Berechtigungen Studiengang backend: insert, update, delete 2025-06-30 11:39:16 +02:00
ma0068 19ef7c2ce1 Tab Abschlusspruefung: bugfix printDocument 2025-06-30 10:32:28 +02:00
ma0068 fbb00a2616 Tab Abschlusspruefung
- set textfield protokoll readonly
- update: add updatevon, updateamum
- selectedFields vorsitz, pruefer: set default null
2025-06-30 08:52:40 +02:00
SimonGschnell e3fe20831e update(Profil Profilbild): changes styling layout and polishment 2025-06-27 11:36:40 +02:00
cgfhtw 0adf7ee9dc Fix "Spaltenbreite wird nicht gespeichert" for Kontakt Tabs: use Filtercomponent default layout 2025-06-27 09:52:18 +02:00
SimonGschnell 9610ca55f7 update(Profil Profilbild): first version of the profilbild upload endpoint 2025-06-26 15:21:09 +02:00
Andreas Österreicher d64f5610c9 Merge branch 'feature-55989/micro_degree_vorlage_im_fas_hinterlegen' 2025-06-26 08:13:27 +02:00
Andreas Österreicher 444f7aec48 Merge branch 'master' into feature-55989/micro_degree_vorlage_im_fas_hinterlegen 2025-06-26 08:12:13 +02:00
Andreas Österreicher 4dbffc3527 Projektliste zieht die Pflichtpuase nicht mehr automatisch ab wenn keine
Pause manuell gebucht wurde. (Task 62601)
2025-06-25 17:48:09 +02:00
cgfhtw af2aa416aa Documents: Doubleclick-Download like in Archive 2025-06-25 16:50:36 +02:00
cgfhtw c9cc86fdbd Archiv: Downloadbutton in actions column 2025-06-25 16:50:03 +02:00
cgfhtw aec0162c01 Konto: Buchungstypen order 2025-06-25 16:49:29 +02:00
Johann Hoffmann 057288a4a5 phrasen & rechte rename 2025-06-25 16:02:51 +02:00
Harald Bamberger 7c251cafc7 Merge branch 'merge_FHC4__55354_55991_55992_60874_60875_61229_61230_61231_TabAbschlusspruefung' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-06-25 15:52:09 +02:00
Harald Bamberger c2ce61d885 Merge branch 'feature-62055/FHC4_Studierendenverwaltung_Detailheader_Update' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-06-25 15:42:56 +02:00
SimonGschnell cbc9a87a47 update(Profil Profilbild): adds button to upload new profil foto if foto is not yet acepted 2025-06-25 11:22:14 +02:00
cgfhtw c3ec34a038 Code Quality to be compatibler with feature-40128 2025-06-25 09:39:19 +02:00
cgfhtw e385a06b73 merge_C4 compatibility 2025-06-25 09:36:47 +02:00
cgfhtw b344b5925a Use Advanced search for CIS & StV 2025-06-24 15:19:21 +02:00
cgfhtw 7b627484c2 Code Quality 2025-06-24 15:01:26 +02:00
SimonGschnell e99cbc9f3d fix(lvMenu optionen):fixes click event bugs with the lv menu and changes the styling for some lvmenu options 2025-06-24 13:28:32 +02:00
cgfhtw cc40fd4393 Safetycheck FHCAPI plugin 2025-06-24 12:15:10 +02:00
cgfhtw 7233bc3cdd Bugfix missing css variable 2025-06-24 11:23:22 +02:00
cgfhtw 301818be69 Fallback "room" for "raum" searchactions 2025-06-24 11:17:00 +02:00
cgfhtw 8c1c56077e CIS: Search-Origin 2025-06-24 11:00:51 +02:00
SimonGschnell f7c03b29db refactor(Studiengang Widget Data): filters only active persons of studiengang information 2025-06-24 10:35:20 +02:00
cgfhtw b217118df4 Cleanup & Phrases 2025-06-24 10:00:35 +02:00
SimonGschnell d76e3feb2a update(LvPlan Month Event tooltip): adds a tooltip to the month lv plan events that contains more detailed information about the lv event 2025-06-24 09:32:19 +02:00
Harald Bamberger b9a920e498 Merge branch 'feature-60876/FHC4_Studierendenverwaltung_Funktionen_als_Corecomponent' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-06-23 17:37:00 +02:00
Harald Bamberger 9426ed9e59 disable headerSort for actions column 2025-06-23 17:36:37 +02:00
Harald Bamberger be6f5b6772 Merge branch 'merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-06-23 17:32:23 +02:00
Harald Bamberger ce8f0843cc calc active tab from router param when using primevue tabsview 2025-06-23 17:31:43 +02:00
cgfhtw 2ec20423e9 Stv: Search-Origin 2025-06-23 14:24:20 +02:00
cgfhtw 5645f6a41f Language API Endpoint 2025-06-23 14:24:11 +02:00
cgfhtw 5bf8f647cb Cms Results 2025-06-23 14:21:06 +02:00
cgfhtw ad7e473cbd Dms Results 2025-06-23 14:14:51 +02:00
cgfhtw d00530d6d6 Organisationsunit Results 2025-06-23 13:54:36 +02:00
cgfhtw cf62563fa3 Room Results 2025-06-23 13:48:52 +02:00
cgfhtw b96a7ab180 Person Results 2025-06-23 13:28:56 +02:00
SimonGschnell 4d61cdeb91 fix(LvPlan route): changes the route on change:range instead of change:offset because the focusdate is updates in change:range 2025-06-23 11:54:42 +02:00
SimonGschnell 30e4459f67 fix(LvPlan renderer) uses Vue.nextTick to acknowledge the suspense state of the dynamically loaded component 2025-06-23 11:44:08 +02:00
SimonGschnell 1d9936757c update(LvPlan router) manages the route changes in the Calendar component instead of the LvPlan 2025-06-23 11:37:33 +02:00
cgfhtw b46da92f25 Employee Results 2025-06-23 11:16:57 +02:00
cgfhtw 04d46b39ed MergedPerson Results 2025-06-23 11:16:20 +02:00
cgfhtw 819ef7bc32 Bugfix this => this.res 2025-06-23 10:48:50 +02:00
cgfhtw 0202bb261f MergedStudent Results 2025-06-23 10:45:28 +02:00
cgfhtw 0b00e393da Student Results 2025-06-23 09:51:52 +02:00
cgfhtw bc79fe2dd6 Prestudent Results 2025-06-23 09:26:09 +02:00
cgfhtw a2250fc727 Add meta information for search mode 2025-06-23 09:01:11 +02:00
Harald Bamberger 4f56d799ac remove private attribute 2025-06-23 07:43:39 +02:00
cgfhtw 707a05f6cd Adding changes from merge_c4 branch to searchbar component 2025-06-20 12:41:20 +02:00
Harald Bamberger cac58a0fc2 Merge branch 'feature-60876/FHC4_Studierendenverwaltung_Funktionen_als_Corecomponent' into merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231 2025-06-20 11:48:11 +02:00
ma0068 cb87b072b3 Merge branch 'merge_FHC4__55354_55991_55992_60874_60875_61229_61230_61231_TabAbschlusspruefung' of github.com:FH-Complete/FHC-Core into merge_FHC4__55354_55991_55992_60874_60875_61229_61230_61231_TabAbschlusspruefung 2025-06-18 16:57:38 +02:00
ma0068 37701dbdfd disable dropdown property for pruefer 2025-06-18 16:57:22 +02:00
Harald Bamberger 96e032bad9 add missing .js file extension 2025-06-18 16:46:47 +02:00
Johann Hoffmann 913211e84d even more & better anw phrasen 2025-06-18 16:23:35 +02:00
cgfhtw 6e9650ddfa Bugfixes: Searchbar state in localStorage/sessionStorage 2025-06-18 15:19:30 +02:00
ma0068 85c16b7f5d Refactor dropdowns
- use allPersons for Dropdown Autocomplete Pruefer1, Pruefer2, Pruefer3
- use allMitarbeiter for Dropdown Autocomplete Vorsitz
2025-06-18 15:04:08 +02:00
SimonGschnell 23e32a51b2 update(LvPlan Reservierungen):renderer componente erstellt und in Events geladen + styling fixes 2025-06-18 12:26:20 +02:00
ma0068 ae10ac877f Tab Adressen: add handling selected Firma for edit and save 2025-06-18 09:02:24 +02:00
Harald Bamberger d558240459 Merge branch 'feature-61282/SearchbarLocalStorageDifferntiation' into merge_C4_25999_61235_61730 2025-06-17 12:45:33 +02:00
Harald Bamberger 52c4ac64f1 remove unused import and uuid helper 2025-06-17 12:44:24 +02:00
Harald Bamberger d3b3c9db41 fix typo 2025-06-17 11:44:26 +02:00
Harald Bamberger 1c7d339e14 stundenplan/lvplan revert changes to jobs/LVPlanJob 2025-06-17 11:06:29 +02:00
Harald Bamberger 4db21d9abb stundenplan/lvplan use reverted classes and function names again 2025-06-17 11:05:31 +02:00
cgfhtw 2b3d772a90 Both searches usable 2025-06-17 10:50:29 +02:00
Harald Bamberger 3db82aea95 stundenplan/lvplan revert changes to stundenplan_model and stundenplandev_model 2025-06-17 10:26:29 +02:00
Harald Bamberger a080daa27a stundenplan/lvplan revert changes to legacy api endpoints 2025-06-17 10:16:54 +02:00
cgfhtw e8d6d751e6 searchAdvanced in new API 2025-06-17 09:48:35 +02:00
cgfhtw fa20652fef Permissions for searchAdvanced 2025-06-17 09:48:20 +02:00
cgfhtw 0aa92debea Phrasen 2025-06-17 09:25:40 +02:00
cgfhtw f596f16255 Merge branch 'master' into feature-40128/Mehrere_Suchergebnisse_für_selbe_Person 2025-06-17 09:24:18 +02:00
Harald Bamberger b6cb9b356f Merge branch 'master' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-06-17 08:57:05 +02:00
ma0068 329da58ce6 Tab Aufnahmetermine: add validation for existing RT-Data 2025-06-16 17:14:55 +02:00
ma0068 cb2ed4696c Tab Betriebsmittel: change type of field Kaution to number, add validation if numeric 2025-06-16 16:01:41 +02:00
ma0068 5140d9de31 refactor Accepting and Unaccepting Documents, new Error Message if more than one document per type, refactor List Accepted Documents 2025-06-16 15:38:56 +02:00
Harald Bamberger 0804c5670e refactor css variables 2025-06-16 15:36:32 +02:00
SimonGschnell 66ccd83b55 refactor(LvPlan): changes the lvInfo and lvMenu component in the Page View to use the renderer components based on the event type 2025-06-16 14:14:49 +02:00
cgfhtw 688f87e2ba New Endpoint for advanced search 2025-06-16 11:57:27 +02:00
Harald Bamberger 9ed68648f6 declare css variables per component file with fallback default 2025-06-16 11:33:15 +02:00
SimonGschnell 57b0ae12d5 update(LvPlan router):changes the route parameters when changing the week in the weeks overview 2025-06-16 10:58:23 +02:00
SimonGschnell 2aa3e7704f fix(style):adds missing border 2025-06-16 10:57:16 +02:00
cgfhtw f321e07731 Move new SearchBarLib to SearchLib 2025-06-16 10:22:28 +02:00
SimonGschnell 9e0bad76ac refactor(Studium): uses link color that adjusts to dark mode and adjusts the button directions next to the select fields of the Studium View 2025-06-16 09:30:40 +02:00
ma0068 7b5b6992c7 Tab Kontakt: Adresse: use Autocomplete and Dropdown for Firma, Bankverbindung: use authUID 2025-06-13 13:02:26 +02:00
SimonGschnell e4100f5fb0 refactor(Calendar Events Layout): changes the layout of the calendar events adjusting to different renderer components 2025-06-13 12:04:31 +02:00
ma0068 44c5b1dd5e Tab Kontakt: refactor displaying of kontakttyp, add updateamum, updatevon, filter kontakttyp hidden 2025-06-12 19:29:06 +02:00
ma0068 cd26667707 refactor backend validierung 2025-06-12 18:40:01 +02:00
Harald Bamberger 3a7e14a95f update composer.lock 2025-06-12 18:07:03 +02:00
Harald Bamberger 40a0affed9 add neutral fhcomplete logo for default theme 2025-06-12 17:38:17 +02:00
Johann Hoffmann fce55e38ae more & better anw phrasen 2025-06-12 17:18:52 +02:00
Harald Bamberger 3adaf8a528 make logo configurable in theme, add fhcomplete logo as default 2025-06-12 16:57:27 +02:00
Harald Bamberger 982373d03b style StudiengangInformation 2025-06-12 15:53:35 +02:00
SimonGschnell 565925abb2 fix(typo) 2025-06-12 14:03:32 +02:00
SimonGschnell 06c822fd84 fix(foto for Studiengang information widget): adds foto property for studiengangs personen that are displayed with a foto 2025-06-12 14:01:27 +02:00
SimonGschnell aed293f93d fix(removes debug print in LvPlan): removes debug prints and changes parameter for the showModal function in LvPlan Day View 2025-06-12 13:55:50 +02:00
SimonGschnell e133f67de2 fix(LvPlan calendarComponent renderer async modal): updates the logic to display the modal for the lv information 2025-06-12 12:32:48 +02:00
Harald Bamberger f017f096f1 add missing component lvinfo, change path Stundenplan to LvPlan 2025-06-12 12:13:08 +02:00
Harald Bamberger 43c868000c LvPlanLib getLvPlan use success or error object for all returns 2025-06-12 12:05:17 +02:00
Harald Bamberger 44b538885f use additional result variable 2025-06-12 11:40:24 +02:00
Harald Bamberger 57d71be792 revert change of loaded StudienplanModel name 2025-06-12 11:39:23 +02:00
ma0068 eb35701280 Tab Gruppen: rewrite inital filter and watcher for working in firefox 2025-06-12 11:32:31 +02:00
Harald Bamberger 7d91976704 remove use of component moodleSVG 2025-06-12 11:18:54 +02:00
ma0068 bd5925e1d6 phrases for author and editor UID 2025-06-12 10:58:43 +02:00
Harald Bamberger 596535b1b9 Merge branch 'master' into merge_C4_25999_61235_61730 2025-06-12 09:51:56 +02:00
ma0068 074403abf5 Tab Notizen: show Name of verfasser and bearbeiter 2025-06-11 17:27:33 +02:00
Harald Bamberger 0f9c98dded messages add translation for tabulator pagination buttons, Tabs component add alternative rendering with primevue tabs and use it in stv details component 2025-06-11 16:56:58 +02:00
Harald Bamberger dc4f8bc640 rename Stundenplan/EventTypes/calendarEvent.js -> LvPlan/EventTypes/calendarEvent.js 2025-06-11 15:38:01 +02:00
ma0068 ab059e9099 refactored detailFilter for Mitarbeiter 2025-06-11 15:29:54 +02:00
Harald Bamberger 90273f64c1 Merge branch 'merge_C4_25999_61235_61730_testremerge' into merge_C4_25999_61235_61730 2025-06-11 15:00:48 +02:00
Harald Bamberger d6f92d23a0 Merge branch 'feature-62366/merge_C4_25999_61235_61730' into merge_C4_25999_61235_61730_testremerge 2025-06-11 14:56:57 +02:00
Harald Bamberger 7929a6b74b Merge branch 'feature-25999/C4_cleanup' into merge_C4_25999_61235_61730_testremerge 2025-06-11 14:51:09 +02:00
Harald Bamberger d83eb42a23 Merge branch 'feature-25999/C4_cleanup' into merge_C4_25999_61235_61730_testremerge 2025-06-11 14:49:26 +02:00
kindlm 45b9bae0b0 Merge remote-tracking branch 'origin/master' 2025-06-11 13:40:01 +02:00
kindlm 77ccfa46de Task #62440 Ampelsystem Benutzercount 2025-06-11 13:39:50 +02:00
SimonGschnell 29f968f308 fix(Profil email extern):Profil endpoint does not provide the extern alias email if the benutzer has no alias defined 2025-06-11 11:24:18 +02:00
SimonGschnell 49c510537a fix(Profil Mailverteiler): adds safeguards and checks on the return value of the Mailverteiler of a person 2025-06-11 11:06:35 +02:00
SimonGschnell d2e8505689 refactor(Profil alias): checks if user has alias, creates extern alias email if available otherwise not 2025-06-10 14:49:30 +02:00
SimonGschnell 83d3f515de refactor(Modals and z-index): ensures dashboard modals are in the forground 2025-06-10 13:18:31 +02:00
SimonGschnell c080d1abb2 refactor(Rename Stundenplan to LvPlan):renames all methods and files from Stundenplan to LvPlan 2025-06-10 11:46:19 +02:00
SimonGschnell a786dec9c1 fix(Dashboard grid):emit dragged item on resize and adjust z-index for overlay and dragged item 2025-06-10 10:23:28 +02:00
SimonGschnell 9faccfa328 update(Url Dashboard widget): makes edit buttons always available 2025-06-06 11:27:17 +02:00
SimonGschnell 6d7f8522f3 refactor(Moodle Events DependencyInjection): resolves lazy loading bug 2025-06-06 09:57:59 +02:00
Harald Bamberger 970e950894 tune layout of new message modal, fix pagination of message table 2025-06-05 17:06:55 +02:00
SimonGschnell 2821339c0a refactor(Dashboard dragging): removes dragging flag from the draggable state 2025-06-05 11:42:21 +02:00
Harald Bamberger 68b6402981 fix height of calender exceeding viewport height 2025-06-05 11:28:37 +02:00
ma0068 826dd52450 - show Profilpicture with lock symbol if foto_sperre
- enable scrolling for multi view
- show uid beneath profile picture
- use phrases in detail header
2025-06-04 13:59:00 +02:00
SimonGschnell e89233d6ac update(LvInfo): adds the file LvInfo again because it is used in a different component 2025-06-04 09:41:33 +02:00
Harald Bamberger c85e902b97 Merge branch 'feature-61730/Cis4_DashboardAnpassungen' into merge_C4_25999_61235_61730 2025-06-03 16:14:59 +02:00
Harald Bamberger d1264c7e5a Merge branch 'feature-61235/Cis4_Studium_Uebersicht' into merge_C4_25999_61235_61730 2025-06-03 16:14:00 +02:00
ma0068 7da8a9ed79 refactor header as component, show uid under profilpicture 2025-06-03 10:39:22 +02:00
Harald Bamberger 96274a2a4a Merge branch 'feature-25999/C4_cleanup_testabgabe' into merge_C4_25999_61235_61730 2025-06-03 10:29:33 +02:00
Harald Bamberger fb01629ec1 Merge branch 'feature-25999/C4_cleanup_testabgabe' into feature-25999/C4_cleanup 2025-06-03 10:29:01 +02:00
Harald Bamberger 02dd466cc3 use green and red as for marking the datepickers 2025-06-03 09:44:03 +02:00
SimonGschnell 7e90771f89 refactor(Moodle Events DependencyInjection): changes the lazy loading for the moodle events in Stundenplan 2025-06-03 09:30:10 +02:00
SimonGschnell a2dee4d6ba feature(FHC Core Renderer Event): adds the FHC Core renderer Event to the loadRenderer Event 2025-06-03 09:24:54 +02:00
ma0048 3e3fa9c1eb svnr aus dem fas entfernt 2025-06-03 08:57:28 +02:00
Harald Bamberger 3ff0f55cc0 tune layout of new message modal 2025-06-03 08:05:38 +02:00
ma0068 96fcff3ade add Event mobility_delete 2025-06-02 13:47:49 +02:00
ma0068 f233b33093 add information to header 2025-06-02 10:29:14 +02:00
SimonGschnell c62b587299 refactor(moodle Event Info):adds the component for moodle event information to the rendered components from the moodle Event 2025-06-02 09:23:14 +02:00
Harald Bamberger 8810657a61 adapt styling message modal, message newdiv, counter display in studentslist 2025-05-30 18:22:53 +02:00
Harald Bamberger ba1ef83ba6 delete entry in tbl_studentlehrverband only if last prestudent status for the semester is deleted, update possibly existing entry in tbl_studentlehrverband when advancing prestudentstatus 2025-05-30 12:38:35 +02:00
Harald Bamberger 0da195810b set updateamum and updatevon, store verband, semester, gruppe in tbl_student if selected semester is current semester 2025-05-30 12:35:48 +02:00
Harald Bamberger b885a8c72d fix getting set to null if e.g. base64 images is sent in request json 2025-05-30 12:34:18 +02:00
Harald Bamberger 42b750e120 add selectedcount add phrases for counts label 2025-05-28 17:31:24 +02:00
Harald Bamberger cb1f6e2e5f allow description to be html instead of plain text 2025-05-28 17:29:54 +02:00
Harald Bamberger 9d48b6ac57 use popupModal layout of notiz component 2025-05-28 17:29:02 +02:00
Johann Hoffmann 3cebbc9fba modal optional expand to full size button - used for qr window; added missing phrase editEntschuldigung; 2025-05-28 17:04:07 +02:00
Harald Bamberger 8bcf01d1bb alter document download to use dmslib and new terminateWithFileOutput funtion of FHCAPI_Controller, render download button as link 2025-05-28 16:38:26 +02:00
Harald Bamberger 4d3d06e1d6 add function to output a file 2025-05-28 16:36:56 +02:00
Harald Bamberger cfa391677e remove duplicate tabulatorEvents in computed 2025-05-28 13:22:27 +02:00
SimonGschnell a5bb72baf6 feature(Stundenplan Moodle Events Dependency Injection): injects moodle components dependency to the Stundenplan 2025-05-28 12:30:38 +02:00
ma0068 a756881a48 refactor delete
refactor validation backend
add permission check for studiengang backend
2025-05-28 09:14:49 +02:00
Harald Bamberger c9b555db77 swap div and form-input end-tag 2025-05-28 08:22:22 +02:00
Harald Bamberger bbf0d044fd use existing phrasename 2025-05-28 08:20:33 +02:00
ma0048 f96bfbe000 lehrfächerverteilung v1 2025-05-28 07:51:10 +02:00
Harald Bamberger 390434050e add missing end tag, add missing .js file extension 2025-05-27 17:39:33 +02:00
Harald Bamberger 0ee5cc09cd add missing .js file extension 2025-05-27 17:30:50 +02:00
SimonGschnell a0fb34420e fix(Stundenplan API):corrects little bug with if statement check 2025-05-27 14:30:34 +02:00
Harald Bamberger b40e1a2c65 fix syntax error 2025-05-27 11:05:24 +02:00
Harald Bamberger 4daf73ee6d Merge branch 'master' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-05-27 10:31:12 +02:00
Andreas Österreicher a52fcf1570 Merge branch 'feature-61601/Issue_Liste_hartcoded_eingeschraenkt' 2025-05-26 13:00:23 +02:00
Alexei Karpenko 5d241b050a issue list: renamed config 2025-05-26 11:16:50 +02:00
Alexei Karpenko 660f195c57 issue list: removed empty space and removed const which was moved to config 2025-05-26 11:03:33 +02:00
Andreas Österreicher 9b0e0fe135 Merge branch 'feature-61751/infocenter_absage_fuer_alle' 2025-05-26 10:59:38 +02:00
Andreas Österreicher 867afa4411 Merge branch 'master' into feature-61751/infocenter_absage_fuer_alle 2025-05-26 10:41:40 +02:00
ma0068 fa0b534471 Refactoring PrimeVue Autocomplete Dropdown Functions
Refactoring PrimeVue Autocomplete Dropdown OrganisationUnits
Change Search from Backend to Frontend Filtering
minor changes Table Functions
2025-05-23 13:27:18 +02:00
SimonGschnell b5bacbbf75 refactor(Studium): changes the query to fetch lehrveranstaltungen for the studienplan 2025-05-23 12:02:13 +02:00
SimonGschnell ad8963e5b5 refactor(Dashboard touch events): allows to scroll on mobile over widgets, fixes dragging bug on mobile 2025-05-23 11:33:58 +02:00
ma0048 fce63eb31b svnr aus dem infocenter entfernt 2025-05-23 10:35:47 +02:00
Alexei Karpenko 94f0d43c4a issues config: removed empty lines 2025-05-23 09:59:13 +02:00
SimonGschnell deec52b959 refactor(Studium): disallows to store null or undefined to the localStorage and changes the next and previous button logic for the select fields 2025-05-23 09:11:22 +02:00
Harald Bamberger 126b2d388b fix upload and adapt styling of Abgabetool Student 2025-05-22 18:55:34 +02:00
Harald Bamberger 4c6c45ceec change Layout of Notizen component to use form in modal 2025-05-22 18:50:30 +02:00
Alexei Karpenko 80faf92dc2 made issue list configurable (apps, status, functions) 2025-05-22 18:41:26 +02:00
Harald Bamberger d686ec0885 Merge branch 'feature-61730/Cis4_DashboardAnpassungen' into merge_C4_25999_61235_61730 2025-05-22 07:48:23 +02:00
Harald Bamberger a387533dc3 Merge branch 'feature-61235/Cis4_Studium_Uebersicht' into merge_C4_25999_61235_61730 2025-05-22 07:45:30 +02:00
Harald Bamberger f8438ee115 Merge branch 'feature-25999/C4_dark_theme' into merge_C4_25999_61235_61730 2025-05-22 07:44:42 +02:00
Johann Hoffmann 12ca915b00 ddi/ddo text in legende old anw liste; studentdropdown order changed; email datumformat d.m.y; 2025-05-21 18:16:01 +02:00
Cristina c3e978b56e Adapted Input.js radio/checkbox label to accept HTML 2025-05-21 18:10:03 +02:00
Cristina 7e83df51a8 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-05-21 18:05:40 +02:00
Johann Hoffmann a99cc96682 fix missing "import VueDatePicker from '../../vueDatepicker.js.php';" statements for new cis4 pages abgabetool & raumsuche 2025-05-21 16:37:00 +02:00
Harald Bamberger f6dd79b9a3 Merge branch 'feature-61231/FHC4_Studierendenverwaltung_Aufnahmetermine' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-05-21 16:31:29 +02:00
Harald Bamberger ede656845a Merge branch 'feature-61230/FHC4_Studierendenverwaltung_LVTermine' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-05-21 16:25:36 +02:00
Harald Bamberger f5a3598c39 Merge branch 'feature-61229/FHC4_Studierendenverwaltung_GemeinsameStudien' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-05-21 16:18:43 +02:00
ma0068 66e5384de6 cleanup: remove not needed code and files 2025-05-21 16:01:37 +02:00
Harald Bamberger 55419c50f7 Merge branch 'feature-60875/FHC4_Studierendenverwaltung_Anrechnungen' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-05-21 15:42:17 +02:00
ma0068 c26bb98960 new Core Component Function
- autocomplete and dropdown field for search oes and search functions with active and non active entries
- possibility to dynamic styling of display switch, newButton in Tabulator, different editLabels
- possibility to show/hide column company
- possibility to show/hide to save function as copy
2025-05-21 15:34:43 +02:00
Andreas Österreicher d677cee1f9 Merge branch 'feature-56330/Digi-Anw-Feedback' 2025-05-21 15:27:31 +02:00
SimonGschnell a1423c33e5 update(Studium): fetches the preselect lehrverband values if the user is a student 2025-05-21 14:12:16 +02:00
Andreas Österreicher 8786b60c4c Merge branch 'master' into feature-56330/Digi-Anw-Feedback 2025-05-21 14:11:50 +02:00
Harald Bamberger 375d56960a Merge branch 'feature-60874/FHC4_Studierendenverwaltung_Dokumente' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-05-21 13:49:58 +02:00
Harald Bamberger 1faab59716 Merge branch 'feature-55992/FHC4_Studierendenverwaltung_Messaging' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-05-21 13:34:34 +02:00
Harald Bamberger 1ac6e50784 Merge branch 'feature-55991/FHC4_Studierendenverwaltung_Gruppen' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-05-21 13:30:07 +02:00
Harald Bamberger 5d7d532396 Merge branch 'feature-55354/Studierendenverwaltung_Karteireiter_Archiv' into merge_FHC4_55354_55991_55992_60874_60875_61229_61230_61231 2025-05-21 13:29:21 +02:00
Harald Bamberger 5ed1bae456 Merge branch 'master' into feature-61231/FHC4_Studierendenverwaltung_Aufnahmetermine 2025-05-21 13:26:47 +02:00
Harald Bamberger c861278aa8 Merge branch 'master' into feature-61230/FHC4_Studierendenverwaltung_LVTermine 2025-05-21 13:26:14 +02:00
Harald Bamberger 2297055949 Merge branch 'master' into feature-61229/FHC4_Studierendenverwaltung_GemeinsameStudien 2025-05-21 13:25:36 +02:00
Harald Bamberger bf3127d518 Merge branch 'master' into feature-60875/FHC4_Studierendenverwaltung_Anrechnungen 2025-05-21 13:24:52 +02:00
Harald Bamberger 10f731f2e2 Merge branch 'master' into feature-60874/FHC4_Studierendenverwaltung_Dokumente 2025-05-21 13:24:08 +02:00
Harald Bamberger b498da8603 Merge branch 'master' into feature-55992/FHC4_Studierendenverwaltung_Messaging 2025-05-21 13:18:43 +02:00
Harald Bamberger fc30222289 Merge branch 'master' into feature-55354/Studierendenverwaltung_Karteireiter_Archiv 2025-05-21 13:18:16 +02:00
Harald Bamberger cd99ba7fdc Merge branch 'master' into feature-55991/FHC4_Studierendenverwaltung_Gruppen 2025-05-21 13:17:34 +02:00
Andreas Österreicher 9b9351fe9b Merge branch 'bug-62088/dummy_std_beim_reinziehen_im_fas_zu_einer_lv_kommt_eine_fehlermeldung_130_std_und_zuordnung_funktioniert_nicht' 2025-05-21 10:49:49 +02:00
ma0048 02701dc0c5 fixed bug stundengrenze hinweis beim hinzufuegen eines dummy lektors 2025-05-21 10:47:55 +02:00
Harald Bamberger a2b77411cb Merge branch 'master' into feature-55991/FHC4_Studierendenverwaltung_Gruppen 2025-05-21 10:47:48 +02:00
Harald Bamberger 7d4fda4fe6 Merge branch 'master' into feature-55354/Studierendenverwaltung_Karteireiter_Archiv 2025-05-21 10:46:31 +02:00
Harald Bamberger e9a373afb8 Merge branch 'feature-61758/stv_kontakte_get_funktionen_null_abfangen' 2025-05-21 07:11:18 +02:00
Harald Bamberger 1222d33e6e Merge branch 'master' into feature-61758/stv_kontakte_get_funktionen_null_abfangen 2025-05-21 07:10:47 +02:00
SimonGschnell af1364faef update(Studium):changes layout 2025-05-20 16:56:25 +02:00
Andreas Österreicher 2db7f812ab Fehlerkurzbz korrigiert 2025-05-20 11:31:28 +02:00
Andreas Österreicher 8b89d6f1cb Merge branch 'feature-48553/UHSTAT_Meldung_fuer_Privatuniversitaeten' 2025-05-20 11:11:39 +02:00
SimonGschnell da118cbf0a refactor(Studium):groups the studienplaene to their studienordnung, sorts the lehrveranstaltungs module and the single lehrveranstaltungen 2025-05-19 12:53:36 +02:00
Harald Bamberger 4e945648d0 Merge branch 'master' into feature-25999/C4_cleanup 2025-05-19 11:00:24 +02:00
Harald Bamberger 310bd08648 Merge branch 'feature-40430/updateamum_von_im_AntragLib' 2025-05-19 10:51:05 +02:00
Harald Bamberger bc4514b2a0 Merge branch 'master' into feature-40430/updateamum_von_im_AntragLib 2025-05-19 10:29:28 +02:00
SimonGschnell 4a10faeb25 update(Dashboard custom Section & additionalRow): the additional row is not removed when moving widgets and the custom section gets also created when created user_overrides 2025-05-19 10:28:15 +02:00
SimonGschnell df108482eb update(Dashboard additionalRow): opens tooltip when hovering over the button to add a now line to the dashboard grid 2025-05-19 09:09:48 +02:00
SimonGschnell 875a788476 update(Dashboard rows and columns): additional row is not removed when going out with the mouse 2025-05-16 09:54:05 +02:00
Harald Bamberger c04c08bca4 finetune datepicker and timepicker config 2025-05-16 08:22:19 +02:00
Harald Bamberger a858049e15 fix viewData prop validator, change nullish coalescing operator to logical or since optional router param is empty string and not an unset prop 2025-05-15 18:54:28 +02:00
SimonGschnell a40f304d8d update(Dashboard DataStructure Migration): also changes datastructure for the dashboard.tbl_dashboard_benuter_override 2025-05-15 12:05:34 +02:00
SimonGschnell ebcb33b316 update(Dashboard DataStructure Migration): adds migration file to change all old datastructures from the dashboard.tbl_dashboard_preset 2025-05-15 12:05:34 +02:00
Harald Bamberger b8d0037e16 Merge branch 'feature-25999/C4_cleanup' into feature-61235/Cis4_Studium_Uebersicht 2025-05-14 15:43:04 +02:00
Harald Bamberger ce2bd3c75d Merge branch 'feature-25999/C4_cleanup' into feature-61730/Cis4_DashboardAnpassungen 2025-05-14 15:33:38 +02:00
Harald Bamberger 7b9b1a762e Merge branch 'master' into feature-25999/C4_cleanup 2025-05-14 15:17:25 +02:00
Harald Bamberger 53f2776efe add CIS_REDIRECT_TO_CIS4 to cis config, add viewport meta tag and alter tw.css and mobile.css to improve layout of index.html and rendering of logos on mobile devices, add logic to redirect users to cis4 after login 2025-05-14 15:16:18 +02:00
Harald Bamberger 3c08bc12cd Merge branch 'feature-61748/FHC-Alert-Plugin_EMail-Address' 2025-05-14 09:20:47 +02:00
ma0048 6e56de1790 null werte abgefangen 2025-05-14 08:33:25 +02:00
ma0048 2417d1549e absage bewerbung abgeschickt beide fuer einzelne studiengaenge ermoeglicht 2025-05-14 08:12:47 +02:00
Andreas Österreicher a72dcdf8b0 Merge branch 'bug-61306/addfaktor_entfernen' 2025-05-13 15:31:20 +02:00
SimonGschnell dab628a72d refactor(Dashboard UX): improves user experience for dashboard 2025-05-13 11:48:01 +02:00
SimonGschnell 8e2fd6e61c refactor(searchbar local/session storage): does not use uuid for localStorage and only saves values to localStorage if searchoptions.origin is defined 2025-05-12 13:58:06 +02:00
SimonGschnell ed2a467926 refactor(Dashboard additional row): changes the UI and behavior to add an additional row to the grid 2025-05-12 13:51:20 +02:00
ma0048 419341f496 absage fuer alle und rueckstellung ueber infocenter uebersicht 2025-05-12 12:53:16 +02:00
SimonGschnell a94b52dbc6 refactor(Dashboard touch events): fixes the touch event behaviors for the widgets and the dashboard 2025-05-12 11:44:27 +02:00
ma0068 12415279d1 hide column and formular field dienstverhaeltnis_unternehmen via prop 2025-05-09 14:08:49 +02:00
Harald Bamberger 4bceddcc82 add systemerror_mailto ci config, render systemerror_mailto to FHC_JS_DATA_STORAGE_OBJECT, use FHC_JS_DATA_STORAGE_OBJECT.systemerror_mailto in FhcAlert Plugins 2025-05-09 13:58:14 +02:00
ma0068 d3dc81eae8 add missing fileendings in imports 2025-05-09 09:51:30 +02:00
SimonGschnell a99721bb22 feature(Dashboard Mobile): the modal to add new widgets distributes the space to display widgetes more evenly 2025-05-09 09:34:12 +02:00
ma0068 233e768aad copy Function files to component 2025-05-09 09:11:33 +02:00
SimonGschnell a6180b3d59 feature(Searchbar Storage): uses UUID's to store searchstr and searchtypes and warn user about missing searchoption origin property 2025-05-08 12:34:35 +02:00
ma0068 9d4568e15e client side placementtest handling, filtering Dropdowns placementtests, Phrases, show future Placementtests, open Reihungstestverwaltung 2025-05-08 09:58:08 +02:00
SimonGschnell b62c063a43 refactor(Searchbar Localstorage): adds the origin of the searchbar to the searchbaroptions and uses it for the localStorage keys 2025-05-07 11:14:59 +02:00
SimonGschnell 7d095b4998 feature(Studium LvModal): checks whether the lv has stundenplan entries and disables menu option if not/ checks the lvevaluierung information and adds it to the lvmodal information 2025-05-07 11:03:12 +02:00
SimonGschnell b5d3bf3f1e update(Cis4 Studium): finilizes Studium feature 2025-05-06 13:30:06 +02:00
Harald Bamberger 05de9cd94a move logic processing moodle events from core to moodle addon 2025-05-06 13:24:08 +02:00
Harald Bamberger 2ee7742ada Merge branch 'master' into feature-25999/C4_cleanup 2025-05-05 16:56:00 +02:00
Harald Bamberger 6ab50654ba add activity title to moodle calender entries, render activity title as html, set overscroll behavior for all day event area 2025-05-05 16:55:06 +02:00
Harald Bamberger 0930866beb revert change introduced by merging api refactoring branch 2025-05-05 13:55:54 +02:00
Andreas Österreicher 7030d5b822 Merge branch 'feature-54827/internationalisierungsmassnahmen_optimierungen' 2025-05-05 11:32:18 +02:00
Harald Bamberger 884a5e41ac Merge branch 'master' into feature-25999/C4_cleanup 2025-05-05 11:20:13 +02:00
Andreas Österreicher 6dfa7089e7 Merge branch 'master' into feature-54827/internationalisierungsmassnahmen_optimierungen 2025-05-05 11:08:25 +02:00
SimonGschnell eae44bc634 update(Studium): loads lehrmodule and lehrveranstaltungen for studienplan and displays the ui with the lvModal 2025-05-02 11:23:39 +02:00
SimonGschnell 9b895fbd23 feature(Studium API endpoinds): adds the api endpoints for the Studium View to get the studienplan from a studiensemester/studiengang/semester 2025-04-30 13:45:01 +02:00
Andreas Österreicher 24b19a1d8b Workaround für Bug in Firefox ab Version 137 wodruch der Weiter Button nicht immer ganz
angezeigt wird
2025-04-30 10:33:37 +02:00
Harald Bamberger 7d3ffdde7b fix api endpoint http error 500 when stundenplan_events is null or empty array 2025-04-29 17:15:32 +02:00
Johann Hoffmann d791a6d3ef phrasen & change email template name to under 32 characters long 2025-04-29 15:03:10 +02:00
Johann Hoffmann 38424bc875 serientermin anlegen mitarbeiter; deadline overview mitarbeiter; 2025-04-29 14:36:40 +02:00
Harald Bamberger c24a9997a9 add function StundenplanEvents to new api factory 2025-04-29 12:13:29 +02:00
Harald Bamberger 3b7a862dbe align composer.lock with composer.json 2025-04-29 11:42:26 +02:00
Harald Bamberger 5856f1c2ae Merge branch 'master' into feature-25999/C4_cleanup 2025-04-29 11:27:27 +02:00
Andreas Österreicher edcd2aa1df Merge branch 'feature-61464/infocenter_ausbildungssemester' 2025-04-28 13:23:38 +02:00
ma0068 bf0cd8e8e3 actions new, update and delete aufnahmetermine 2025-04-25 16:15:27 +02:00
Johann Hoffmann a5ab2f1381 match abgabetool_detail student/mitarbeiter look&feel; WIP terminserie, zweitbetreuer logic etc 2025-04-25 14:30:12 +02:00
Johann Hoffmann 54e8a855f4 Merge branch 'master' into feature-25999/C4_cleanup
# Conflicts:
#	public/js/apps/Dashboard/Fhc.js
#	public/js/components/Cis/Cms/Content.js
#	public/js/components/Cis/Cms/News.js
#	public/js/components/Cis/Cms/StudiengangInformation/StudiengangInformation.js
#	public/js/components/Cis/Mylv/LvUebersicht.js
#	public/js/components/Cis/Stundenplan/Stundenplan.js
#	public/js/components/DashboardWidget/Ampel.js
#	public/js/components/DashboardWidget/News.js
#	public/js/components/DashboardWidget/Stundenplan.js
#	public/js/components/DashboardWidget/Url.js
#	system/phrasesupdate.php
2025-04-25 10:58:02 +02:00
Johann Hoffmann 97d83d3acf WIP abgabetool mitarbeiter 2025-04-25 09:59:41 +02:00
ma0068 2ab01132b1 show List Admission Dates 2025-04-24 16:30:50 +02:00
Harald Bamberger 9410388a7a tune order by to sort nearest active dv first 2025-04-24 15:40:58 +02:00
ma0068 d48a0b62fd Refactoring FhcApi_Factory 2025-04-24 12:59:47 +02:00
Harald Bamberger a196da03d2 change order by to ensure latest dv is sorted first 2025-04-24 10:52:47 +02:00
ma0068 ed6b9310ae Refactoring FhcApi_Factory 2025-04-24 08:23:24 +02:00
ma0068 a4777724dc Merge branch 'master' into feature-61230/FHC4_Studierendenverwaltung_LVTermine 2025-04-24 07:59:13 +02:00
ma0068 eaaf5de9c0 Refactoring FhcApi_Factory 2025-04-24 07:54:06 +02:00
Johann Hoffmann e28067259b WIP Abgabetool Mitarbeiter DetailComponent 2025-04-23 13:59:31 +02:00
ma0068 854223a2d7 Merge master into feature-60874/FHC4_Studierendenverwaltung_Dokumente 2025-04-23 13:37:31 +02:00
Johann Hoffmann 91910ef538 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup
# Conflicts:
#	application/libraries/dashboard/DashboardLib.php
#	public/js/components/Dashboard/Dashboard.js
#	public/js/components/Dashboard/Section.js
2025-04-23 12:49:16 +02:00
ma0068 8442a3d758 Refactoring FhcApi_Factory 2025-04-23 12:03:21 +02:00
ma0068 d780b472a6 Merge master into feature-60875/FHC4_Studierendenverwaltung_Anrechnungen 2025-04-23 11:11:35 +02:00
ma0068 3200a94d17 Refactoring FhcApi_Factory 2025-04-23 11:06:08 +02:00
ma0068 874c91e21c Merge branch 'master' into feature-61229/FHC4_Studierendenverwaltung_GemeinsameStudien 2025-04-23 09:41:50 +02:00
ma0068 65c398498f Refactoring FhcApi_Factory View Modal 2025-04-23 09:32:49 +02:00
ma0068 b9bd0e53d8 merge master into feature-55992/FHC4_Studierendenverwaltung_Messaging 2025-04-22 14:58:56 +02:00
ma0068 08b27edd64 Refactoring FhcApi_Factory 2025-04-22 14:29:45 +02:00
ma0068 2b9805aeb3 merge master into feature-55991/FHC4_Studierendenverwaltung_Gruppen 2025-04-22 13:58:27 +02:00
ma0068 2d87663841 basic structure for Tab Admission Dates 2025-04-22 13:35:31 +02:00
SimonGschnell 0c95dbad1f update(Dashboard Section description): adds phrases for the description of general/custom/other sections 2025-04-22 11:40:58 +02:00
Harald Bamberger 34eb2ab80c check permission system_change_outputformat in final exam on degree program oe_kurzbz 2025-04-22 11:11:46 +02:00
SimonGschnell 8c00158d04 refactor(Dashboard Database data structure): changes how the data for the dashboard is structured in the database, instead of having a global widgets property, each section has its own widgets property where additional properties like description can be stored 2025-04-22 09:52:07 +02:00
Alexei Karpenko da86575e65 archiv: added space in edit form 2025-04-18 13:25:00 +02:00
Harald Bamberger ced54d76d5 Merge branch 'feature-55980/gehaltsbestandteile_export_filtern_summieren' 2025-04-17 18:43:51 +02:00
Harald Bamberger 7b30869f7c make where clause more precise 2025-04-17 18:28:26 +02:00
Johann Hoffmann 47917e42c3 compare datetime timestamp for n-workdays ago calculation; more eager check on change of kontrollzeiten/termine if they match a termin; added missing phrase; fetch uploaddatum in same format as von/bis for entschuldigungen so date headerfilter can work as intended; zugangscode zeitlich abgelaufen show error message; 2025-04-17 12:07:54 +02:00
ma0048 d4012232ab ausbildungssemester hinzugefuegt 2025-04-17 11:01:33 +02:00
SimonGschnell c98d0a9c45 refactor(Dashboard Section description): updates the database structure for the dashboard information to add information about the description of a section 2025-04-17 08:52:21 +02:00
Harald Bamberger ac5e95e6b9 dbchanges: add columns lvexport and lvexport_sum to hr.tbl_gehalstyp, add gehaltstyp zulage_allin, set zulage_allin for gbs attached to vbs freitext allin 2025-04-17 08:20:30 +02:00
Alexei Karpenko 59f83c33b0 Merge branch 'master' into feature-55354/Studierendenverwaltung_Karteireiter_Archiv 2025-04-16 15:24:59 +02:00
Johann Hoffmann 3f607ec241 phrasen 2025-04-15 18:03:51 +02:00
Johann Hoffmann 5abc48f568 Merge branch 'master' into feature-56330/Digi-Anw-Feedback 2025-04-15 17:56:31 +02:00
Harald Bamberger b323f91999 Merge branch 'feature-60851/FhcApi_Factory_Refactoring' 2025-04-15 16:49:17 +02:00
Harald Bamberger 99587fd064 Merge branch 'master' into feature-60851/FhcApi_Factory_Refactoring 2025-04-15 16:20:34 +02:00
Harald Bamberger b67b19bd1a handle condition when endpoint has not been set 2025-04-15 15:38:27 +02:00
ma0068 26d7d17169 delete unneeded code, fix permission issue 2025-04-15 15:21:36 +02:00
Harald Bamberger b2a7ec6e67 add component names, Modal dynamically import new phrases plugin to created app 2025-04-15 14:52:24 +02:00
Harald Bamberger 9c5ebc902d fix typos, remove duplicate attribute 2025-04-15 14:51:10 +02:00
ma0068 af30a3408c add switch stundenplan, excel export, phrases 2025-04-15 14:22:39 +02:00
SimonGschnell 19f169aca2 feature(Dashboard Grid): adds a red border to the widget if the user tries to resize the widget over its max width/height or under its min width/height 2025-04-15 13:55:02 +02:00
SimonGschnell fc0a09180a update(Dashboard pinned animation): also triggers the pinned animation when the target area of a drag action contains a pinned widget 2025-04-15 11:16:20 +02:00
ma0048 1888c51a48 master gemerged
phrase bugfix
2025-04-15 11:09:59 +02:00
ma0048 ad93a0a84c Merge branch 'refs/heads/master' into feature-54827/internationalisierungsmassnahmen_optimierungen 2025-04-15 11:09:05 +02:00
Harald Bamberger 3669e0df40 check if entry in tbl_studentlehrverband exits and update or insert on result 2025-04-15 08:24:16 +02:00
Harald Bamberger 26bf1e33d4 close button tags 2025-04-14 17:32:13 +02:00
kindlm e8a233e503 Merge remote-tracking branch 'origin/master' 2025-04-14 17:13:15 +02:00
kindlm 1cb29ce8bb Task #61376 CIS Gesamtnote Berechtigung für OE 2025-04-14 17:13:03 +02:00
Johann Hoffmann 6b6ec311c7 Merge branch 'master' into feature-56330/Digi-Anw-Feedback 2025-04-14 15:23:31 +02:00
Johann Hoffmann 8218c915d5 anw phrasen 2025-04-14 15:14:49 +02:00
SimonGschnell 88c4a04aea fix(Dashboard widget resize position): when resizing an widget without saved position it would save it with x:0 and y:0 2025-04-14 14:57:14 +02:00
SimonGschnell a25ccd79b2 fix(Dashboard New Widget Not Draggable): adds the widgetid property to newly created widgets if it is not already present 2025-04-14 14:46:11 +02:00
SimonGschnell d4ae8b0f91 fix(Dashboard Grid Height): a bug was removed where the grid height was not correct when adding a new widget and the widget was not correctly displayed when adding a new widget 2025-04-14 14:33:49 +02:00
SimonGschnell 54bbfacf86 remove(Dashboard debugging):removes a debugging print statment 2025-04-14 11:42:03 +02:00
SimonGschnell 59ebd33ba6 feature(Dashboard resize):adds overlays to the elements when resizing widgets on the dashboard 2025-04-14 11:28:13 +02:00
Harald Bamberger 31c1b087e5 fix typo, readd showallformats lookup since isBerechtigtDocAndOdt is an array of oe_kurzbzs 2025-04-11 17:51:34 +02:00
Harald Bamberger 9f94c8fafd fix typo 2025-04-11 17:22:37 +02:00
Harald Bamberger a5b8e7dc8b fix typo 2025-04-11 17:14:54 +02:00
Harald Bamberger f7138b2cfc prevent loading old phrasen plugin when Modal component is used, only commented out since plugin is maybe needed in ModalApp in some cases 2025-04-11 17:00:39 +02:00
Harald Bamberger 7f7a423e65 prevent loading old and new FhcAlert plugin resulting in two FhcAlert Apps and showing e.g. two delete confirm Dialogs 2025-04-11 16:57:20 +02:00
Harald Bamberger 75338a89c7 fix edit modal for bankdata not opening 2025-04-11 16:55:35 +02:00
Harald Bamberger 3c3e2ae662 add name to studentenverwaltung app 2025-04-11 16:53:39 +02:00
Johann Hoffmann 4ee239dd62 entschuldigung upload without file; changed dropdowns; 2025-04-11 15:53:18 +02:00
SimonGschnell a0a2ac41bf refactor(Dashboard Grid): updates replace logic when moving widgets and fixes position detection between mousemove and mousedown 2025-04-11 12:00:38 +02:00
SimonGschnell 90ce3e0263 update(dashboard CSS): adds animation for pinned widgets and different cursor styles 2025-04-11 11:55:57 +02:00
SimonGschnell 204ae75f57 refactor(Dashboard Widget Names): adds the name property to the components of the dashboard widgets 2025-04-10 11:23:39 +02:00
ma0048 bcc712e900 addfaktor beim hinzuefuegen einer lv entfernt 2025-04-09 14:27:37 +02:00
Cristina 8788cf17e2 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-04-09 12:14:51 +02:00
ma0068 419c199e84 new Tab GemeinsameStudien 2025-04-09 11:06:50 +02:00
SimonGschnell 9b9b8b1532 feature(CIS Dashboard gridsystem): allows to pin widgets in the grid and changes how widgets are positioned in different viewports 2025-04-09 10:50:19 +02:00
Harald Bamberger f45e0105b0 fix typo 2025-04-07 15:54:32 +02:00
ma0068 d75e26f8ae add basis framework for lv dates 2025-04-07 14:46:36 +02:00
Harald Bamberger 242cee2b62 Merge branch 'feature-61228/FHC4_Studierendenverwaltung_SetNameAttributes' into feature-60851/FhcApi_Factory_Refactoring 2025-04-07 13:26:49 +02:00
Harald Bamberger 48a9ca0ff4 Merge branch 'master' into feature-61228/FHC4_Studierendenverwaltung_SetNameAttributes 2025-04-07 13:23:24 +02:00
Harald Bamberger cbd3c86e59 studiensemester dropdown order desc 2025-04-07 11:44:25 +02:00
cgfhtw 49cfeddfa2 LvTemplateUebersicht: use new API 2025-04-04 12:35:51 +02:00
cgfhtw 93689e3906 $fhcApi on plugins: error => warning 2025-04-04 12:35:33 +02:00
ma0068 958577902d set name attribute to components 2025-04-04 11:07:54 +02:00
ma0068 01b3d4580e set name attribute to components 2025-04-04 11:03:00 +02:00
ma0068 b2fef71b47 added name attribute to components 2025-04-04 09:53:54 +02:00
ma0068 4d1fc5e48c added name attribute to components 2025-04-04 09:41:11 +02:00
ma0068 92a05c4711 reset config use_vuejs_dev_version 2025-04-04 09:35:37 +02:00
ma0068 bef3e88e92 name attributes for components added 2025-04-04 09:33:44 +02:00
ma0048 f826c20949 lv_id beim zeugnis.rdf.php hinzugefuegt
auf die ersten 2 lvs im microdegree eingeschränkt
2025-04-04 08:42:20 +02:00
ma0068 1991418931 New tab Dokumente 2025-04-03 16:54:56 +02:00
Harald Bamberger 8c0325b693 fix template compilation errors 2025-04-03 16:35:29 +02:00
Harald Bamberger 9572bdf3eb Merge branch 'master' into feature-60851/FhcApi_Factory_Refactoring 2025-04-03 15:58:45 +02:00
Harald Bamberger 97782b7f1d Merge branch 'feature-60863/Betragspalte_Sachaufwand' 2025-04-03 11:12:31 +02:00
Harald Bamberger 315b763380 Merge branch 'master' into feature-60863/Betragspalte_Sachaufwand 2025-04-03 11:10:52 +02:00
Andreas Österreicher b41baad89d Merge branch 'Monika70-lvgesamtnoteverwalten' 2025-04-03 07:43:02 +02:00
Andreas Österreicher cc51e7f04a Merge branch 'lvgesamtnoteverwalten' of github.com:Monika70/FHC-Core into Monika70-lvgesamtnoteverwalten 2025-04-03 07:38:03 +02:00
Andreas Österreicher 2a2e2ea193 Warteliste Message angepasst damit die Tagesgrenze korrekt vom
Wartenden-Status ermittelt wird
2025-04-02 16:55:31 +02:00
Harald Bamberger a54f7531bf add column betrag to table hr.tbl_sachaufwand 2025-04-02 16:07:09 +02:00
SimonGschnell 97e34948e5 refactor(WidgetIcon for Dashboard dragging): puts the hidden dashboard icons for the dragging image in the section component so that each section has its relative clientX and clientY positions 2025-04-02 11:23:25 +02:00
SimonGschnell 33f800fa28 fix(Dashboard Mobile Touch Events): fixes the behaviour of the touch event for the dashboard grid 2025-04-01 13:06:23 +02:00
Andreas Österreicher 7345dd258d Merge branch 'feature-56033/Beurteilungsformulare_neue_Kategorien_ab_SS2025' 2025-04-01 11:17:51 +02:00
Andreas Österreicher 8a7290359a Merge branch 'master' into feature-56033/Beurteilungsformulare_neue_Kategorien_ab_SS2025 2025-04-01 10:52:04 +02:00
SimonGschnell 702a84a25d update(Dashboard Grid Item):makes a widget only draggable if the dragAction is defined 2025-04-01 09:28:29 +02:00
Harald Bamberger e809e48262 fix order of parameters 2025-03-31 15:40:18 +02:00
SimonGschnell 232da256ac fix(Dashboard Drag Placeholder): doesn't allow placeholder items to be dragged anymore and keeps the height and width of a widget when resizing the grid of the dashboard 2025-03-31 14:56:50 +02:00
SimonGschnell 51f4e1e57d fix(Chrome overflow scroll display): changes overflow scroll to auto to change the visual in the chrome browser 2025-03-31 09:47:27 +02:00
Alexei Karpenko b4b2d8da49 added UHSTAT issue resolvers, bugfix getuhstatdata: check for empty array 2025-03-30 23:38:35 +02:00
kindlm 86158e6f28 Merge remote-tracking branch 'origin/master' 2025-03-30 00:40:14 +01:00
kindlm 7c61ee55c2 Fragensumme in Übersicht eingefügt 2025-03-30 00:40:08 +01:00
Andreas Österreicher 5197037126 Merge branch 'feature-60880/pep_finetuning_spring_231' 2025-03-28 08:59:00 +01:00
Johann Hoffmann ba806c13fb assistenz edit entschuldigung modal for editing von/bis date (on open excuse notes) & textarea for notiz - which is still limited to 255 characters; added student semester column to assistenz table; removed column width constraints & layout changed to fitData, persistence option is TRUE now; WIP von/bis/uplaoddate headerfilter; automatically send email to students on entschuldigungn status changed; added minimum time range for Kontrolle to be at least the length of 1 teaching unit(per config) - currently 45minutes; start new kontrolle modal more clearly shows when time & date values have been read from stundenplan; increased qr degeneration timer from 200 to 5000ms to avoid "missed" checkins due to network time; lektor can retrieve all entschuldigungen ranges & statuses of students when hovering their row; lektor can show anw qr window seperately now; into externalzuordnung admin/person_id fix in deleteEntschuldigung; moved fetch semesterinfo into global setup; fixed some vue template warnings; 2025-03-27 17:15:37 +01:00
Harald Bamberger 95856c9e4d bootstrap5 version 5.3.3 2025-03-27 15:14:56 +01:00
kindlm 1e2a4d202f Fix Typo PrueferIn 2025-03-27 13:57:44 +01:00
Cristina 0113c9d97a Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-03-27 13:42:48 +01:00
kindlm b32f60874c Merge remote-tracking branch 'origin/master' 2025-03-27 11:55:58 +01:00
kindlm 78c23699d5 TinyMCE-Editor bei Ampeldetails 2025-03-27 11:55:41 +01:00
Andreas Österreicher 8178368113 Merge branch 'feature-40953/LV-Template_Uebersichtsseite' 2025-03-27 09:34:06 +01:00
Andreas Österreicher 392c15da77 Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite 2025-03-27 09:32:59 +01:00
SimonGschnell 727b951bbc update(Dashboard Grid): does not show the overlay when resizing the widget and adds different grid sizes for different viewports 2025-03-26 14:59:28 +01:00
SimonGschnell 08cb4a7970 refactor(color update): switches fhc-secondary with fhc-tertiary 2025-03-26 13:17:08 +01:00
SimonGschnell b52993f7cc refactor(Grid Widgets drag): shows a placeholder item in the space where the new widget position would be when dragging a widget on the dashboard 2025-03-26 13:02:48 +01:00
cgfhtw c780b29732 load new API in old API 2025-03-26 09:20:58 +01:00
kindlm f55c309692 Fehlende Tabellen beim Löschen von Personen ergänzt 2025-03-25 16:33:13 +01:00
kindlm c569af6d0f Löschen bei Personensuche löscht auch Testtooleinträge 2025-03-25 16:07:42 +01:00
kindlm ce54cf3c9c Bugfixes Studentenmeldung 2025-03-25 16:07:09 +01:00
kindlm fae299847e Messaging-Fenster scrollt automatisch nach oben 2025-03-25 15:56:55 +01:00
kindlm 742ae40d98 Link Zugangscode öffnet nicht sondern kopiert in zwischenablage 2025-03-25 15:56:30 +01:00
SimonGschnell 1cdf89e405 fix(Dashboard drag event): fixes bug where widget wouldn't drag to new position 2025-03-25 13:18:00 +01:00
SimonGschnell ab36d567b8 refactor(Url Widget): fixes add link button inside the widget 2025-03-25 12:47:58 +01:00
Andreas Österreicher 4c38d88840 Merge branch 'feature-61109/infocenter_anzahlung_auf_kaution_aendern' 2025-03-24 16:45:49 +01:00
SimonGschnell 75ad88eb24 update(Plugin Theme):changes the way the primevue theme is replaced if the theme is not dark or light 2025-03-24 15:05:07 +01:00
ma0048 7126ab4561 - "Kaution" - column: buchungstyp von anzahlung auf kaution geandert 2025-03-24 14:33:34 +01:00
SimonGschnell 5d39d5ec46 feature(FHC Theme plugin): adds a plugin that provides functionality and information of the current theme 2025-03-24 14:29:21 +01:00
ma0048 45b7a56c3a - zeugnis vorlage fuer micro degree 2025-03-24 14:00:14 +01:00
cgfhtw 9f06fbcf93 refactor fhcApi 2025-03-24 13:38:49 +01:00
SimonGschnell 80c326360f update(FHC Color Themes): makes the css variables and color modes configurable through the config for different fh's 2025-03-24 11:59:03 +01:00
Andreas Österreicher a6ee6a8c0f ReihungstestJob angepasst damit Drittstaatenkaution berücksichtigt wird.
Fehler behoben beim setzen des Abgewiesenen Status das nicht in allen
Fällen funktioniert hat
2025-03-24 11:45:58 +01:00
Cristina 92db886a9f Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-03-24 11:18:53 +01:00
Andreas Österreicher 45f3acf922 Merge branch 'feature-37620/reihungslisten' 2025-03-24 10:24:01 +01:00
Andreas Österreicher 08e38078a0 Removed duplicate Confirm 2025-03-24 09:57:46 +01:00
SimonGschnell ff311ddaa8 fix(News widget autoscroll): removes the ride attribute from the bootstrap carousel to remove the autoscrolling of the news widget 2025-03-24 09:34:52 +01:00
Andreas Österreicher 410231a427 Merge branch 'master' into feature-37620/reihungslisten 2025-03-24 09:18:26 +01:00
SimonGschnell 0735c61361 update(UrlWidget addUrl Action):adds the transition animation to the action button of the url widget 2025-03-24 08:53:15 +01:00
SimonGschnell 7936e08d3d refactor(Dasboard Item): adds container for actions events from Dashboard widgets 2025-03-21 12:49:29 +01:00
SimonGschnell 3f605e7051 feature(Cis Color Themes): makes it possible to change color theme of the application 2025-03-21 11:42:09 +01:00
Johann Hoffmann a3e22da633 calcEntschuldigungen minDate as workdays in config; updatevon/um anwCheckIn; Orgform dual in sancho mail; zusatz (d.d.i)/(d.d.o) & (o) auch wenn bis datum leer ist aber von bereits eingetragen 2025-03-20 17:21:42 +01:00
Alexei Karpenko fb2f8d5c53 added function for getting UHSTAT1 person data (centralizing...) 2025-03-20 14:41:28 +01:00
Cristina b18b3b62a7 Merge remote-tracking branch 'origin/feature-40953/LV-Template_Uebersichtsseite' into feature-40953/LV-Template_Uebersichtsseite
# Conflicts:
#	system/phrasesupdate.php
2025-03-20 13:29:49 +01:00
Cristina 2a4f1af69f Added phrase lizenzkategorie to Softwarebereitstellung app 2025-03-20 11:41:47 +01:00
Cristina b8417869b5 Added phrase lizenzkategorie to Softwarebereitstellung app 2025-03-20 11:18:26 +01:00
ma0068 b75c9cc524 portation of tab Anrechnungen
- switch version edit / non edit in config
2025-03-20 11:16:05 +01:00
Johann Hoffmann 2759bb0309 cis4 abgabetool student uploads/signature check/emails working; TODO: - testing with diff users, styling & mobile layout; 2025-03-19 15:57:08 +01:00
ma0048 0a2bd1bdde - stundengrenze bei dummy nicht beruecksichtigen 2025-03-18 14:02:23 +01:00
Cristina 19fdefc398 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-03-18 10:42:15 +01:00
Harald Bamberger f6352211f2 Merge branch 'feature-55614/Uebersichten_LV_TPL_QK_OP' 2025-03-17 12:56:59 +01:00
SimonGschnell 0dd1e4a628 refactor(RoomInformation): updates the roomInformation endpoint to use the Stundenplan library functions 2025-03-13 10:29:23 +01:00
ma0068 3b8b8d7882 remove testdata in getFunction 2025-03-13 09:34:06 +01:00
ma0068 7b4f0f9dff Adaptions
- bugfix personFields
- validation for sendmessage for openmode inSamePage, newTab, window
- restyling div for enable scrolling in openmode InSamePage
2025-03-13 09:05:53 +01:00
Szabo Mónika 2901847788 Update lvgesamtnoteverwalten.php
Der Lehrveranstaltungstyp wurde in der E-Mail über die freigegebenen Noten hinzugefügt.
2025-03-12 15:11:00 +01:00
ma0068 a0ce635c7e Refactor and Cleanup
- adapt tabulator and queries for remote pagination
- use formatterParams for messageStati to enable phrase logic
- adapt logic for mitarbeiter_uid
- refactor logic to use new Page, new Tab and newDiv with one child component
- add phrases
2025-03-12 15:04:37 +01:00
Johann Hoffmann 669752dd90 WIP cis4 abgabetool student 2025-03-12 13:41:01 +01:00
Andreas Österreicher dc51e9bd85 Merge branch 'bug-56084/PHP_Notice_bei_Lehrauftrag_Erteilen_Bestellen' 2025-03-12 12:08:49 +01:00
Harald Bamberger 129637cf4f add phrases for lvdev overviews 2025-03-12 12:05:34 +01:00
Harald Bamberger ff65852643 neues recht basis/verwaltet_oe 2025-03-12 08:21:03 +01:00
ma0068 ea2be8026b filter hidden from kontakttyp, show typ.beschreibung in dropdown 2025-03-12 08:06:23 +01:00
Cristina ed2f895d8b Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite 2025-03-11 17:35:34 +01:00
Cristina f219a19dec Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-03-11 16:31:48 +01:00
Alexei Karpenko 639c7d7e41 Studentenverwaltung Archiv: added phrases for table headings 2025-03-10 22:50:04 +01:00
Alexei Karpenko f8eb265eb0 Studentenverwaltung Archiv: non-signable documents can be archived, set correct default Vorlage (Zeugnis) 2025-03-10 22:35:14 +01:00
Harald Bamberger 1f5925e860 searchbar restults mobile improve css selector, alter student result view 2025-03-10 17:11:03 +01:00
Harald Bamberger b9823a0278 set overscrollbehavior none for all dashboard-items 2025-03-10 14:39:31 +01:00
Harald Bamberger 2b4ccab2f1 studiengang info widget decrease size of headings 2025-03-10 14:30:28 +01:00
Harald Bamberger fad5f8b9d0 increase height of iframe especially for mobile view 2025-03-10 11:28:29 +01:00
ma0068 1989e65d72 Tree structure for messages, preview in NewDiv, Note to close window, check recipient_id, save relationmessage_id 2025-03-10 07:51:53 +01:00
Johann Hoffmann d349a64ca8 fix news widget carousel (re)initialization after resize 2025-03-06 16:19:49 +01:00
Andreas Österreicher 21e3169d8d Merge branch 'bug/pep_suche_lehre' 2025-03-06 11:58:56 +01:00
ma0048 740a473c8d tagheaderfilter fix 2025-03-06 11:55:25 +01:00
Cristina 83fe68c04e Removed 2 methods getNonQuellkursLvs and getNonQuellkursLvsAutocompleteSuggestions from Lehrveranstaltung_model.php 2025-03-06 10:39:00 +01:00
Andreas Österreicher c84ffdf893 Merge branch 'pep_deploy_2025_03_06' 2025-03-06 10:36:26 +01:00
Cristina eedbab21a2 Added phrases for Softwarebereitstellung 2025-03-06 09:58:15 +01:00
Cristina 3a83d468ef Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite 2025-03-06 09:50:55 +01:00
Cristina 85ef49bb62 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-03-06 09:48:58 +01:00
Cristina aab0dd7fc7 Added / Adapted Model queries and api Controller regarding for Lehrveranstaltung- and Studienjahr Model 2025-03-06 09:40:40 +01:00
Harald Bamberger bd7669ff5b Merge branch 'merge_FHC4_C4' 2025-03-05 17:37:16 +01:00
Harald Bamberger 00b766cb69 tweak mobility form behavior 2025-03-05 17:35:27 +01:00
ma0048 663ff947b0 prepare for deploy 2025-03-05 15:19:24 +01:00
ma0048 11ba9c9911 Merge branch 'refs/heads/feature-55289/pep_fine_tuning' into pep_deploy_2025_03_06
# Conflicts:
#	system/dbupdate_3.4.php
2025-03-05 15:15:57 +01:00
ma0048 f942836453 Merge remote-tracking branch 'origin/feature-54945/filtercomponent_custom_headerfilter_datum' into pep_deploy_2025_03_06
# Conflicts:
#	public/js/tabulator/filters/defaultHeaderFilter.js
2025-03-05 15:14:49 +01:00
Alexei Karpenko 2cbbcc9039 changed Projektarbeitsbeurteilung phrase 2025-03-05 14:52:55 +01:00
Johann Hoffmann 14f64401e5 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2025-03-05 14:24:24 +01:00
Johann Hoffmann a4d2a2cace fix news widget carousel (re)initialization after resize 2025-03-05 14:23:35 +01:00
SimonGschnell 97ee1f8144 fix(News Widget animation): fixes the animation bug when changing the width of the News widget from 1 to >1 2025-03-05 13:42:37 +01:00
SimonGschnell ba2014b1a3 fix(News Widget animation): fixes the animation bug when changing the width of the News widget from 1 to >1 2025-03-05 11:21:49 +01:00
SimonGschnell c22118a26c fix(VueRouter News Ansicht):News ansicht konnte nicht geladen werden weil viewData im Cms controller nicht uebergeben wurde aber im CisRouterView verwendet wird 2025-03-05 10:49:03 +01:00
SimonGschnell c677c48b00 fix(StudiengangsInformationen API data): fixes little error when checking if the uid is a mitarbeiter or not 2025-03-05 10:47:45 +01:00
SimonGschnell 44777e2f1b fix(VueRouter News Ansicht):News ansicht konnte nicht geladen werden weil viewData im Cms controller nicht uebergeben wurde aber im CisRouterView verwendet wird 2025-03-05 09:20:35 +01:00
SimonGschnell 415e759586 fix(StudiengangsInformationen API data): fixes little error when checking if the uid is a mitarbeiter or not 2025-03-05 08:54:26 +01:00
ma0068 188e6db759 bugfix: update sqls with LEFT condiiton 2025-03-05 08:49:42 +01:00
ma0068 588834d73f add click event to enable new choice for lehreinheit dropdown 2025-03-04 15:11:22 +01:00
Harald Bamberger fe4c14f75f Merge branch 'merge_FHC4_C4' 2025-03-04 14:40:13 +01:00
ma0068 45fd48a50e add watcher for resetting lehreinheit 2025-03-04 14:33:20 +01:00
ma0068 d39dfbc41b use loadItems with second condition 2025-03-04 14:11:40 +01:00
ma0068 e69a9eeadb set 1st condition to not disabled 2025-03-04 14:02:50 +01:00
ma0068 eb958d19c8 set 3rd condition to not disabled 2025-03-04 14:00:13 +01:00
ma0068 358480600e add condition existing lehreinheit and not existing lv_id 2025-03-04 13:58:02 +01:00
ma0068 d5eae17ba5 extend queries for lehrveranstaltung_id to see dropdown 2025-03-04 13:49:39 +01:00
SimonGschnell b1b0d5edd0 remove(Calendar Week Page Style): removes not needed style check in component 2025-03-04 12:05:24 +01:00
Harald Bamberger 93ff868501 ensure student_uids is an array even if only one uid is passed 2025-03-04 11:23:46 +01:00
cgfhtw 825ccfcc37 Calendar: Get rid of Warnings 2025-03-04 11:15:51 +01:00
ma0068 701c57966f tab contact - field plz: numberformat validation only for Austria 2025-03-04 10:53:03 +01:00
ma0068 c2691f867d form Abschlusspruefung as modal 2025-03-04 09:57:25 +01:00
ma0068 8320de66bc redesign dropdown mobility-support with overriding filtercomponent 2025-03-04 08:26:07 +01:00
ma0068 815307e392 Reply functionality and Pagination 2025-03-04 07:32:14 +01:00
Johann Hoffmann 2b16d8940f fhc header skiplink; cis4 skiplink css; 2025-03-03 17:57:42 +01:00
Harald Bamberger 091aa1917b set maxwidth for frozen actions column 2025-03-03 17:17:25 +01:00
ma0068 f471321b98 Merge branch 'merge_FHC4_C4' of github.com:FH-Complete/FHC-Core into merge_FHC4_C4 2025-03-03 16:40:15 +01:00
ma0068 1944152d13 redesign dropdown mobility-properties with overriding filtercomopnent actions 2025-03-03 16:40:05 +01:00
Johann Hoffmann e4317f7a94 mobile breakpoints & form validation; 2025-03-03 15:57:55 +01:00
Harald Bamberger 9aa8c33e83 fix use of confirm dialog with rewritten factory calls 2025-03-03 15:26:54 +01:00
ma0068 20fc528107 Use Modal for Mobility Tab 2025-03-03 15:10:01 +01:00
SimonGschnell b8239b0842 update(LvInfo Phrasen): adds some phrasen for the LvInfo View for the moodle events 2025-03-03 14:38:23 +01:00
SimonGschnell 20f22d5a7b fix(Calendar selectedEvent and Scrolling): sorts the events before selecting the first as the selectedEvent and adds some scrolling checks 2025-03-03 14:15:50 +01:00
Johann Hoffmann 225d6b0a83 raumsuche student config for allowed roomtypes 2025-03-03 13:51:43 +01:00
Paolo c028a769cc TableWidget bug: the bootstrapVersion was provided with the tableUniqueId, not needed 2025-03-03 13:44:40 +01:00
ma0068 50ec93f5c1 extend function getLesFromLvIds for studiensemesterkurzb and aggregation lehreinheit_id 2025-03-03 13:43:19 +01:00
Alexei Karpenko e61b6b447c Abgabetool: removed hyperlink from benoten button quickinfo 2025-03-03 13:37:33 +01:00
SimonGschnell a408c85fd4 fix(Calendar Day SelectedEvent): fixes the watcher on the property active to additionally look at the events property and set the selectedEvent accordingly to the situation 2025-03-03 13:29:31 +01:00
SimonGschnell 98fa76ca1d fix(Calendar Month setSelectedEvent): selects the clicked lehrveranstaltung as selectedEvent in the click handler of the Month/Page View 2025-03-03 13:04:52 +01:00
Alexei Karpenko 037811c24c Paarbeitsabgabe: replaced num_rows_sem with new paiscurrent variable 2025-03-03 12:39:07 +01:00
ma0068 da9afa5c67 Merge branch 'merge_FHC4_C4' of github.com:FH-Complete/FHC-Core into merge_FHC4_C4 2025-03-03 11:54:13 +01:00
Harald Bamberger 409a70bdf9 add form as first param 2025-03-03 11:47:30 +01:00
ma0068 05a6109c27 Merge branch 'merge_FHC4_C4' of github.com:FH-Complete/FHC-Core into merge_FHC4_C4 2025-03-03 11:46:12 +01:00
ma0068 b50a4a16d1 change form parameter mobility and add param studiensemester_kurzbz to function get LVsandLesByStudent 2025-03-03 11:45:31 +01:00
SimonGschnell b8c45cf244 update(Moodle Events):adds additional fields for Moodle Events and disables the automatic scrolling for moodleEvents 2025-03-03 11:07:54 +01:00
Harald Bamberger 1fbc552d30 fix factory losing enpoints when person search is called before 2025-03-03 10:45:02 +01:00
Johann Hoffmann bc7dba1c14 legacy raumsuche.php -> cis4 vue component 2025-02-28 16:41:18 +01:00
SimonGschnell 4a01198e10 refactor(Stundenplan Endpoint):puts methods used to fetch Stundenplan and Reservierungs Events in its own library and dynamically merges the moodle events if plugin is present 2025-02-28 14:52:02 +01:00
Harald Bamberger 28f11d7550 Merge branch 'bhdev_tabulator6' into merge_FHC4_C4 2025-02-28 14:35:17 +01:00
Alexei Karpenko a63c321f97 added Projektarbeitsbeurteilung phrases 2025-02-28 12:09:26 +01:00
Alexei Karpenko c07c4ef4c9 Merge branch 'master' into feature-56033/Beurteilungsformulare_neue_Kategorien_ab_SS2025 2025-02-27 15:46:09 +01:00
SimonGschnell 45c929cb90 refactor(LvInfo): refactors template layout of LvInfo for lehrveranstaltungen and moodle events 2025-02-27 14:47:45 +01:00
Alexei Karpenko b348119488 added comment to Documents api controller 2025-02-27 14:45:57 +01:00
ma0068 f9f185bfef Views modal, new tab, new page, app and controller for newMessage to open in tab or window 2025-02-27 14:06:25 +01:00
SimonGschnell e2b1dad776 fix(Plugin Moodle Event.php) adds the moodle calendar events integration through the Events instead of having a fixed dependency 2025-02-27 12:06:43 +01:00
Johann Hoffmann 9b68bfd336 focus day highlight css animation 2025-02-27 11:49:57 +01:00
Harald Bamberger 80b67ad416 add tabulator6 2025-02-27 11:35:21 +01:00
Johann Hoffmann 9acc2a8a9d revert router.replace strategy in month page; added weeks component without header into modal when week page header is clicked to enable week selection but without leaving the week carousel page 2025-02-27 11:16:35 +01:00
ma0048 55312848a3 Merge remote-tracking branch 'origin/feature-55289/pep_fine_tuning' into feature-55289/pep_fine_tuning 2025-02-27 09:08:29 +01:00
ma0048 737c9937c9 - namen bei tags
- phrasen hinzugefuegt
2025-02-27 09:07:23 +01:00
ma0048 30c4245861 - international skills -> diplomasupp
- notenuebernahme mail
- student uebersicht ueberarbeitet
- phrases angepasst
2025-02-27 08:35:05 +01:00
Alexei Karpenko 9bd5f6dcb6 Studierendenverwaltung Archiv: enabled download of documents 2025-02-26 19:38:09 +01:00
Alexei Karpenko 00b77d726c Studverwaltung Archiv: update of archived documents is possible, enabled archiving via multi-select 2025-02-26 18:11:07 +01:00
Johann Hoffmann 8e697515bc added vue datepicker11 option; month page header click show months in modal instead of switching page & mode; 2025-02-26 17:04:59 +01:00
Andreas Österreicher 1cecdcb8ef Berechtigung fuer begrenzte Reports umbenannt 2025-02-26 16:24:46 +01:00
Harald Bamberger fe98eb2784 add missing .js file extension to import statement 2025-02-26 15:34:49 +01:00
Johann Hoffmann c833b40527 merge fix 2025-02-26 15:11:05 +01:00
SimonGschnell 973b011f36 merge C4 cleanup 2025-02-26 14:42:52 +01:00
SimonGschnell e635d5e0e1 update(Dashboard Calendar Moodle): adds the moodle Calendar Events in the Dashboard Stundenplan both for the minimized view and the month view 2025-02-26 13:43:28 +01:00
SimonGschnell fe1971a1d3 update(Calendar Moodle): adds background color to full day events, adds the link to the moodle activity, sorts the events based on type 2025-02-26 13:05:17 +01:00
Johann Hoffmann ecd5e95f2d access computed grade phrase defensive; avoid pushing redundant mode changes; replace current state with new params when a different day is selected in the current month -> beforeEnter guard creates redundant navigation history entry which is currently being blocked but produces the possibility to infinitely "rego forward"; 2025-02-26 11:42:32 +01:00
SimonGschnell bad19ccde7 feature(Calendar Scroll Behavior): only scrolls an entire hour at the time when scrolling with the mouse wheel 2025-02-26 09:40:42 +01:00
Johann Hoffmann 881b7fb789 fix loadEvents race condition; normalize route pushes; WIP getting route.replace to work; 2025-02-24 17:53:56 +01:00
ma0048 ab20943493 - filter aus dem defaultfilter entfernt
- tagfilter hinzugefuegt
- clear filter hinzugefuegt
- persistence default auf false gesetzt
2025-02-24 08:58:35 +01:00
Harald Bamberger ba594a320b Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-24 08:50:04 +01:00
Harald Bamberger 9876976c70 Merge branch 'master' into merge_FHC4_C4 2025-02-24 08:46:48 +01:00
ma0068 3c34b17d2d add Preview-logic, update function sendMessage 2025-02-21 14:58:59 +01:00
SimonGschnell ebbec03de4 feature(Calendar Moodle): adds moodle svg and adopts month page view for moodle events 2025-02-21 14:21:38 +01:00
Johann Hoffmann 7a0a2d756d load lv entry as meta info when querying stundenplan by lva & show titel in ger/eng; also show currently active Studiensemester; roomInfo constant defined aswell; 2025-02-21 14:16:11 +01:00
Alexei Karpenko b989eae461 added archive tab to Studierendenverwaltung, possibility to archive documents 2025-02-20 20:07:07 +01:00
Johann Hoffmann 844c31885e defined row min height & event max height props; month event click opens lv modal; fixed off by one date state; 2025-02-20 16:25:57 +01:00
Johann Hoffmann 3d467524e4 change Stundenplan/Rauminfo currentDay on prev/next event by certain offset and update url/browser history 2025-02-20 12:59:28 +01:00
SimonGschnell 400ba2d7f9 fix(Calendar All Day Events): positions the all day Events in its own container above the events 2025-02-20 12:10:48 +01:00
Johann Hoffmann 1d9ea5d091 router click intercepter does not resolve internally when only matched route was the Fallback matchAll route; cleanup routes.php & Stundenplan controller from viewData and verbose reroutes; overflow setting on years page; 2025-02-20 11:22:30 +01:00
SimonGschnell 40f64cc979 feature(Calendar Moodle): adds and modifies the week and day view for moodle events 2025-02-19 14:52:51 +01:00
SimonGschnell 5cb09c8e7b fix(LvMenu): fixes the highlighting styles for the lvMenu, instead of using fhc-entry it uses its own class 2025-02-19 14:50:19 +01:00
Harald Bamberger 11e8ffb22c Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-19 14:25:04 +01:00
Harald Bamberger 157ffd00f2 Merge branch 'master' into merge_FHC4_C4 2025-02-19 14:24:14 +01:00
ma0068 f89c194d32 add Vorlagendropdown Component and Listboxes for Messaging Variables 2025-02-19 11:36:00 +01:00
Johann Hoffmann 714d74d9aa url widget template fix 2025-02-19 11:25:29 +01:00
Johann Hoffmann b817458222 lv menu events send phrasenkey to enable responsive localization in myLv 2025-02-18 17:36:48 +01:00
Johann Hoffmann cb42ba110e adapt new calendar url format for rauminfo page; readded vue router dashboard fallback since there are possible url combinations that can not be resolved properly; 2025-02-18 16:31:05 +01:00
Johann Hoffmann 8e76d93a5a consistent naming of calendar modes in english; fixed routerguard to work with router.push on mode or date changes inside stpl component; 2025-02-18 14:48:14 +01:00
SimonGschnell e086da2274 feature(Calendar Moodle Events): displays moodle events as allDayEvents in the Calendar 2025-02-18 14:23:56 +01:00
Johann Hoffmann e2e537b09c fix calendar mode watch/emit handling; WIP roomInfo routes 2025-02-18 10:55:46 +01:00
Johann Hoffmann d45a41b949 defined new CI routes to differentiate between 5 cases CI doesnt handle anymore but vue router does; define Stundenplan/:lv_id? route for old links to redirect to new route Stundenplan/:mode/:focus_date/lv_id; new route with props route param handling to put them into viewData to always check for the same object; define day as allowed init mode; WIP same thing for raum calendar page; 2025-02-18 10:18:39 +01:00
Alexei Karpenko 9fb2ea4ae3 Projektarbeitsbeurteilung: added authorization (Berechtigungen) check to document export 2025-02-17 19:03:53 +01:00
SimonGschnell c960b4832d test 2025-02-17 14:40:24 +01:00
Alexei Karpenko 57eec9b940 adapted document export to new Projektarbeit version (percent assessment) 2025-02-14 23:47:19 +01:00
Alexei Karpenko 7083955702 changed Proektarbeitsbeurteilung phrases 2025-02-14 16:44:33 +01:00
Harald Bamberger 48ef35c0e9 Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-14 14:58:46 +01:00
Harald Bamberger f6f06c4d5e use attribute binding since value should be boolean 2025-02-14 14:58:12 +01:00
Harald Bamberger b01400d21c remove unused data declaration 2025-02-14 14:55:57 +01:00
Harald Bamberger 92ba4aea9a return year as number not as string 2025-02-14 14:53:19 +01:00
Johann Hoffmann 7fed1d231c p.t( -> $p.t( in stundenplan & mylv components, added missing phrasen; WIP adding phrasen keys for noten, maybe for lva titles 2025-02-14 14:49:28 +01:00
Johann Hoffmann 3a1055d87e computed phrasen in column titles student profil for zutrittsgruppen/betriebsmittel; samilar to mitarbeiter profil 2025-02-14 13:54:02 +01:00
Johann Hoffmann bb69e07340 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2025-02-14 13:35:48 +01:00
Johann Hoffmann ff8d1c78fd funktionen/betriebsmittel table in profil & viewprofil got computed phrasen title; provide computed language reference in fhc app from phrasen plugin to watch for language changes to reevaluate computed phrasen in columns with; added some phrasen; 2025-02-14 13:34:52 +01:00
Harald Bamberger 350980c5df Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-14 13:33:52 +01:00
Harald Bamberger cff606815e fix TransitionGroup children have to be keyed when adding a new widget to dashboard 2025-02-14 13:33:29 +01:00
Harald Bamberger ee0e5fe40e Merge branch 'master' into merge_FHC4_C4 2025-02-14 13:25:14 +01:00
Johann Hoffmann ff60de5772 anrechnungen reload page on languageChange in php template site with cis4Reload attribute set; 2025-02-14 11:26:14 +01:00
Johann Hoffmann 40db480489 stundenplan widget header format as per fhc locale 2025-02-13 17:46:28 +01:00
Johann Hoffmann 43e3fdcc46 remove log 2025-02-13 17:28:34 +01:00
Johann Hoffmann 4de9441699 fix accessing fhc language locale .locale -> .LC_TIME 2025-02-13 17:25:24 +01:00
Johann Hoffmann 47293a81d3 avoid persisting invisible column definitions on funktionen table 2025-02-13 13:40:24 +01:00
Johann Hoffmann 139a2f900f watch for changing betriebsmittel & funktionen data; wait for loaded viewData before rendering greeting; 2025-02-13 12:41:24 +01:00
Johann Hoffmann 2d5309f97d fix invisible funktionen/betriebsmittel tabulator columns; fix phrasen roleInfo studentViewProfil; 2025-02-13 12:06:41 +01:00
Alexei Karpenko de895362be changed Projektarbeitsbeurteilung phrases even more 2025-02-12 19:28:27 +01:00
Alexei Karpenko 92f3f0d89c changed Projektarbeitsbeurteilung phrases 2025-02-12 19:15:43 +01:00
Harald Bamberger 2f47cc7966 Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-12 17:58:37 +01:00
Harald Bamberger 9bcd566bee fix TransitionGroup children have to be keyed and duplicate attribute v-bind 2025-02-12 17:57:53 +01:00
Harald Bamberger a6e0f10f32 use correct path to searchbar.css 2025-02-12 17:56:10 +01:00
Johann Hoffmann 480bef3b0d student profile role info verband/gruppe/semester links to old cis list; reworked role info data to also work in english lol; 2025-02-12 17:24:37 +01:00
Johann Hoffmann e6edd42737 profil remove console.log, added missing phrase 2025-02-12 14:34:52 +01:00
Johann Hoffmann 60e12e1ab7 dont load any studiengang related infos for mitarbeiter 2025-02-12 14:04:23 +01:00
Harald Bamberger 09aae4c82b Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-12 13:47:24 +01:00
Harald Bamberger d8438b4f4c Merge branch 'master' into merge_FHC4_C4 2025-02-12 13:44:39 +01:00
Johann Hoffmann a9e3a85d99 format gebdatum for profil in sql; fix show telefonnummer in profil; 2025-02-12 13:44:32 +01:00
Johann Hoffmann 8525c82305 set menuEntry href based on link form -> no href on menus without full url, hash links on menus dont trigger routing anymore; news widget check if carousel exists on mounted nextTick; 2025-02-12 11:56:12 +01:00
SimonGschnell bcb88c0cb7 refactor(Calendar Month View): instead of using border when highlighting the current day, uses box-shadow so that the content inside the highlighted day does not shift because of the width of the additional border 2025-02-12 11:11:23 +01:00
ma0068 ca187efce4 bugfix: deleted outputJson returns 2025-02-11 15:58:31 +01:00
Johann Hoffmann bdb312cf56 img parse only after usual procedure failed 2025-02-11 15:16:07 +01:00
Johann Hoffmann 2b27b55f40 attempt sanitizing raum content when content is just h1 + img tag; sanitize tables on raum contents sites 2025-02-11 15:05:22 +01:00
Johann Hoffmann fe4351fc87 lv info ort content link when content_id was expanded 2025-02-11 11:23:50 +01:00
Johann Hoffmann eabe8ef401 CalendarDate patch schaltjahr 2025-02-11 10:15:22 +01:00
Harald Bamberger 36d3af91f1 Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-11 09:44:38 +01:00
ma0068 ae3072be92 listTables with preview in two layouts 2025-02-11 09:02:56 +01:00
ma0048 df685133b5 - date filter 2025-02-11 08:58:00 +01:00
Johann Hoffmann 4936cfd61c added roomInfo to app routes & remove old views; stundenplan reservierungen for MA working WIP roomInformation/roomContent link from lvinfo event ort_kurzbz; 2025-02-10 17:05:27 +01:00
Alexei Karpenko 4ccbdecc48 added phrases for new Beurteilungsformular 2025 2025-02-10 13:37:53 +01:00
ma0048 83baa0ed8b - fehlende phrase 2025-02-10 12:59:18 +01:00
ma0068 bca95bcb66 change dateFormat Tab Notizen 2025-02-10 11:04:02 +01:00
ma0068 f653c2c054 change dateFormat Tab Mobility 2025-02-07 14:06:48 +01:00
ma0068 72649f4177 change dateFormat Tab Contact 2025-02-07 13:52:17 +01:00
ma0068 5ae9a99de4 change dateformats Tab Status 2025-02-07 13:39:51 +01:00
ma0068 5ec886e815 Tab Abschlusspruefung: return nothing in case of null date 2025-02-07 13:21:58 +01:00
ma0068 21ecbf482f change dateformate Betriebsmittel 2025-02-07 13:16:59 +01:00
Harald Bamberger acc57bbebd fix problem with vanishing factory entries when called via Form.js computed factory 2025-02-07 11:46:02 +01:00
ma0068 3db367b255 bugfix Uhrzeit, datumsformat for tab abschlusspruefung 2025-02-07 09:34:07 +01:00
Harald Bamberger 6ac91dc016 add mustache brackets to phrases in template 2025-02-06 16:26:28 +01:00
Harald Bamberger cb46dff548 fix props declarations 2025-02-06 16:25:41 +01:00
Harald Bamberger 83321ac2ab fix props declarations 2025-02-06 16:25:00 +01:00
Harald Bamberger 4fe801ddf9 fix props declarations 2025-02-06 16:24:34 +01:00
Harald Bamberger a507533f40 use getStudiengangByKz to get stgtyp and stg_oe_kurzbz for checking showallformats permission, add and use phrase notekommpruefung 2025-02-06 16:23:42 +01:00
Harald Bamberger 0cca508881 add Studiengang Endpoint getStudiengangByKz 2025-02-06 16:19:27 +01:00
Johann Hoffmann fc06ffe0e5 fix jumping into march 01 from january 29 2025-02-06 13:18:19 +01:00
Harald Bamberger 3ce803684a change prop type to String since an uid is passed 2025-02-06 11:33:38 +01:00
Harald Bamberger e4e6849351 cleanup duplicate attribute definition 2025-02-06 11:31:25 +01:00
Harald Bamberger 2008fc2a15 remove duplicate attribute definition 2025-02-06 11:26:35 +01:00
Harald Bamberger 422ce28703 use correct phrases category 2025-02-06 11:25:57 +01:00
ma0068 018220594a prepare basic framework 2025-02-06 08:34:34 +01:00
Harald Bamberger 9d0e365516 use tabulator header filters 2025-02-05 18:49:46 +01:00
Harald Bamberger 3fff535713 prevent custom defaultHeaderFilter breaking tristate built-in filter 2025-02-05 18:49:07 +01:00
Harald Bamberger 9745621975 remove duplicate pharse bankverbindung category person 2025-02-05 17:08:20 +01:00
Johann Hoffmann a0ddde4978 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2025-02-05 17:02:55 +01:00
Johann Hoffmann e901d414a0 lane overlay div up to certain % instead of all day opaque or not; defined hours length and calculating accurate lane width from that; 2025-02-05 17:02:21 +01:00
Harald Bamberger 61ec4ce6c1 Merge branch 'master' into merge_FHC4_C4 2025-02-05 16:58:20 +01:00
Harald Bamberger 4410baf7ac Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-05 16:57:52 +01:00
Harald Bamberger 99c3403009 check against information schema if column exists 2025-02-05 16:55:48 +01:00
Johann Hoffmann b198b6a961 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2025-02-05 16:05:04 +01:00
Johann Hoffmann b8823052f5 deactivate old month page css for day number and events in favor of new computed style (can be redesigned but is being handled in js instead of css class); save & inject/provide observed resize from already existing ResizeObserver to be able to access concrete container width/height values we already had all the time anyway; added some comment to 2year old TODO concerning calendar breakpoints; check if navbar is showing before toggling programmatically; remove some unused code; week time line spawns in dayLane which is representing today to avoid caluclating left/right offsets -> WIP accurately retrieving lane width somehow else, currently approximated; 2025-02-05 16:03:20 +01:00
SimonGschnell 7c8508da0e update(Infoterminal authentification): adds a query parameter to the infoterminal view that enables authentification 2025-02-05 12:50:23 +01:00
Harald Bamberger d038119a3b adapt infoterminal page so that login can be forced 2025-02-05 11:41:02 +01:00
SimonGschnell d889756302 update(Calendar exports): viewdata update 2025-02-05 11:03:19 +01:00
SimonGschnell 9ec57b6ce7 update(calendar exports): adds icons to the calendar exports buttons 2025-02-05 09:26:00 +01:00
Johann Hoffmann d70cd58698 past shadow on day page if it is today; current time line on day & week page; mobile checkup; close lvInfoModal on stundenplan unmount; 2025-02-04 18:04:41 +01:00
ma0068 6eb9c2ac22 update filtering 2025-02-04 14:57:35 +01:00
ma0068 7fbff20dd9 new Tab Gruppen 2025-02-04 14:49:41 +01:00
SimonGschnell 9082c3cb8c feature(Calendar Exports): uses the old enpoints to export excel,csv,ical1,ical2 documents 2025-02-04 14:37:34 +01:00
SimonGschnell cc5a14ea02 update(Sprachen.js): switches colors for the currently active sprache 2025-02-04 14:37:34 +01:00
ma0048 50fa3d6f94 - faktor in eigener spalte 2025-02-04 10:42:59 +01:00
Harald Bamberger 03c192cbbf Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-03 16:58:45 +01:00
Harald Bamberger b10ee208ff pad only in y direction 2025-02-03 16:58:25 +01:00
Harald Bamberger 63239b3fb6 Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-02-03 16:14:23 +01:00
Harald Bamberger 1a0601ebc0 Merge branch 'feature-54856/FHC4_Studierendenverwaltung_In_Out' into merge_FHC4_C4 2025-02-03 16:06:06 +01:00
Harald Bamberger 5843d1d58e Merge branch 'master' into merge_FHC4_C4 2025-02-03 15:53:55 +01:00
Cristina ac98420130 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-02-03 10:39:45 +01:00
Johann Hoffmann 11ad8ae1c8 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2025-01-31 14:10:26 +01:00
Johann Hoffmann c1918726df Stundenplan Week Page smaller breakpoints style handling; searchbar emit action finished on default link click; month stundenplan past days use opacity-50 class; Day page height fix of right col; 2025-01-31 14:09:05 +01:00
ma0068 dbd7adc96c adapt inline form validations, edit validation in final exam tab 2025-01-31 12:55:34 +01:00
SimonGschnell 0892b94c93 update(legacyLinkHelper): fixes little regex bugs 2025-01-31 12:08:40 +01:00
ma0068 ec46dbd10d Validation during delete for extension mobility, add field lehreinheit to dropdown and backend 2025-01-30 14:56:48 +01:00
ma0068 304433d76f Merge branch 'merge_FHC4_C4' of github.com:FH-Complete/FHC-Core into merge_FHC4_C4 2025-01-30 11:07:17 +01:00
ma0068 7cf0060e40 delete testoutputs 2025-01-30 11:07:03 +01:00
ma0048 9cd7caa6ba added missing file 2025-01-30 09:08:53 +01:00
ma0048 42a09ffa9e - lehrform beim faktor hinzugefuegt
- indexes
- delete restrict -> delete cascade bei der faktor tabelle
- neues recht fuer reports -> direktzugriff
2025-01-29 15:21:01 +01:00
SimonGschnell b855c404e4 update(Cis Profil picture): instead of using cover, uses contain for the cis profile picture and adds a black border and background color 2025-01-29 14:33:42 +01:00
SimonGschnell 062e6e5f90 update(Sprachen.js): updates the usage of the classes fhc-entry in the Sprachen.js component 2025-01-29 14:04:36 +01:00
SimonGschnell 10c718b78c update(CalendarDate):changes the stop watcher function 2025-01-29 12:10:16 +01:00
ma0068 06dcad755b Backendvalidation insert and update, validation local tabulator array 2025-01-29 07:38:21 +01:00
Harald Bamberger 7f645b363f Merge branch 'master' into merge_FHC4_C4 2025-01-28 16:54:08 +01:00
Cristina 9a53880b9d Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite 2025-01-28 13:58:58 +01:00
ma0068 dacde5f5fd Merge branch 'merge_FHC4_C4' of github.com:FH-Complete/FHC-Core into merge_FHC4_C4 2025-01-28 13:31:44 +01:00
ma0068 d906e9b4a3 edit missing fileextensions 2025-01-28 13:31:24 +01:00
SimonGschnell bd3eeff684 update(Stundenplan Style): changes the background/color styles for Calendar events in the different views 2025-01-28 13:22:57 +01:00
Harald Bamberger ad0fccab6a Merge branch 'master' into merge_FHC4_C4 2025-01-28 13:20:32 +01:00
SimonGschnell 9a3221e88e update(Fhc.js): installs font contrast directive in the global app 2025-01-28 13:13:02 +01:00
SimonGschnell 8991ab86a5 update(fhc-entry css class): instead of hard coding the color the css rules uses the filter:brightness function to highlight or darken elements 2025-01-28 13:04:43 +01:00
SimonGschnell 9816521291 directive(text color contrast): adds a directive that determines a suitable font color based on the background color of the element through a directive 2025-01-28 13:01:24 +01:00
Harald Bamberger a89ca4e143 Merge branch 'feature-53938/StV_Tab_Noten_fertigstellen' into merge_FHC4_C4 2025-01-28 09:49:53 +01:00
ma0068 d96cc5672e child components Zweck/Purpose and Aufenthaltsfoerderung/Support 2025-01-28 09:39:24 +01:00
Harald Bamberger 519aa2f9b2 Merge branch 'feature-25999/C4_cleanup' into merge_FHC4_C4 2025-01-27 18:34:42 +01:00
Harald Bamberger 872f883ce1 Merge branch 'bug-52531/Studierendenverwaltung/Adressenhandling' into merge_FHC4_C4 2025-01-27 18:29:48 +01:00
Harald Bamberger 637a7b1d17 Merge branch 'feature-53936/StudierendenVerwaltung_Studierendenliste_Anzahl_einblenden' into merge_FHC4_C4 2025-01-27 18:20:31 +01:00
Harald Bamberger db70a7869c Merge branch 'feature-54564/FHC-4_Studierendenverwaltung_Abschlusspruefung' into merge_FHC4_C4 2025-01-27 18:17:50 +01:00
Harald Bamberger a60ce78d18 Merge branch 'feature-40280/FHC4_Studierendenverwaltung_Pruefung' into merge_FHC4_C4 2025-01-27 17:39:47 +01:00
Harald Bamberger 2b5d23782b Merge branch 'feature-47784/FHC-4/CleanupTasks' into merge_FHC4_C4 2025-01-27 17:13:15 +01:00
SimonGschnell ec23974129 update(searchbar): makes the searchbar more visible by adding additional border and adding a search icon at the beginning of the searchbar 2025-01-27 15:13:27 +01:00
SimonGschnell e53dae24e6 update(Calendar Locale): updates the locale used by the english language to en-GB instead of en-US 2025-01-27 13:24:47 +01:00
SimonGschnell 8afc2ab433 addition(InfoTerminal): adds the Infoterminal page to the cis4 2025-01-27 11:50:51 +01:00
ma0048 b079d22e8d - filter hinzugefuegt
- db index hinzugefuegt
- sqls optimiert
- diplomand wird nun auch angezeigt
2025-01-27 09:37:02 +01:00
SimonGschnell 467072b94e update(Stundenplan.js): adds event beginn & ende time to the event display in Wochen/Tages Ansicht 2025-01-24 12:17:31 +01:00
SimonGschnell 38a083742d update(MyLv Noten farbe): uses db positiv column to determine the color of the grade in the MyLv component 2025-01-24 11:18:46 +01:00
ma0068 c69910a338 Child component Purpose.js for tableview 2025-01-24 11:00:50 +01:00
SimonGschnell 9b348aed11 fix(Dashboard News): fixes carousel animations when skipping news 2025-01-23 13:20:57 +01:00
SimonGschnell e7df262cc5 update(News Dashboard): next and previous icons don't stay active after clicking them 2025-01-23 10:41:55 +01:00
Johann Hoffmann 8133d73cff remove route logging & catchAll fallback 2025-01-22 16:47:14 +01:00
Johann Hoffmann 9350838ebc set menu entry active when clicked 2025-01-22 16:43:37 +01:00
Johann Hoffmann 10e4032718 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2025-01-22 15:16:59 +01:00
Johann Hoffmann de8a206f27 delete cms app and move dom magic to respective components; profil vue router integration; profil component reloads with watcher on uid property; profiLUpdateRequest app->comp TODO; deleted profil app; 2025-01-22 15:16:15 +01:00
SimonGschnell 065f6bdede update(News Dashboard): updates the stylesheet so that the layout of the news is responsive 2025-01-22 13:36:59 +01:00
Johann Hoffmann bb8ebdd465 initial route through router implicit; ci route tag only for debugging purposes. 2025-01-22 10:49:53 +01:00
Johann Hoffmann c7f3398b11 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2025-01-21 16:42:58 +01:00
Johann Hoffmann e9b01b7fa8 vue router merge cms & fhc app; viewData check and fetch in dashboard and widgets if not originating from that php controller; lvinfo app delete; code cleanup profil; WIP profil routing; 2025-01-21 16:42:23 +01:00
SimonGschnell d72bc4fa44 update(News DashboardWidget): updates how to betreff is queried from the XML 2025-01-21 14:20:40 +01:00
SimonGschnell 381b6a75db update(News DashboardWidget): doesn't render news which don't have a topic 2025-01-21 09:40:22 +01:00
SimonGschnell ff0ee68229 refactor(BookmarkWidget) 2025-01-17 12:47:04 +01:00
ma0048 0d99cc35d4 - phrasen angepasst 2025-01-16 15:59:36 +01:00
Johann Hoffmann 0ec3ba8e69 intercept a tag clicks and attempt vue routing to avoid having to know about vue router configuration; routes include Stundenplan, MyLv; 2025-01-16 15:16:33 +01:00
SimonGschnell 4b2a1cd7f6 update(Url.js): adds scrolling behavior to the Bookmark widget 2025-01-16 11:32:19 +01:00
SimonGschnell 46c033ad77 update(NewsWidget):reduces z-index so that it does not overlap modals, add light background to the next/prev buttons for visibility 2025-01-16 11:10:03 +01:00
SimonGschnell aef0e34b93 update(Calendar/Header.js):icon reihenfolge sowie icon fuer Tagesansicht wurden angepasst 2025-01-16 10:41:21 +01:00
SimonGschnell 09b2615d82 update(FhcAlert.js): if the request was aborted, no error message is shown to the user 2025-01-15 14:42:13 +01:00
SimonGschnell 7b46db7100 update(LegacyLinkReplaceHelper.js):adds constants for the replacement strategies when the pattern has groups that should be added as path_segements or query_parameters 2025-01-15 14:15:03 +01:00
Johann Hoffmann f60f735fa8 FhcApp uses vueRouter4; CisApp checks for global router instance and routes internally as long as a path/routename/component setup is defined, if that is not the case use the provided href link; WIP moving apps like Profil, MyLv etc into components to be navigated by FhcApp; 2025-01-15 14:10:08 +01:00
SimonGschnell bae7b330f8 feature(LegacyLinkReplacementHelper.js): adds a helper file with multiple functions that replace relative or absolute legacy links with new links that use the new app_root and ci_router 2025-01-15 13:34:54 +01:00
SimonGschnell cf57fe5086 replaces the old relative paths inside the content html with absolute paths that use the new app_root path 2025-01-15 09:45:03 +01:00
SimonGschnell 516554c1e3 update(CalendarDate.js): uses phrasen.user_locale for calculations and watches for changes on the user_locale 2025-01-14 11:43:50 +01:00
Johann Hoffmann cf32974652 fhc chart just accepts chartOptions to maximize highcharts usability; statsComponent multiselect ux improvement; 2025-01-13 17:36:09 +01:00
SimonGschnell 907107d78d update(searchbar.js): adds the search text to the sessionStorage and the searchOption to the localStorage 2025-01-13 14:45:41 +01:00
SimonGschnell 16097edfca refactor(CalendarDate.js): sets the locale for every new instance of CalendarDate that gets created in the CalendarDate.js class 2025-01-13 09:41:58 +01:00
SimonGschnell 05cbe495fe fix(Calendar Weeks View): updates the number of weeks in the weeks View when going to the next or previous year 2025-01-13 09:29:54 +01:00
SimonGschnell 14d4e103a3 update(Calendar Tages Ansicht): doesn't how the hour indicator if there are no events that day 2025-01-10 13:50:47 +01:00
SimonGschnell 478588aef0 fix(Calendar Date Issues):fixes a variety of user_locale calendar bugs 2025-01-10 13:46:24 +01:00
ma0068 03ad3116f7 temp formular 2025-01-10 07:16:56 +01:00
SimonGschnell d9375e2c8b comment(CalendarDate.js): adds comments to the functions: firstDayOfCalendarMonth, lastDayOfCalendarMonth, firstDayOfWeek, lastDayOfWeek 2025-01-09 15:04:56 +01:00
Johann Hoffmann 848d50ec93 Graph has reactive state over several types; WIP seperating data UI from graph component 2025-01-09 14:35:17 +01:00
Johann Hoffmann 036aeb5215 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2025-01-08 16:13:50 +01:00
Johann Hoffmann 2fdca1f09f WIP stats Tab in anw extension & FhcChart component in fhcore; 2025-01-08 16:12:30 +01:00
SimonGschnell b20965fcff refactor(CalendarDate.js): adds comments and restructures some conditionals 2025-01-08 13:31:38 +01:00
SimonGschnell 50f55eed1a Merge remote-tracking branch 'origin/bhdev' into feature-25999/C4_cleanup 2025-01-08 11:20:33 +01:00
SimonGschnell a67cc8cc4e Merge branch 'master' into feature-25999/C4_cleanup 2025-01-08 11:17:29 +01:00
SimonGschnell 26348bed80 update(FHC_JS_DATA_STORAGE_OBJECT/Sprachen.js): adds server_languages and their locale to FHC_JS_DATA_STORAGE_OBJECT and updates Sprachen.js accordingly 2025-01-08 11:15:55 +01:00
Harald Bamberger e432501a1f possible fix for kw 1 issue 2025-01-07 17:09:07 +01:00
SimonGschnell 6361d40356 update(WeekCalendarHeader):uses the last day of the week instead of the first day of the week for the calendar title 2025-01-07 15:26:08 +01:00
SimonGschnell c7ee2934a7 fix(Stg 0 not found bug): displays the LV in the lvMenu differently if the stg_kurzbz is 0, which is the case for lv's that are organisational 2025-01-07 11:17:29 +01:00
SimonGschnell 5a45b29bcd comment(Profil Quick links): comments the quick links of the profil views away because there is no idea of implementation yet 2025-01-07 09:10:41 +01:00
cgfhtw b43df5aea0 NotenTab: Phrases 2024-12-27 14:44:53 +01:00
SimonGschnell 574301d9e2 fix(Calendar Language): also update the tooltips of the calendar by using the client lannguage 2024-12-20 15:03:05 +01:00
cgfhtw 469c01c9e6 Comments 2024-12-20 14:15:28 +01:00
cgfhtw e13e612ad9 Merge branch 'master' into feature-53938/StV_Tab_Noten_fertigstellen 2024-12-19 16:48:15 +01:00
cgfhtw 174816e652 Cleanup & existing phrases 2024-12-19 16:42:02 +01:00
cgfhtw d899bf3393 NotenTab: Document download/archive 2024-12-19 16:20:14 +01:00
cgfhtw 14eb27ae24 add PrimeVue TieredMenu 2024-12-19 16:19:46 +01:00
cgfhtw de9e3d079c Endpoints for document download/archive (content/pdfExport.php with "archivdokument" not set) 2024-12-19 16:18:51 +01:00
Johann Hoffmann 551fd3a860 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-12-19 16:08:25 +01:00
Johann Hoffmann 64ff94882b stats enabled config flag; using highcharts plugin in new Tab & Component for (anw)Statistics; currently able to show old pie charts from old landing page; wip building setup UI for configurable graphs depending datasets and chart types; 2024-12-19 16:07:56 +01:00
ma0068 c980dee96b edit select 2024-12-19 15:25:21 +01:00
SimonGschnell 114562909f update(Calendar.js): uses the user_language for the different day formattings in the calendar views 2024-12-19 12:12:13 +01:00
Johann Hoffmann e2af00e41d highcharts consolidation -> add plugin, import switch to footer and repository requirement in composer.json 2024-12-19 11:24:31 +01:00
ma0068 39a23693ba start Table Mobility 2024-12-18 16:31:39 +01:00
ma0068 ba62abc19b bug stv 2024-12-18 14:57:18 +01:00
SimonGschnell 1094219a58 helper(Json.js):adds new helper component to display JSON data in the template, that can be used globally inside a vuejs app 2024-12-18 14:26:45 +01:00
SimonGschnell 313a6a6030 fix(Profil Views): corrects the title of the web tab from Stundenplan to Profil 2024-12-18 13:47:52 +01:00
ma0068 faa705408d Merge master into feature-54564/FHC-4_Studierendenverwaltung_Abschlusspruefung 2024-12-18 13:12:57 +01:00
ma0068 9f5b3b6f32 Print Functionality and Phrases 2024-12-18 12:56:51 +01:00
cgfhtw e1327453f7 DocumentExportLib: CI version of dokument_export.class 2024-12-18 09:43:16 +01:00
cgfhtw 636a331ca6 add Vorlagestudiengang_model->getCurrent similar to vorlage.class->getAktuelleVorlage 2024-12-17 14:29:37 +01:00
SimonGschnell e3f91003b3 phrasen(Profil.js): adds dynamic phrasen for the various Profil Views 2024-12-17 11:29:05 +01:00
SimonGschnell d247150fd6 phrasen(StudiengangInformationen.js): adds Phrasen to the StudiengangInformationen Component and all its subcomponents 2024-12-17 10:55:13 +01:00
cgfhtw b78382f1ba Add extra fields/joins to getZeugnisnoten 2024-12-17 09:27:18 +01:00
Johann Hoffmann 25dbee7266 removed app instance hacks, content component watches route.param.content_id and reloads accordingly; changed template to <router-view/> for cms pages; 2024-12-16 11:46:38 +01:00
Johann Hoffmann 0509137ad8 Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_CMS_content_router
# Conflicts:
#	public/js/apps/Cis/Cms.js
#	public/js/components/Cis/Cms/Content.js
2024-12-16 10:38:22 +01:00
SimonGschnell b4cd5055d2 delete(Contentl.js/Debugging prints) 2024-12-13 14:48:48 +01:00
SimonGschnell cb6fca9a2e update(Cms.js/News.js/PhrasenPlugin): removes the reload option, because the content can be newly fetched based on the currently active language 2024-12-13 14:41:07 +01:00
SimonGschnell 701f44c767 update(Cis4-Menu/Sprache): changes language of the Menu when switching language of the application 2024-12-13 14:40:01 +01:00
Johann Hoffmann 986b6934d6 Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_CMS_content_router
# Conflicts:
#	public/js/components/Cis/Cms/News.js
2024-12-13 12:04:38 +01:00
Johann Hoffmann 499e3077e2 Merge branch 'master' into feature-25999/C4_CMS_content_router 2024-12-13 12:00:50 +01:00
Johann Hoffmann 98d4a08836 navigating to another content_id link from cms app reloads the content instead of entire page; WIP implementing abstract reload functionality for all content types; 2024-12-13 11:52:34 +01:00
SimonGschnell 8f07bd6b4d update(Sprachen.js): shows the sprachen in the component always using their bezeichnung 2024-12-12 14:46:32 +01:00
SimonGschnell 7bd9129056 fix(LvMenu/Lv.js): removes the list-item styling from the spinner when the data for the lvMenu is not yet ready and aligns the spinner in the center of the card 2024-12-12 13:47:15 +01:00
SimonGschnell 24ff474cad update(MyLv/Lv.js):the user can only click on the grade of an lv if the lv had multiple pruefungen otherwise the grade is not clickable 2024-12-12 13:31:06 +01:00
SimonGschnell 4321a2325b update(StudiengangInformation.js): adds the general moodle link for the Studiengang informations to the component using a static link 2024-12-12 11:35:16 +01:00
SimonGschnell 1d5f13c5ce Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-12-12 09:52:27 +01:00
Johann Hoffmann 82e7783259 stundenplan day layout fixed for scroll behaviour; max-height for stundenplan events to avoid escalating the grid width; 2024-12-11 16:59:35 +01:00
SimonGschnell e215e9e948 refactor(News-Paginator@Bottom):also adds the pagination at the bottom of the news, so that the user doesn't have to scroll up if he reaches the end 2024-12-11 12:44:06 +01:00
Johann Hoffmann fcbb9e43a4 Merge branch 'master' into feature-25999/C4_cleanup 2024-12-11 11:08:49 +01:00
Johann Hoffmann 53de29f3d2 stundeplan_model byLva() query when providing lv_id irrespective of student, group, lector etc just fetch all & show them 2024-12-09 17:13:23 +01:00
Johann Hoffmann e9d02c41ff merge fix; 2024-12-09 15:42:08 +01:00
Johann Hoffmann 04583d0cf2 Merge branch 'feature-25999/C4_anwesenheiten_widget' into feature-25999/C4_cleanup
# Conflicts:
#	public/js/components/Cis/Cms/News.js
#	public/js/components/DashboardWidget/News.js
#	public/js/plugin/FhcApi.js
2024-12-09 15:37:20 +01:00
Johann Hoffmann cbdd6bc954 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-12-09 14:32:35 +01:00
Johann Hoffmann a1045586fe use carousel instance .to(index) & computed classes to retrieve order; 2024-12-09 14:30:33 +01:00
SimonGschnell e9d2234353 feature(Studiengang Widget):creates a component for the Studiengang Widget that reuses the StudiengangInformation component 2024-12-09 13:36:18 +01:00
Johann Hoffmann 9fd0f43d3b news widget prev/next button hover styles; mobile responsive menu & gutter layout fix; 2024-12-06 13:04:28 +01:00
SimonGschnell 39ffd6bdb9 fix(news Widget api): readds the removed api call from the news widget because it differs from the getNews api call that is used in the News View 2024-12-06 09:59:58 +01:00
SimonGschnell 0a5c335602 refactor(News-StudiengangInformationen): component clean up and refactors vertretungen into own component 2024-12-05 16:22:21 +01:00
cgfhtw 6fdad1b664 Noten Tab: delete 2024-12-05 16:19:51 +01:00
cgfhtw 3969ebfa01 Filter Component: better btn width/height css 2024-12-05 15:26:38 +01:00
SimonGschnell 797e52aad7 refactor(News-StudiengangInformationen): adds the Studiengangs informationen next to the news View 2024-12-05 15:22:53 +01:00
cgfhtw 5fd14949fa Tabulator Default Layout: fitDataStretchFrozen 2024-12-05 15:13:58 +01:00
cgfhtw 482f6b9a19 FhcAlert Color Bugfix 2024-12-05 15:08:31 +01:00
Johann Hoffmann 7f6884b67d primevue imports cis/dashboard; Anw widget implementation; WIP showing single anw entries on click on a quota progress bar in widget; 2024-12-05 15:03:46 +01:00
Johann Hoffmann f0e97c915b rename bindKeys() to addEndpoints(); removed Vue.reactive on $fhcApi; check if Api has been instantiated in install, only addEndpoints if that is the case; 2024-12-05 13:53:08 +01:00
SimonGschnell ecbb65c2a4 feature(News-StudiengangsInformationen): adds the Studiengangsinformationen next to the news view 2024-12-04 15:04:05 +01:00
Johann Hoffmann f7bc01e63f actually provide root to bindKeys() in FhcApiFactoryWrapper constructor 2024-12-04 13:53:59 +01:00
Johann Hoffmann 65c154054d actually provide root to bindKeys() in FhcApiFactoryWrapper constructor 2024-12-04 13:52:17 +01:00
Johann Hoffmann 27cd9dca6b Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_anwesenheiten_widget 2024-12-04 13:49:32 +01:00
Johann Hoffmann 00fba24936 fhcApi.factory.bindKeys to extend api later on from extensions 2024-12-04 13:48:28 +01:00
Harald Bamberger 57cba02559 Merge branch 'master' into feature-25999/C4_cleanup 2024-12-04 13:35:59 +01:00
SimonGschnell a3dc5aec93 feature(StudiengangInformations componente): creates a Vue component for the StudiengangsInformationen that were displayed next to the news 2024-12-04 11:20:52 +01:00
Harald Bamberger af3334f227 Merge branch 'feature-25999/C4_cleanup_rc' into feature-25999/C4_cleanup 2024-12-04 09:29:29 +01:00
Harald Bamberger 16e7ee8aba Merge branch 'feature-25999/C4_cleanup_rc' into feature-25999/C4_cleanup 2024-12-04 09:17:57 +01:00
ma0068 7cff70e88d update search Mitarbeiter, form 2024-12-04 08:34:36 +01:00
Johann Hoffmann fe6f229d9f template fix; remove unused menu function; 2024-12-03 14:44:18 +01:00
cgfhtw 446a5732d2 NotenTab: Use Points 2024-12-03 09:27:38 +01:00
Cris 2ae9e4fffa Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite 2024-12-02 11:02:43 +01:00
ma0068 00d64f2c97 bugfix index Favorites 2024-12-02 08:54:35 +01:00
ma0068 ae58cef816 Merge master 2024-12-02 08:43:13 +01:00
Harald Bamberger 90ae50ac59 Merge branch 'master' into feature-47784/FHC-4/CleanupTasks 2024-11-29 12:48:38 +01:00
cgfhtw cf6cc97475 Noten Tab: header/inline edit 2024-11-29 08:42:36 +01:00
ma0068 bf6b6e4563 actions insert, update, delete, link Pruefungsprotokoll 2024-11-28 16:29:13 +01:00
ma0068 9024b43f62 Merge master into feature-47784/Cleanup Tasks FHC4 2024-11-28 07:26:59 +01:00
ma0068 e8ded1f59f prepare branch before merge phrases 2024-11-28 07:14:15 +01:00
Cris b549622f50 Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite
# Conflicts:
#	application/models/organisation/Studiensemester_model.php
#	system/phrasesupdate.php
2024-11-27 17:44:45 +01:00
Cris 3ec748e6fb Added new phrases for Softwarebereitstellung 2024-11-27 17:31:48 +01:00
Cris c94a2d2d0c Added param lehrveranstaltung_id to getTemplateLvTree method in Lehrveranstaltung_model.php and enhanced order
Now ordering extra templates to appear first and directly after the assigned lvs
2024-11-27 17:31:02 +01:00
Cris 1159b0dad5 Refactored getLvs method in Lehrveranstaltung_model.php 2024-11-27 17:28:54 +01:00
ma0068 f398a5699f merge into feature-54564 2024-11-27 15:14:48 +01:00
ma0068 ffe28ea8fb undo phrases changes to avoid merging conflict 2024-11-27 14:58:00 +01:00
ma0068 3318147ba0 Start tab Abschlusspruefung, Table and Form with Dropdowns and default data 2024-11-27 12:52:03 +01:00
cgfhtw 3457309d63 Switching grades to single edit 2024-11-26 15:06:13 +01:00
cgfhtw 5f61ae43f9 Hide Noten Tab from non-Students 2024-11-25 16:23:43 +01:00
cgfhtw 9c32e6f968 Zeugnis title 2024-11-25 13:06:13 +01:00
cgfhtw 28e4454409 Move Semester Filter to top component 2024-11-25 11:20:44 +01:00
cgfhtw 334fc870d0 Repeater Grades 2024-11-25 10:45:45 +01:00
ma0068 9c503ae66f Validierung Modal askAusbildungssemester 2024-11-22 10:51:47 +01:00
ma0068 bb724bef6e Bug filter Semester 2024-11-22 08:08:35 +01:00
ma0068 b0fb045b50 Cleanup tasks: add factory, validations in form, phrases ID 2024-11-21 16:07:10 +01:00
ma0068 f2b5c12e6d add abort controller to autocomplete fields 2024-11-21 15:53:58 +01:00
ma0068 94255709c7 mark mandatory fields 2024-11-21 14:31:57 +01:00
ma0068 7a0690227c Merge branch 'feature-47784/FHC-4/CleanupTasks' of github.com:FH-Complete/FHC-Core into feature-47784/FHC-4/CleanupTasks 2024-11-20 16:23:16 +01:00
ma0068 d17c776905 bug address.js, phrase Notiz 2024-11-20 16:22:39 +01:00
Cris e94e9ceff2 Added phrases 'zuordnungExistiertBereits' and 'swFuerLvAendern' 2024-11-20 14:07:43 +01:00
Cris 8a22eab0c8 Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite 2024-11-20 13:59:35 +01:00
Cris ae94daa4a6 Added getStudienjahrByStudiensemester method to Studiensemester Model 2024-11-20 13:57:30 +01:00
Cris 933af94344 Added checkIsTemplate method to Lehrveranstaltung Model
Checks if given LV is a template (Quellkurs)
2024-11-20 13:55:11 +01:00
Cris 8614e4301f Added getStudienjahrByStudiensemester method to Studiensemester API Controller 2024-11-20 13:54:05 +01:00
cgfhtw e0e123f264 Teacher Component 2024-11-20 13:19:43 +01:00
cgfhtw ad01c8bdeb Bugfix: reinitialize initialData in Prestudent Tab after saving 2024-11-20 12:45:14 +01:00
cgfhtw 8593fda5cd Bugfix: scrolling in Notiz Tab 2024-11-20 12:44:45 +01:00
cgfhtw e76d8fb85d Phrases & TODO cleanup 2024-11-20 11:15:18 +01:00
cgfhtw fe7ca2bf69 Teacher Proposal 2024-11-20 11:06:28 +01:00
cgfhtw 5369c95e77 Scroll Bug Notizen Tab 2024-11-20 11:05:05 +01:00
ma0068 b189ac8cd0 adapt Notes: Tinymce, textarea, delete bsModal 2024-11-20 10:41:12 +01:00
cgfhtw d650587418 use fhcApi for grades tab 2024-11-18 09:58:59 +01:00
ma0068 eccd827c71 adaptions and additions cleanup tasks according to task 54312 2024-11-15 11:14:58 +01:00
cgfhtw da465fffb1 Points to Grade conversion 2024-11-15 09:56:58 +01:00
cgfhtw 5705cd2d66 Note einblenden 2024-11-15 09:56:22 +01:00
cgfhtw 1cdf1e7896 Anzahl anzeigen 2024-11-13 10:08:36 +01:00
cgfhtw 2ed5df8c1c Orgform of Stg in searchresults 2024-11-07 17:01:51 +01:00
cgfhtw 72c992569c Improvements Mergedperson Component 2024-11-07 13:33:51 +01:00
cgfhtw f82ed6928a Phrasen 2024-11-07 11:47:35 +01:00
cgfhtw 8c689418f7 Bugfixes 2024-11-07 09:57:26 +01:00
cgfhtw 02a5465708 Merge branch 'master' into feature-40128/Mehrere_Suchergebnisse_für_selbe_Person 2024-11-05 15:41:48 +01:00
cgfhtw e3119ee48c cleanup 2024-11-05 15:35:00 +01:00
cgfhtw d0cf86585a Visual update for search icons 2024-11-05 11:42:18 +01:00
cgfhtw 3a13226298 Bug: merge "RECURSIVE"-keyword 2024-11-05 11:08:07 +01:00
cgfhtw 2ff7c9f582 Dms search result component 2024-11-05 09:02:09 +01:00
cgfhtw b27564ea0f Multiple uids in person search 2024-11-05 09:01:18 +01:00
cgfhtw 0916d34767 DMS Search 2024-10-31 14:25:27 +01:00
cgfhtw 8d00a9b4c9 Bugfix 2024-10-31 14:22:31 +01:00
cgfhtw 963391ec99 Bug: counting "with" statements + allowing multi primarykey + allowing "recursive" statement in prepare config 2024-10-28 11:20:51 +01:00
cgfhtw b1f4e5487d Bug: wrong function name 2024-10-28 11:18:25 +01:00
cgfhtw 084a13316d Remove duplicate emails 2024-10-28 11:17:03 +01:00
cgfhtw a9a18d1cd4 Remove deprecated components 2024-10-28 11:16:02 +01:00
ma0068 0779bc5204 bugfix add and update Adresse 2024-10-23 16:33:02 +02:00
ma0068 e283997293 cleanUp Tasks Tab Details 2024-10-23 14:26:33 +02:00
ma0068 8787558fef cleanUp Tasks Tab PrestudentIn 2024-10-22 15:58:02 +02:00
Cris dcb24415fc Added phrases 'errorConfigFehlt' and 'errorUnbekannteUrl' 2024-10-21 14:02:25 +02:00
ma0048 5cee80ed12 - rtliste automatisierte messages 2024-10-18 13:24:39 +02:00
Cris 2f448ca2bc Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite
# Conflicts:
#	system/phrasesupdate.php
2024-10-16 09:44:50 +02:00
cgfhtw 123f29a750 CMS Search 2024-10-14 11:22:20 +02:00
cgfhtw 322544c7fb dynamic image url for searchresults 2024-10-14 11:20:46 +02:00
Cris 7096bba958 Added phrases for Softwarebereitstellung 2024-10-07 16:37:45 +02:00
Cris b08e01f72f Added columns to and moved where-clauses from _getQryLvsByStudienplan to calling methods in Lehrveranstaltung_model.php
.added cols lehrtyp_kurzbz and lehrveranstaltung_template_id
2024-10-07 16:37:07 +02:00
Cris 8744a00ce7 Added filter lehrtyp_kurzbz and $oe_column to getLvsByStudienplan in Lehrveranstaltung_model.php
.lehrtyp_kurzbz filters by Lehrtyp 'lv' or 'modul' (default no filter)
.oe_column is used when filtering $oes: Filter by lv.oe_kurzbz or stg.oe_kurzbz (the stg joined to lv)
2024-10-07 16:34:41 +02:00
Cris 11b0e770a2 Added filter lehrtyp_kurzbz to getAutocompleteSuggestions in Lehrveranstaltung_model.php 2024-10-07 16:29:53 +02:00
ma0068 b9911e69c5 renaming id: Tab Contact 2024-10-02 08:58:24 +02:00
ma0068 00cf7b8112 tabs Status and Gesamthistorie: use factories 2024-10-01 15:27:36 +02:00
ma0068 0127982f50 use factories in Address.js, Bankaccount.js, Contact.js 2024-09-27 10:54:54 +02:00
ma0068 9d5a0585b0 Phrases alerts, templates, tabulator 2024-09-26 07:56:15 +02:00
ma0068 1df91303f0 update Permissions, update validations, insert Termin1 with Termin2, finish phrases 2024-09-24 15:10:31 +02:00
cgfhtw 7174f9cbe0 Use Merged Person 2024-09-20 14:38:33 +02:00
cgfhtw 6c08741450 Fist Draft 2024-09-20 14:31:25 +02:00
ma0068 4579c133a8 Validierung Eintragung Note after ExamDate, Hinweis KommPruefung, Phrases 2024-09-20 14:21:45 +02:00
ma0068 a7f51205b1 Show Kürzel Ma in Dropdown, Filter current semester, adapt Berechtigungen, reload semester 2024-09-20 11:41:44 +02:00
ma0068 f874ca43c0 Standard validations, show Hint KommPrfg, disable noten not active 2024-09-18 16:03:35 +02:00
ma0068 4d5ea1f519 adapt addNewPruefung, pruefungModal, function getLvsByStudent 2024-09-17 15:28:18 +02:00
Cris d6d6d0ac48 Added phrases for softwarebereitstellung app 2024-09-16 18:22:28 +02:00
Cris 585cec31e2 Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite 2024-09-16 16:20:51 +02:00
ma0068 de0fbdb72c Form, Table and Queries for new Tab Pruefung 2024-08-29 09:53:34 +02:00
ma0068 d254b9c10b Start Tab Pruefung, Abfrage Pruefungen 2024-08-23 11:58:08 +02:00
cgfhtw c0e2cec556 s&d 2024-08-14 15:51:27 +02:00
742 changed files with 73829 additions and 10483 deletions
+32 -9
View File
@@ -3,12 +3,35 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
use CI3_Events as Events;
/**
* NOTE(chris): example:
Events::on('stv_conf_student', function (&$res) {
$res['test'] = [
'title' => 'TEST',
'component' => './Stv/Studentenverwaltung/Details/Notizen.js'
];
});
*/
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["lehreinheit"] = array(
'calendarEvent' => APP_ROOT.'public/js/components/Cis/Renderer/Lehreinheit/calendarEvent.js',
'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Lehreinheit/modalTitle.js',
'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Lehreinheit/modalContent.js',
'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css'
);
});
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["reservierung"] = array(
'calendarEvent' => APP_ROOT.'public/js/components/Cis/Renderer/Reservierungen/calendarEvent.js',
'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Reservierungen/modalTitle.js',
'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Reservierungen/modalContent.js',
'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css'
);
});
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["ferien"] = array(
'calendarEvent' => APP_ROOT.'public/js/components/Cis/Renderer/Feiertage/calendarEvent.js',
'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Feiertage/modalTitle.js',
'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Feiertage/modalContent.js',
'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css'
);
});
+6
View File
@@ -0,0 +1,6 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
// Define configuration parameters
$config['timezone'] = 'Europe/Vienna';
+7 -1
View File
@@ -4,6 +4,12 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
// CMS Content Id for CIS4 Menu Root
$config['cis_menu_root_content_id'] = 11066;
$config['cis_menu_root_content_id'] = 11087;
// send Mails for ProfilUpdate
$config['cis_send_profil_update_mails'] = true;
// Vilesci CI BaseUrl
$config['cis_vilesci_base_url'] = defined('VILESCI_ROOT') ? VILESCI_ROOT : APP_ROOT;
$config['cis_vilesci_index_page'] = 'index.ci.php';
// Cis CI BaseUrl
$config['cis_base_url'] = defined('CIS_ROOT') ? CIS_ROOT : APP_ROOT;
$config['cis_index_page'] = 'cis.php';
+11
View File
@@ -0,0 +1,11 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// apps for which issues should be displayed
$config['issues_list_apps'] = array('core', 'dvuh');
// functions which enable users to see issues
$config['issues_list_functions'] = array('ass');
// functions which enable users to see issues
$config['issues_list_status'] = array('Aufgenommener', 'Student', 'Incoming', 'Diplomand', 'Abbrecher', 'Unterbrecher', 'Absolvent');
+3 -1
View File
@@ -4,4 +4,6 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
// use vuejs dev version
$config['use_vuejs_dev_version'] = false;
// use bundled javascript
$config['use_bundled_javascript'] = false;
$config['use_bundled_javascript'] = false;
// systemerror_mailto use in FHC-Alert Plugin - if empty Link will not be rendered
$config['systemerror_mailto'] = '';
+11
View File
@@ -0,0 +1,11 @@
<?php
/*It defines which tags are available in LVVerwaltung and whether they are editable
$config['lvverwaltung_tags'] = [
'tag_1' => ['readonly' => false],
'tag_1' => ['readonly' => true]
];
*/
$config['lvverwaltung_tags'] = [];
+13 -3
View File
@@ -64,7 +64,7 @@ $config['navigation_header'] = array(
'lehrveranstaltungen' => array(
'link' => site_url('lehre/lvplanung/LvTemplateUebersicht'),
'icon' => '',
'description' => 'Lehrveranstaltungen',
'description' => 'Lehrveranstaltungen Templates',
'sort' => 15
),
'reihungstest' => array(
@@ -81,6 +81,16 @@ $config['navigation_header'] = array(
'sort' => 30,
'requiredPermissions' => 'infocenter:r'
),
'lvverwaltung' => array(
'link' => site_url('LVVerwaltung'),
'icon' => '',
'description' => 'LV Verwaltung',
'requiredPermissions' => array(
'admin:r',
'assistenz:r'
),
'sort' => 35
),
'lehrauftrag' => array(
'link' => site_url('lehre/lehrauftrag/Lehrauftrag/Dashboard'),
'description' => 'Lehrauftrag',
@@ -93,7 +103,7 @@ $config['navigation_header'] = array(
),
'zverfueg' => array(
'link' => site_url('lehre/lvplanung/AdminZeitverfuegbarkeit'),
'description' => 'Zeitverf&uuml;gbarkeit',
'description' => 'Zeitverfügbarkeit',
'expand' => true,
'sort' => 45,
'requiredPermissions' => array(
@@ -325,4 +335,4 @@ $config['navigation_menu']['system/issues/Issues/*'] = array(
'target' => '_blank',
'requiredPermissions' => array('admin:rw')
),
);
);
+25
View File
@@ -0,0 +1,25 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// liste von raumtyp_kurzbz welche in raumsuche studenten angezeigt werden
$config['roomtypes_student'] = array(
'LAB BM/Chem',
'xEDV 1-36',
'xEDV 37-60',
'EDV 60',
'EDV-HÖPL',
'EDV ES',
'LAB Elek',
'LAB ES/TK',
'Ener-EDV',
'Ener-Lab',
'Ener-SEM',
'Ener-HS',
'HS 59-109',
'HS 25-38',
'HS 39-58',
'LAB Inf',
'LAB Robo',
'LAB SET'
);
+68 -14
View File
@@ -61,27 +61,81 @@ $route['api/v1/organisation/[O|o]rganisationseinheit/(:any)'] = 'api/v1/organisa
$route['api/v1/ressource/[B|b]etriebsmittelperson/(:any)'] = 'api/v1/ressource/betriebsmittelperson2/$1';
$route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1';
$route['CisVue'] = 'CisVue/dashboard';
$route['Cis/Stundenplan/(:any)'] = 'Cis/Stundenplan';
$route['Cis/LvPlan/.*'] = 'Cis/LvPlan/index/$1';
$route['Cis/MyLvPlan/.*'] = 'Cis/MyLvPlan/index/$1';
$route['Cis/MyLv/.*'] = 'Cis/MyLv/index/$1';
// load routes from extensions
$subdir = 'application/config/extensions';
$dirlist = scandir($subdir);
// 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';
if ($dirlist)
// (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';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/outgoing'] = 'api/frontend/v1/stv/Students/getOutgoing';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/gemeinsamestudien'] = 'api/frontend/v1/stv/Students/getGemeinsamestudien';
// (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';
// (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';
// (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';
// (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';
// (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';
// (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';
// // (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'];
foreach($subdirs as $subdir)
{
$files = array_diff($dirlist, array('.','..'));
foreach ($files as &$item)
if(is_dir($subdir))
{
if (is_dir($subdir . DIRECTORY_SEPARATOR . $item))
$dirlist = scandir($subdir);
if ($dirlist)
{
$routes_file = $subdir . DIRECTORY_SEPARATOR . $item . DIRECTORY_SEPARATOR . 'routes.php';
$files = array_diff($dirlist, array('.','..'));
if (file_exists($routes_file))
foreach ($files as &$item)
{
require($routes_file);
if (is_dir($subdir . DIRECTORY_SEPARATOR . $item))
{
$routes_file = $subdir . DIRECTORY_SEPARATOR . $item . DIRECTORY_SEPARATOR . 'routes.php';
if (file_exists($routes_file))
{
require($routes_file);
}
}
}
}
}
}
}
+874
View File
@@ -0,0 +1,874 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
$config['person'] = [
'primarykey' => 'person_id',
'table' => 'public.tbl_person',
'searchfields' => [
'uid' => [
'comparison' => 'equals',
'field' => 'uid',
'join' => [
'table' => "public.tbl_benutzer",
'using' => "person_id"
],
'1-n' => true
],
'vorname' => [
'alias' => ['firstname'],
'comparison' => 'similar',
'field' => 'vorname'
],
'nachname' => [
'alias' => ['lastname', 'surename'],
'comparison' => 'similar',
'field' => 'nachname'
],
'name' => [
'comparison' => 'similar',
'field' => "(vorname || ' ' || nachname)"
],
'email' => [
'comparison' => 'similar',
'field' => 'kontakt',
'join' => [
'table' => "public.tbl_kontakt",
'on' => "kontakttyp = 'email' AND tbl_kontakt.person_id = tbl_person.person_id"
],
"1-n" => true
],
'tel' => [
'alias' => ['phone', 'telefon'],
'comparison' => 'similar',
'field' => 'kontakt',
'join' => [
'table' => "public.tbl_kontakt",
'on' => "kontakttyp IN ('telefon', 'so.tel', 'mobil') AND tbl_kontakt.person_id = tbl_person.person_id"
],
"1-n" => true
],
'preid' => [
'alias' => ['prestudent_id'],
'comparison' => 'equal-int',
'field' => 'prestudent_id',
'join' => [
'table' => "public.tbl_prestudent",
'using' => "person_id"
],
'1-n' => true
],
'pid' => [
'alias' => ['person_id'],
'comparison' => 'equal-int',
'field' => 'person_id'
]
],
'resultfields' => [
"ARRAY( SELECT uid FROM public.tbl_benutzer WHERE person_id = p.person_id ) AS uids",
"p.person_id",
"(p.vorname || ' ' || p.nachname) AS name",
"ARRAY( SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp = 'email' AND person_id=p.person_id ) AS email",
"CASE
WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
ELSE NULL END
AS photo_url"
],
'resultjoin' => "
JOIN public.tbl_person p USING (person_id)"
];
$config['student'] = [
'primarykey' => 'student_uid',
'table' => 'public.tbl_student',
'searchfields' => [
'uid' => [
'comparison' => 'equals',
'field' => 'student_uid'
],
'vorname' => [
'alias' => ['firstname'],
'comparison' => 'similar',
'field' => 'vorname',
'join' => [
[
'table' => "public.tbl_prestudent",
'using' => "prestudent_id"
],
[
'table' => "public.tbl_person",
'using' => "person_id"
]
]
],
'nachname' => [
'alias' => ['lastname', 'surename'],
'comparison' => 'similar',
'field' => 'nachname',
'join' => [
[
'table' => "public.tbl_prestudent",
'using' => "prestudent_id"
],
[
'table' => "public.tbl_person",
'using' => "person_id"
]
]
],
'name' => [
'comparison' => 'similar',
'field' => "(vorname || ' ' || nachname)",
'join' => [
[
'table' => "public.tbl_prestudent",
'using' => "prestudent_id"
],
[
'table' => "public.tbl_person",
'using' => "person_id"
]
]
],
'email' => [
'comparison' => 'similar',
'field' => 'kontakt',
'join' => [
[
'table' => "public.tbl_prestudent",
'using' => "prestudent_id"
],
[
'table' => "public.tbl_kontakt",
'on' => "kontakttyp = 'email' AND tbl_kontakt.person_id = tbl_prestudent.person_id"
]
],
"1-n" => true
],
'tel' => [
'alias' => ['phone', 'telefon'],
'comparison' => 'similar',
'field' => 'kontakt',
'join' => [
[
'table' => "public.tbl_prestudent",
'using' => "prestudent_id"
],
[
'table' => "public.tbl_kontakt",
'on' => "kontakttyp IN ('telefon', 'so.tel', 'mobil') AND tbl_kontakt.person_id = tbl_prestudent.person_id"
]
],
"1-n" => true
],
'stg' => [
'alias' => ['studiengang'],
'comparison' => 'equals',
'field' => "typ || kurzbz",
'join' => [
[
'table' => "public.tbl_prestudent",
'using' => "prestudent_id"
],
[
'table' => "public.tbl_studiengang",
'on' => "tbl_studiengang.studiengang_kz = tbl_prestudent.studiengang_kz"
]
]
],
'preid' => [
'alias' => ['prestudent_id'],
'comparison' => 'equal-int',
'field' => 'prestudent_id'
],
'pid' => [
'alias' => ['person_id'],
'comparison' => 'equal-int',
'field' => 'person_id',
'join' => [
'table' => "public.tbl_prestudent",
'using' => "prestudent_id"
]
]
],
'resultfields' => [
"s.student_uid AS uid",
"s.matrikelnr",
"p.person_id",
"(p.vorname || ' ' || p.nachname) AS name",
"(s.student_uid || '@" . DOMAIN . "') || ARRAY( SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp = 'email' AND person_id=p.person_id ) AS email",
"CASE
WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
ELSE NULL END
AS photo_url",
"b.aktiv"
],
'resultjoin' => "
JOIN public.tbl_student s USING (student_uid)
JOIN public.tbl_benutzer b ON(b.uid = s.student_uid)
JOIN public.tbl_person p USING(person_id)"
];
$prestudent_sort = [
"Student",
"Incoming",
"Outgoing",
"Diplomand",
"Unterbrecher",
"Aufgenommener",
"Wartender",
"Bewerber",
"Interessent",
"Abgewiesener",
"Absolvent",
"Abbrecher",
"Ausserordentlicher",
"Praktikant"
];
$prestudent_sort_array = "array['" . implode("','", $prestudent_sort) . "']";
$config['prestudent'] = [
'primarykey' => 'prestudent_id',
'table' => 'public.tbl_prestudent',
'searchfields' => [
'uid' => [
'comparison' => 'equals',
'field' => 'student_uid',
'join' => [
'table' => "public.tbl_student",
'using' => "prestudent_id"
]
],
'vorname' => [
'alias' => ['firstname'],
'comparison' => 'similar',
'field' => 'vorname',
'join' => [
'table' => "public.tbl_person",
'using' => "person_id"
]
],
'nachname' => [
'alias' => ['lastname', 'surename'],
'comparison' => 'similar',
'field' => 'nachname',
'join' => [
'table' => "public.tbl_person",
'using' => "person_id"
]
],
'name' => [
'comparison' => 'similar',
'field' => "(vorname || ' ' || nachname)",
'join' => [
'table' => "public.tbl_person",
'using' => "person_id"
]
],
'email' => [
'comparison' => 'similar',
'field' => 'kontakt',
'join' => [
'table' => "public.tbl_kontakt",
'on' => "kontakttyp = 'email' AND tbl_kontakt.person_id = tbl_prestudent.person_id"
],
"1-n" => true
],
'tel' => [
'alias' => ['phone', 'telefon'],
'comparison' => 'similar',
'field' => 'kontakt',
'join' => [
'table' => "public.tbl_kontakt",
'on' => "kontakttyp IN ('telefon', 'so.tel', 'mobil') AND tbl_kontakt.person_id = tbl_prestudent.person_id"
],
"1-n" => true
],
'stg' => [
'alias' => ['studiengang'],
'comparison' => 'equals',
'field' => "typ || kurzbz",
'join' => [
'table' => "public.tbl_studiengang",
'using' => "studiengang_kz"
]
],
'preid' => [
'alias' => ['prestudent_id'],
'comparison' => 'equal-int',
'field' => 'prestudent_id'
],
'pid' => [
'alias' => ['person_id'],
'comparison' => 'equal-int',
'field' => 'person_id',
'join' => [
'table' => "public.tbl_person",
'using' => "person_id"
]
]
],
'resultfields' => [
"ps.prestudent_id",
"ps.studiengang_kz",
"s.matrikelnr",
"p.person_id",
"b.uid",
"(p.vorname || ' ' || p.nachname) AS name",
"(b.uid || '@" . DOMAIN . "') || ARRAY( SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp = 'email' AND person_id=p.person_id ) AS email",
"CASE
WHEN p.foto IS NOT NULL THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
ELSE NULL END
AS photo_url",
"UPPER(sg.typ || sg.kurzbz) AS stg_kuerzel",
"sg.bezeichnung",
"(
SELECT bezeichnung_mehrsprachig[(TABLE lang)]
FROM public.tbl_status
WHERE status_kurzbz = public.get_rolle_prestudent(ps.prestudent_id, NULL)
LIMIT 1
) AS status",
"COALESCE(
(
SELECT COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz)
FROM public.tbl_prestudentstatus pss
LEFT JOIN lehre.tbl_studienplan plan USING (studienplan_id)
WHERE pss.prestudent_id=ps.prestudent_id
ORDER BY pss.datum DESC, pss.insertamum DESC, pss.ext_id DESC
LIMIT 1
),
sg.orgform_kurzbz
) AS orgform",
"b.aktiv",
"array_position(" . $prestudent_sort_array . ", public.get_rolle_prestudent(ps.prestudent_id, NULL)) AS sort"
],
'resultjoin' => "
LEFT JOIN public.tbl_prestudent ps USING (prestudent_id)
LEFT JOIN public.tbl_student s ON (ps.prestudent_id = s.prestudent_id)
LEFT JOIN public.tbl_benutzer b ON (b.uid = s.student_uid)
JOIN public.tbl_person p ON (p.person_id = ps.person_id)
LEFT JOIN public.tbl_studiengang sg ON (sg.studiengang_kz = ps.studiengang_kz)"
];
$config['employee'] = [
'alias' => ['ma', 'mitarbeiter'],
'primarykey' => 'mitarbeiter_uid',
'table' => 'public.tbl_mitarbeiter',
'searchfields' => [
'uid' => [
'alias' => ['mitarbeiter_uid'],
'comparison' => 'equals',
'field' => "mitarbeiter_uid"
],
'vorname' => [
'alias' => ['firstname'],
'comparison' => 'similar',
'field' => "vorname",
'join' => [
[
'table' => "public.tbl_benutzer",
'on' => "uid = mitarbeiter_uid"
],
[
'table' => "public.tbl_person",
'using' => "person_id"
]
]
],
'nachname' => [
'alias' => ['lastname', 'surename'],
'comparison' => 'similar',
'field' => "nachname",
'join' => [
[
'table' => "public.tbl_benutzer",
'on' => "uid = mitarbeiter_uid"
],
[
'table' => "public.tbl_person",
'using' => "person_id"
]
]
],
'name' => [
'comparison' => 'similar',
'field' => "(vorname || ' ' || nachname)",
'join' => [
[
'table' => "public.tbl_benutzer",
'on' => "uid = mitarbeiter_uid"
],
[
'table' => "public.tbl_person",
'using' => "person_id"
]
]
],
'email' => [
'comparison' => 'similar',
'field' => "COALESCE(alias, uid) || '" . '@' . DOMAIN . "'",
'join' => [
'table' => "public.tbl_benutzer",
'on' => "uid = mitarbeiter_uid"
]
],
'tel' => [
'alias' => ['phone', 'telefon'],
'comparison' => 'similar',
'field' => "TRIM(COALESCE(kontakt, '') || ' ' || COALESCE(telefonklappe, ''))",
'join' => [
'table' => "public.tbl_kontakt",
'on' => "kontakttyp = 'telefon' AND tbl_kontakt.standort_id = tbl_mitarbeiter.standort_id"
],
"1-n" => true
],
'pid' => [
'alias' => ['person_id'],
'comparison' => 'equal-int',
'field' => "person_id",
'join' => [
'table' => "public.tbl_benutzer",
'on' => "uid = mitarbeiter_uid"
]
],
'oe' => [
'alias' => ['ou', 'organisationseinheit', 'organisationunit'],
'comparison' => 'vector',
'field' => "fts_bezeichnung",
'join' => [
[
'table' => "public.tbl_benutzerfunktion",
'on' => "mitarbeiter_uid = uid
AND funktion_kurzbz = 'oezuordnung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())"
],
[
'table' => "public.tbl_organisationseinheit",
'using' => "oe_kurzbz"
]
],
'1-n' => true
],
'kst' => [
'comparison' => 'vector',
'field' => "fts_bezeichnung",
'join' => [
[
'table' => "public.tbl_benutzerfunktion",
'on' => "mitarbeiter_uid = uid
AND funktion_kurzbz = 'kstzuordnung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())"
],
[
'table' => "public.tbl_organisationseinheit",
'using' => "oe_kurzbz"
]
],
'1-n' => true
]
],
'resultfields' => [
"b.uid",
"p.person_id",
"(p.vorname || ' ' || p.nachname) AS name",
"ARRAY(
SELECT
'[' || ot.bezeichnung || '] ' || o.bezeichnung AS bezeichnung
FROM public.tbl_benutzerfunktion bf
JOIN public.tbl_organisationseinheit o USING(oe_kurzbz)
JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz)
WHERE bf.funktion_kurzbz = 'oezuordnung'
AND (bf.datum_von IS NULL OR bf.datum_von <= NOW())
AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW())
AND bf.uid = b.uid
GROUP BY o.bezeichnung, ot.bezeichnung
) AS organisationunit_name",
"COALESCE(b.alias, b.uid) || '" . '@' . DOMAIN . "' AS email",
"TRIM(COALESCE(k.kontakt, '') || ' ' || COALESCE(m.telefonklappe, '')) AS phone",
"'" . base_url("/cis/public/bild.php?src=person&person_id=") . "' || p.person_id AS photo_url",
"ARRAY(
SELECT
'[' || ot.bezeichnung || '] ' || o.bezeichnung AS bezeichnung
FROM public.tbl_benutzerfunktion bf
JOIN public.tbl_organisationseinheit o USING(oe_kurzbz)
JOIN public.tbl_organisationseinheittyp ot USING(organisationseinheittyp_kurzbz)
WHERE bf.funktion_kurzbz = 'kstzuordnung'
AND (bf.datum_von IS NULL OR bf.datum_von <= NOW())
AND (bf.datum_bis IS NULL OR bf.datum_bis >= NOW())
AND bf.uid = b.uid
GROUP BY o.bezeichnung, ot.bezeichnung
) AS standardkostenstelle"
],
'resultjoin' => "
JOIN public.tbl_mitarbeiter m USING (mitarbeiter_uid)
JOIN public.tbl_benutzer b ON (b.uid = m.mitarbeiter_uid)
JOIN public.tbl_person p USING(person_id)
LEFT JOIN (
SELECT kontakt, standort_id
FROM public.tbl_kontakt
WHERE kontakttyp = 'telefon'
) k ON (k.standort_id = m.standort_id)"
];
// TODO(chris): move to searchpv21.php
$config['unassigned_employee'] = $config['employee'];
$config['unassigned_employee']['alias'] = ['mitarbeiter_ohne_zuordnung'];
$config['unassigned_employee']['prepare'] = "unassigned_employee AS (
SELECT tbl_mitarbeiter.*
FROM public.tbl_mitarbeiter
LEFT JOIN public.tbl_benutzerfunktion ON (
uid = mitarbeiter_uid
AND funktion_kurzbz = 'kstzuordnung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())
)
WHERE tbl_benutzerfunktion.bezeichnung IS NULL
UNION
SELECT tbl_mitarbeiter.*
FROM public.tbl_mitarbeiter
LEFT JOIN public.tbl_benutzerfunktion ON (
uid = mitarbeiter_uid
AND funktion_kurzbz = 'oezuordnung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())
)
WHERE tbl_benutzerfunktion.bezeichnung IS NULL
)";
$config['unassigned_employee']['table'] = "unassigned_employee";
$config['unassigned_employee']['searchfields']['tel']['join']['on'] = "
kontakttyp = 'telefon'
AND tbl_kontakt.standort_id = unassigned_employee.standort_id
";
$config['unassigned_employee']['renderer'] = 'employee';
$config['organisationunit'] = [
'alias' => ['ou', 'organisationseinheit', 'oe'],
'primarykey' => 'oe_kurzbz',
'table' => 'public.tbl_organisationseinheit',
'searchfields' => [
'uid' => [
'comparison' => 'equals',
'field' => 'uid',
'prepare' => "organisationunit_leader(oe_kurzbz, uid, vorname, nachname) AS (
SELECT oe_kurzbz, vorname, nachname, uid
FROM public.tbl_benutzerfunktion
JOIN public.tbl_benutzer USING (uid)
JOIN public.tbl_person USING (person_id)
WHERE funktion_kurzbz = 'Leitung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())
AND tbl_benutzer.aktiv = TRUE
)",
'join' => [
'table' => "organisationunit_leader",
'using' => "oe_kurzbz"
],
'1-n' => true
],
'vorname' => [
'alias' => ['firstname'],
'comparison' => 'similar',
'field' => 'vorname',
'prepare' => "organisationunit_leader(oe_kurzbz, uid, vorname, nachname) AS (
SELECT oe_kurzbz, vorname, nachname, uid
FROM public.tbl_benutzerfunktion
JOIN public.tbl_benutzer USING (uid)
JOIN public.tbl_person USING (person_id)
WHERE funktion_kurzbz = 'Leitung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())
AND tbl_benutzer.aktiv = TRUE
)",
'join' => [
'table' => "organisationunit_leader",
'using' => "oe_kurzbz"
],
'1-n' => true
],
'nachname' => [
'alias' => ['lastname', 'surename'],
'comparison' => 'similar',
'field' => 'nachname',
'prepare' => "organisationunit_leader(oe_kurzbz, uid, vorname, nachname) AS (
SELECT oe_kurzbz, vorname, nachname, uid
FROM public.tbl_benutzerfunktion
JOIN public.tbl_benutzer USING (uid)
JOIN public.tbl_person USING (person_id)
WHERE funktion_kurzbz = 'Leitung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())
AND tbl_benutzer.aktiv = TRUE
)",
'join' => [
'table' => "organisationunit_leader",
'using' => "oe_kurzbz"
],
'1-n' => true
],
'name' => [
'comparison' => 'similar',
'field' => "(vorname || ' ' || nachname)",
'prepare' => "organisationunit_leader(oe_kurzbz, uid, vorname, nachname) AS (
SELECT oe_kurzbz, vorname, nachname, uid
FROM public.tbl_benutzerfunktion
JOIN public.tbl_benutzer USING (uid)
JOIN public.tbl_person USING (person_id)
WHERE funktion_kurzbz = 'Leitung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())
AND tbl_benutzer.aktiv = TRUE
)",
'join' => [
'table' => "organisationunit_leader",
'using' => "oe_kurzbz"
],
'1-n' => true
],
'oe' => [
'alias' => ['ou', 'organisationseinheit', 'organisationunit'],
'comparison' => 'vector',
'field' => "fts_bezeichnung"
],
'kurzbz' => [
'alias' => ['oe_kurzbz'],
'comparison' => 'equals',
'field' => "oe_kurzbz"
]
],
'resultfields' => [
"oe.oe_kurzbz",
"('[' || type.bezeichnung || '] ' || oe.bezeichnung) AS name",
"oe_parent.oe_kurzbz AS parentoe_kurzbz",
"(CASE WHEN oe_parent.bezeichnung IS NOT NULL THEN '[' || type_parent.bezeichnung || '] ' || oe_parent.bezeichnung END) AS parentoe_name",
"ARRAY(
SELECT JSON_BUILD_OBJECT('uid', b.uid, 'vorname', p.vorname, 'nachname', p.nachname, 'name', (p.vorname || ' ' || p.nachname))
FROM public.tbl_benutzerfunktion bf
JOIN public.tbl_benutzer b USING (uid)
JOIN public.tbl_person p USING (person_id)
WHERE funktion_kurzbz = 'Leitung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())
AND b.aktiv = TRUE
AND oe_kurzbz = oe.oe_kurzbz
) AS leaders",
"(
SELECT COUNT(*)
FROM public.tbl_benutzerfunktion
WHERE funktion_kurzbz = 'oezuordnung'
AND (datum_von IS NULL OR datum_von <= NOW())
AND (datum_bis IS NULL OR datum_bis >= NOW())
AND oe_kurzbz = oe.oe_kurzbz
) AS number_of_people",
"(CASE WHEN oe.mailverteiler THEN oe.oe_kurzbz || '" . '@' . DOMAIN . "' END) AS mailgroup"
],
'resultjoin' => "
JOIN public.tbl_organisationseinheit oe
USING (oe_kurzbz)
JOIN public.tbl_organisationseinheittyp type
USING (organisationseinheittyp_kurzbz)
LEFT JOIN public.tbl_organisationseinheit oe_parent
ON (oe_parent.oe_kurzbz = oe.oe_parent_kurzbz)
LEFT JOIN public.tbl_organisationseinheittyp type_parent
ON (oe_parent.organisationseinheittyp_kurzbz = type_parent.organisationseinheittyp_kurzbz)"
];
$config['room'] = [
'alias' => ['raum'],
'primarykey' => 'ort_kurzbz',
'table' => 'public.tbl_ort',
'searchfields' => [
'name' => [
'comparison' => 'similar',
'field' => 'ort_kurzbz'
]
],
'resultfields' => [
"ort.ort_kurzbz",
"ort.gebteil AS building",
"ort.ausstattung AS equipment",
"ort.stockwerk AS floor",
"ort.dislozierung AS room_number",
"ort.content_id",
"address.ort AS city",
"address.plz AS zip",
"address.strasse AS street",
"ort.max_person",
"ort.arbeitsplaetze AS workplaces"
],
'resultjoin' => "
JOIN public.tbl_ort ort
USING (ort_kurzbz)
LEFT JOIN public.tbl_standort
USING (standort_id)
LEFT JOIN public.tbl_adresse address
USING (adresse_id)"
];
$sprache = getUserLanguage();
$config['cms'] = [
'primarykey' => 'contentsprache_id',
'table' => 'campus.tbl_contentsprache',
'prepare' => "
cms_auth (content_id) AS (
SELECT content_id
FROM campus.tbl_content c
WHERE NOT EXISTS (SELECT 1 FROM campus.tbl_contentgruppe g WHERE g.content_id=c.content_id)
UNION
SELECT content_id
FROM public.vw_gruppen g
JOIN campus.tbl_contentgruppe c USING (gruppe_kurzbz)
WHERE uid = (TABLE auth)
),
cms_active (content_id, template_kurzbz) AS (
SELECT content_id, template_kurzbz
FROM cms_auth
JOIN campus.tbl_content USING (content_id)
WHERE aktiv = TRUE
),
cms_active_redirect (content_id) AS (
SELECT content_id
FROM cms_active
WHERE template_kurzbz = 'redirect'
),
cms_active_redirect_linked (content_id) AS (
SELECT content_id
FROM cms_active_redirect
JOIN campus.tbl_contentsprache USING (content_id)
WHERE LEFT((xpath('string(/content/url)', content))[1]::text, 1) <> '#'
),
cms_active_others (content_id) AS (
SELECT content_id
FROM cms_active
WHERE template_kurzbz IN ('contentmittitel', 'contentohnetitel', 'contentmittitel_filterwidget')
)
",
'searchfields' => [
'content' => [
'alias' => ['inhalt'],
'comparison' => "vector",
'field' => "(
setweight(to_tsvector('simple', COALESCE(titel, '')), 'A')
||
setweight(to_tsvector('simple', COALESCE(content, '')::text), 'B')
)"
],
'content_id' => [
'alias' => ['id'],
'comparison' => "equal-int",
'field' => "content_id"
],
'lang' => [
'alias' => ['language', 'sprache'],
'comparison' => "equals",
'field' => "sprache"
]
],
'resultfields' => [
"contentsprache.content_id",
"content.template_kurzbz",
"contentsprache.version",
"contentsprache.sprache AS language",
"contentsprache.titel AS title",
"contentsprache.content",
"(xpath('string(/content/url)', contentsprache.content))[1] AS content_url"
],
'resultjoin' => "
JOIN campus.tbl_contentsprache contentsprache
USING (contentsprache_id)
JOIN campus.tbl_content content
USING (content_id)
WHERE content_id IN (
SELECT content_id
FROM cms_active_redirect_linked
UNION
SELECT content_id
FROM cms_active_others
)
AND version = campus.get_highest_content_version(content_id)
AND contentsprache.sprache = '{$sprache}'"
];
$config['dms'] = [
'primarykey' => 'dms_id, version',
'table' => 'campus.tbl_dms_version',
'searchfields' => [
'keywords' => [
'alias' => ['keyword', 'keywords', 'schlagwort', 'schlagworte'],
'comparison' => "vector",
'field' => "(to_tsvector('simple', COALESCE(schlagworte, '')))"
]
],
'resultfields' => [
"v.dms_id",
"v.version",
"v.filename",
"v.mimetype",
"v.name",
"v.beschreibung AS description",
"v.schlagworte AS keywords"
],
'resultjoin' => "
JOIN campus.tbl_dms_version v
USING (dms_id, version)
WHERE cis_suche = TRUE
AND version=(SELECT MAX(version) FROM campus.tbl_dms_version WHERE dms_id=v.dms_id)
AND NOT EXISTS (
SELECT
1
FROM
fue.tbl_projekt_dokument p
WHERE p.dms_id = v.dms_id
) AND (
NOT EXISTS (
WITH RECURSIVE categories (kategorie_kurzbz) AS (
SELECT
kategorie_kurzbz
FROM
campus.tbl_dms c
WHERE c.dms_id = v.dms_id
UNION ALL
SELECT
cat.parent_kategorie_kurzbz AS kategorie_kurzbz
FROM
categories
JOIN campus.tbl_dms_kategorie cat USING (kategorie_kurzbz)
)
SELECT
1
FROM
categories
JOIN campus.tbl_dms_kategorie_gruppe USING (kategorie_kurzbz)
UNION
SELECT
1
FROM
categories
JOIN campus.tbl_dms_kategorie USING (kategorie_kurzbz)
WHERE
berechtigung_kurzbz IS NOT NULL
) OR EXISTS (
WITH RECURSIVE categories (kategorie_kurzbz) AS (
SELECT
kategorie_kurzbz
FROM
campus.tbl_dms c
WHERE c.dms_id = v.dms_id
UNION ALL
SELECT
cat.parent_kategorie_kurzbz AS kategorie_kurzbz
FROM
categories
JOIN campus.tbl_dms_kategorie cat USING (kategorie_kurzbz)
)
SELECT
1
FROM
categories
JOIN campus.tbl_dms_kategorie_gruppe USING (kategorie_kurzbz)
JOIN public.tbl_benutzergruppe USING(gruppe_kurzbz)
WHERE
uid = (TABLE auth)
)
)"
];
+48
View File
@@ -0,0 +1,48 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
$CI =& get_instance();
$config['employee'] = $CI->config->item('employee', 'search');
$config['employee']['resultjoin'] = "
JOIN public.tbl_mitarbeiter m USING (mitarbeiter_uid)
JOIN public.tbl_benutzer b ON (b.uid = m.mitarbeiter_uid AND b.aktiv = true)
JOIN public.tbl_person p USING(person_id)
LEFT JOIN (
SELECT kontakt, standort_id
FROM public.tbl_kontakt
WHERE kontakttyp = 'telefon'
) k ON (k.standort_id = m.standort_id)";
$config['student'] = $CI->config->item('student', 'search');
unset($config['student']['searchfields']['email']);
unset($config['student']['searchfields']['tel']);
$config['student']['resultfields'] = [
"s.student_uid AS uid",
"s.matrikelnr",
"p.person_id",
"(p.vorname || ' ' || p.nachname) AS name",
"ARRAY[s.student_uid || '@' || '" . DOMAIN . "'] AS email",
"CASE
WHEN (p.foto_sperre = false AND p.foto IS NOT NULL) THEN 'data:image/jpeg' || CONVERT_FROM(DECODE('3b','hex'), 'UTF8') || 'base64,' || p.foto
ELSE NULL END
AS photo_url",
"b.aktiv"
];
$config['student']['resultjoin'] = "
JOIN public.tbl_student s USING (student_uid)
JOIN public.tbl_benutzer b ON(b.uid = s.student_uid AND b.aktiv = true)
JOIN public.tbl_person p USING(person_id)";
$config['organisationunit'] = $CI->config->item('organisationunit', 'search');
$config['organisationunit']['prepare'] = 'active_organisationseinheit AS (SELECT * FROM public.tbl_organisationseinheit WHERE aktiv = true AND organisationseinheittyp_kurzbz <> \'Container\')';
$config['organisationunit']['table'] = 'active_organisationseinheit';
$config['room'] = $CI->config->item('room', 'search');
$config['cms'] = $CI->config->item('cms', 'search');
$config['dms'] = $CI->config->item('dms', 'search');
+35
View File
@@ -0,0 +1,35 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/*
* TODO: 2025-07-21 ma0080 bare integer comparision results in db error
* if searchstring is numeric but out of range of int, think about
* more sophisticated solution using column data type - quick fix
* convert field and search string to text
*/
$config['equal-int'] = [
'priority' => 4,
'rank' => "0",
'compare' => "{field}::text = {word}::text",
'force_integer' => true
];
$config['equals'] = [
'priority' => 3,
'rank' => "0",
'compare' => "LOWER({field}) = {word}"
];
$config['similar'] = [
'priority' => 2,
'rank' => "(COALESCE({field}, '') <->> {word})",
'compare' => "COALESCE({field}, '') %> {word}",
'compare_boolean' => "COALESCE({field}, '') ILIKE {like:word}"
];
$config['vector'] = [
'priority' => 1,
'rank' => "ts_rank({field}, to_tsquery('simple', {word}))",
'compare' => "to_tsquery('simple', {word}) @@ {field}"
];
+11
View File
@@ -0,0 +1,11 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
$CI =& get_instance();
$config['student'] = $CI->config->item('student', 'search');
$config['prestudent'] = $CI->config->item('prestudent', 'search');
+115
View File
@@ -0,0 +1,115 @@
<?php
$config['number_displayed_past_studiensemester_default'] = 5;
$config['tabs'] =
[
'details' => [
//all fields can be configured to be hidden, see class attribute stv-details-details-name for name
'hiddenFields' => [],
'hideUDFs' => false
],
'prestudent' => [
//all fields can be configured to be hidden, see class attribute stv-details-prestudent-name for name
'hiddenFields' => [
//propably used by FH-Communities
'aufnahmeschluessel', 'standort_code', 'facheinschlaegigBerufstaetig'
],
'hideUDFs' => false
],
'finalexam' => [
'documents' => [
'pruefungsprotokoll' => [
'de' => [
'Bakk' => 'PrProtBA',
'Master' => 'PrProtMA',
],
'en' => [
'Bakk' => 'PrProtBAEng',
'Master' => 'PrProtMAEng',
],
],
'pruefungszeugnis' => [
'de' => [
'Bakk' => 'Bakkzeugnis',
'Master' => 'Diplomzeugnis',
],
'en' => [
'Bakk' => 'BakkzeugnisEng',
'Master' => 'DiplomzeugnisEng',
],
],
'urkunde' => [
'de' => [
'Bakk' => 'Bakkurkunde',
'Master' => 'Diplomurkunde',
],
'en' => [
'Bakk' => 'BakkurkundeEng',
'Master' => 'DiplomurkundeEng',
],
],
],
],
'exemptions' => [
//if true, Anrechnungen can be added and edited in tab Anrechnungen
'editableAnrechnungen' => false,
],
'notes' => [
//if true, the count of Messages will be shown in the header of the Tab Messages
'showCountNotes' => true
]
];
// List of fields to show when ZGV_DOKTOR_ANZEIGEN is defined
$fieldsZgvDoktor = ['zgvdoktorort', 'zgvdoktordatum', 'zgvdoktornation', 'zgvdoktor_erfuellt', 'zgvdoktor_code'];
// List of fields to show when ZGV_ERFUELLT_ANZEIGEN is defined
$fieldsZgvErfuellt = ['zgv_erfuellt', 'zgvmas_erfuellt','zgvdoktor_erfuellt'];
//order important: to show zgf_erfuellt_doktor just in case visibility of doktor is true
if (!defined('ZGV_ERFUELLT_ANZEIGEN') || !ZGV_ERFUELLT_ANZEIGEN) {
$config['tabs']['prestudent']['hiddenFields'] = array_merge(
$config['tabs']['prestudent']['hiddenFields'], $fieldsZgvErfuellt
);
}
if (!defined('ZGV_DOKTOR_ANZEIGEN') || !ZGV_DOKTOR_ANZEIGEN) {
$config['tabs']['prestudent']['hiddenFields'] = array_merge(
$config['tabs']['prestudent']['hiddenFields'],
$fieldsZgvDoktor
);
}
$config['student_tab_order'] = [
'details',
'notes',
'messages',
'contact',
'prestudent',
'status',
'documents',
'archive',
'banking',
'grades',
'exam',
'exemptions',
'finalexam',
'mobility',
'jointstudies',
'admissionDates',
'groups',
'functions',
'coursedates',
'resources',
];
$config['students_tab_order'] = [
'banking',
'status',
'groups',
'finalexam',
'archive',
];
+11
View File
@@ -0,0 +1,11 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// changing the color theme
$config['theme_name']='default';
$config['theme_css']= "public/css/theme/default.css";
$config['theme_logo']= "public/images/logo_fh-complete_300x46.png";
$config['theme_modes']=['light','dark'];
+108
View File
@@ -0,0 +1,108 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Abgabetool extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => self::PERM_LOGGED,
'getStudentProjektarbeitAbgabeFile' => self::PERM_LOGGED,
'Mitarbeiter' => self::PERM_LOGGED,
'Student' => self::PERM_LOGGED,
'Deadlines' => self::PERM_LOGGED
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']);
}
public function Student()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']);
}
public function Mitarbeiter()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolMitarbeiter']);
}
public function Deadlines()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'DeadlinesOverview']);
}
public function getStudentProjektarbeitAbgabeFile()
{
$this->_ci =& get_instance();
$this->_ci->load->helper('download');
$paabgabe_id = $this->_ci->input->get('paabgabe_id');
$student_uid = $this->_ci->input->get('student_uid');
if (!isset($paabgabe_id) || isEmptyString($paabgabe_id) || !isset($student_uid) || isEmptyString($student_uid))
$this->terminateWithJsonError($this->p->t('global', 'wrongParameters'), 'general');
$this->_ci->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$isZugeteilterBetreuer = count($this->_ci->ProjektarbeitModel->checkZuordnung($student_uid, getAuthUID())->retval) > 0;
if(getAuthUID() == $student_uid || $isZugeteilterBetreuer) {
$file_path = PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf';
if(file_exists($file_path)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Disposition: attachment; filename="'.basename($file_path).'"');
header('Content-Length: ' . filesize($file_path));
flush(); // send headers first just in case
readfile($file_path); // read file content to output buffer
} else {
$this->terminateWithJsonError('File not found');
}
} else {
$this->terminateWithJsonError('Keine Zuordnung!');
}
}
}
+2 -1
View File
@@ -72,6 +72,7 @@ class Auth extends FHC_Controller
{
$this->load->library('AuthLib');
$this->authlib->logout();
redirect('/Cis/Auth/login', 'refresh');
setcookie('fhclogout', 'fhclogout', 0, '/');
redirect(base_url('/cis/private/logout.php'), 'refresh');
}
}
@@ -5,7 +5,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Stundenplan extends Auth_Controller
class InfoTerminal extends Auth_Controller
{
/**
* Constructor
@@ -13,7 +13,7 @@ class Stundenplan extends Auth_Controller
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r']
'index' => ['basis/cis:r'],
]);
}
@@ -25,6 +25,6 @@ class Stundenplan extends Auth_Controller
*/
public function index()
{
$this->load->view('Cis/Stundenplan');
$this->load->view('Cis/InfoTerminal.php', []);
}
}
+39
View File
@@ -0,0 +1,39 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class LvPlan extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r']
]);
// Load Config
$this->load->config('calendar');
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$viewData = array(
'uid'=>getAuthUID(),
'timezone' => $this->config->item('timezone')
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'LvPlan']);
}
}
+6 -1
View File
@@ -26,7 +26,12 @@ class MyLv extends Auth_Controller
*/
public function index()
{
$this->load->view('Cis/MyLv');
$viewData = array(
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLv']);
}
public function Info($studien_semester,$lvid)
+39
View File
@@ -0,0 +1,39 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class MyLvPlan extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r']
]);
// Load Config
$this->load->config('calendar');
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$viewData = array(
'uid'=>getAuthUID(),
'timezone' => $this->config->item('timezone')
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLvPlan']);
}
}
+20 -2
View File
@@ -55,7 +55,15 @@ class Profil extends Auth_Controller
*/
public function index()
{
$this->load->view('Cis/Profil');
$this->load->library('ProfilLib');
$profil_data = $this->profillib->getView(getAuthUID());
$profil_data = hasData($profil_data) ? getData($profil_data) : null;
$viewData = array(
'editable'=>true,
'profil_data' => $profil_data,
);
$this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'profilIndex']);
}
/**
@@ -65,7 +73,17 @@ class Profil extends Auth_Controller
*/
public function View($uid)
{
$this->load->view('Cis/Profil');
$this->load->library('ProfilLib');
$profil_data = $this->profillib->getView($uid);
$profil_data = hasData($profil_data) ? getData($profil_data) : null;
$viewData = array (
'uid' => $uid,
'profil_data'=>$profil_data,
);
if($uid == getAuthUID()){
$viewData['editable'] = true;
}
$this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'profilViewUid']);
}
/**
+12 -740
View File
@@ -9,54 +9,21 @@ if (!defined('BASEPATH'))
class ProfilUpdate extends Auth_Controller
{
public static $STATUS_PENDING = NULL;
public static $STATUS_ACCEPTED = NULL;
public static $STATUS_REJECTED = NULL;
public static $TOPICS = [];
public function __construct()
{
parent::__construct([
'index' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'id' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'getProfilUpdateWithPermission' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'acceptProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'denyProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'show' => ['basis/cis:r'],
'insertProfilRequest' => ['basis/cis:rw'],
'updateProfilRequest' => ['basis/cis:rw'],
'deleteProfilRequest' => ['basis/cis:rw'],
'selectProfilRequest' => ['basis/cis:r'],
'insertFile' => ['basis/cis:rw'],
'getProfilRequestFiles' => ['basis/cis:r'],
'getStatus' => ['basis/cis:r'],
'getTopic' => ['basis/cis:r'],
'id' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r']
]);
$this->load->config('cis');
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Adressentyp_model', 'AdressenTypModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->load->model('person/Profil_update_status_model', 'ProfilUpdateStatusModel');
$this->load->model('person/Profil_update_topic_model', 'ProfilUpdateTopicModel');
// Load language phrases
$this->loadPhrases(
array(
'ui',
'global',
'person',
'profil',
'profilUpdate'
)
);
@@ -64,32 +31,10 @@ class ProfilUpdate extends Auth_Controller
$this->load->library('DmsLib');
$this->load->library('PermissionLib');
//? put the uid and pid inside the controller for reusability
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
// setup the ProfilUpdate states
$this->ProfilUpdateStatusModel->addSelect(['status_kurzbz']);
$status_kurzbz = $this->ProfilUpdateStatusModel->load();
if (hasData($status_kurzbz)) {
list($status_pending, $status_accepted, $status_rejected) = getData($status_kurzbz);
self::$STATUS_PENDING = $status_pending->status_kurzbz;
self::$STATUS_ACCEPTED = $status_accepted->status_kurzbz;
self::$STATUS_REJECTED = $status_rejected->status_kurzbz;
}
// setup the ProfilUpdate topics
$this->ProfilUpdateTopicModel->addSelect(['topic_kurzbz']);
$topic_kurzbz = $this->ProfilUpdateTopicModel->load();
if (hasData($topic_kurzbz)) {
foreach (getData($topic_kurzbz) as $topic) {
self::$TOPICS[$topic->topic_kurzbz] = $topic->topic_kurzbz;
}
}
}
public function index()
{
$this->load->view('Cis/ProfilUpdate');
@@ -100,129 +45,14 @@ class ProfilUpdate extends Auth_Controller
$this->load->view('Cis/ProfilUpdate', ['profil_update_id' => $profil_update_id]);
}
public function getStatus()
{
echo json_encode([self::$STATUS_PENDING => self::$STATUS_PENDING, self::$STATUS_ACCEPTED => self::$STATUS_ACCEPTED, self::$STATUS_REJECTED => self::$STATUS_REJECTED]);
}
public function getTopic()
{
echo json_encode(self::$TOPICS);
}
private function sendEmail_onProfilUpdate_response($uid, $topic, $status)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$email = $uid . "@" . DOMAIN;
function languageQuery($language)
{
return "select index from public.tbl_sprache where sprache = '" + $language + "'";
}
$this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]);
$status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]);
if (isError($status_translation)) {
show_error($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError'));
}
$status_translation = hasData($status_translation) ? getData($status_translation)[0] : null;
if (isset($status_translation)) {
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending')));
if (!$mail_res) {
show_error($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
private function sendEmail_onProfilUpdate_insertion($uid, $profil_update_id, $topic)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$emails = [];
$isMitarbeiter_res = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($isMitarbeiter_res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
$isMitarbeiter_res = getData($isMitarbeiter_res);
//! if the $uid is a mitarbeiter and student, only the hr is notified by email
if ($isMitarbeiter_res) {
//? user is not a student therefore he is a mitarbeiter, send email to Personalverwaltung
//? use constant variable MAIL_GST to mail to the personalverwaltung
$this->MitarbeiterModel->addSelect([TRUE]);
$this->MitarbeiterModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid");
//? check if the the userID is a mitarbeiter and if the benutzer is active
$res = $this->MitarbeiterModel->loadWhere(["public.tbl_mitarbeiter.mitarbeiter_uid" => $uid, "public.tbl_benutzer.aktiv" => TRUE]);
if (isError($res)) {
show_error("was not able to query the mitarbeiter and benutzer by the uid: " . $uid);
}
if (hasData($res)) {
array_push($emails, MAIL_GST);
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
} else {
//? if it is not a mitarbeiter, check whether it is a student and send email to studiengang
$isStudent_res = $this->StudentModel->isStudent($uid);
if (isError($isStudent_res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_studentCheck_error'));
}
$isStudent_res = getData($isStudent_res);
if ($isStudent_res) {
//? Send email to the Studiengangsassistentinnen
$this->StudentModel->addSelect(["public.tbl_studiengang.email"]);
$this->StudentModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_student.student_uid");
$this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id");
$this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id");
$this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz");
//* check if the benutzer itself is active
//* check if the student status is Student or Diplomand (active students)
$this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']);
$res = $this->StudentModel->loadWhere(["public.tbl_benutzer.aktiv" => TRUE, "public.tbl_student.student_uid" => $uid]);
if (isError($res)) {
show_error(getData($res));
} else {
$res = hasData($res) ? getData($res) : [];
foreach ($res as $emailObj) {
array_push($emails, $emailObj->email);
}
}
}
}
$mail_res = [];
//? sending email
foreach ($emails as $email) {
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid)));
}
foreach ($mail_res as $m_res) {
if (!$m_res) {
show_error($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
public function show($dms_id)
{
$profil_update = $this->ProfilUpdateModel->loadWhere(['attachment_id' => $dms_id]);
$profil_update = hasData($profil_update) ? getData($profil_update)[0] : null;
//? checks if an profil update exists with the dms_id requested from the user
if ($profil_update) {
if ($profil_update)
{
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($profil_update->uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($profil_update->uid));
@@ -230,7 +60,8 @@ class ProfilUpdate extends Auth_Controller
$this->permissionlib->isBerechtigt('student/stammdaten:r') && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten:r') && $is_mitarbeiter_profil_update ||
$this->uid == $profil_update->uid
) {
)
{
// Get file to be downloaded from DMS
$newFilename = $this->uid . "/document_" . $dms_id;
$download = $this->dmslib->download($dms_id);
@@ -239,576 +70,17 @@ class ProfilUpdate extends Auth_Controller
// Download file
$this->outputFile(getData($download));
} else {
}
else
{
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
return;
}
} else {
}
else
{
show_error($this->p->t('profilUpdate', 'profilUpdate_dms_error'));
return;
}
}
public function insertFile($replace)
{
$replace = json_decode($replace);
if (!count($_FILES)) {
echo json_encode([]);
return;
}
//? if replace is set it contains the profil_update_id in which the attachment_id has to be replaced
if (isset($replace)) {
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$profilUpdate = $this->ProfilUpdateModel->load([$replace]);
if (isError($profilUpdate)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error')));
}
//? get the attachmentID
$dms_id = hasData($profilUpdate) ? getData($profilUpdate)[0]->attachment_id : null;
//? delete old dms_file of Profil Update
$this->deleteOldVersionFile($dms_id);
}
$files = $_FILES['files'];
$file_count = count($files['name']);
$res = [];
for ($i = 0; $i < $file_count; $i++) {
$_FILES['files']['name'] = $files['name'][$i];
$_FILES['files']['type'] = $files['type'][$i];
$_FILES['files']['tmp_name'] = $files['tmp_name'][$i];
$_FILES['files']['error'] = $files['error'][$i];
$_FILES['files']['size'] = $files['size'][$i];
$dms = [
"kategorie_kurzbz" => "profil_aenderung",
"version" => 0,
"name" => $_FILES['files']['name'],
"mimetype" => $_FILES['files']['type'],
"beschreibung" => $this->uid . " Profil Änderung",
"insertvon" => $this->uid,
"insertamum" => "NOW()",
];
$tmp_res = $this->dmslib->upload($dms, 'files', array("jpg", "png", "pdf"));
$tmp_res = hasData($tmp_res) ? getData($tmp_res) : null;
array_push($res, $tmp_res);
}
echo json_encode($res);
}
public function selectProfilRequest()
{
$_GET = json_decode($this->input->raw_input_stream, true);
$uid = $this->input->get('uid');
$id = $this->input->get('id');
$whereClause = ['uid' => $this->uid];
if (isset($uid))
$whereClause['uid'] = $uid;
if (isset($id))
$whereClause['id'] = $id;
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere($whereClause);
$res = hasData($res) ? getData($res) : null;
echo json_encode($res);
}
public function getProfilRequestFiles()
{
$id = json_decode($this->input->raw_input_stream);
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$attachmentID = $this->ProfilUpdateModel->load([$id]);
if (isError($attachmentID)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error')));
}
//? get the attachmentID
$dms_id = hasData($attachmentID) ? getData($attachmentID)[0]->attachment_id : null;
//? get the name to the file
$this->DmsVersionModel->addSelect(["name", "dms_id"]);
$attachment = $this->DmsVersionModel->load([$dms_id, 0]);
if (isError($attachment)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error')));
}
$attachment = hasData($attachment) ? getData($attachment) : null;
//? returns {name:..., dms_id:...}
echo json_encode($attachment);
}
public function insertProfilRequest()
{
$json = json_decode($this->input->raw_input_stream);
$payload = $json->payload;
$identifier = property_exists($json->payload, "kontakt_id") ? "kontakt_id" : (property_exists($json->payload, "adresse_id") ? "adresse_id" : null);
$data = ["topic" => $json->topic, "uid" => $this->uid, "requested_change" => json_encode($payload), "insertamum" => "NOW()", "insertvon" => $this->uid, "status" => self::$STATUS_PENDING ?: 'Pending'];
//? insert fileID in the dataset if sent with post request
if (isset($json->fileID)) {
$data['attachment_id'] = $json->fileID;
}
//? loops over all updateRequests from a user to validate if the new request is valid
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere(["uid" => $this->uid]);
if (isError($res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_loading_error'));
}
$res = hasData($res) ? getData($res) : null;
//? the user cannot delete a zustelladresse/kontakt
if (isset($payload->delete) && $payload->{$identifier == "kontakt_id" ? "zustellung" : "zustelladresse"}) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')));
return;
}
//? if the user tries to delete a adresse, checks whether the adresse is a heimatadresse, if so an error is raised
if (isset($payload->delete) && $identifier == "adresse_id") {
$adr = $this->AdresseModel->load($payload->$identifier);
$adr = getData($adr)[0];
if ($adr->heimatadresse) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')));
return;
}
}
if ($res) {
$pending_changes = array_filter($res, function ($element) {
return $element->status == (self::$STATUS_PENDING ?: "Pending");
});
foreach ($pending_changes as $update_request) {
$existing_change = $update_request->requested_change;
//? the user can add as many new kontakte/adressen as he likes
if (!isset($payload->add) && property_exists($existing_change, $identifier) && property_exists($payload, $identifier) && $existing_change->$identifier == $payload->$identifier) {
//? the kontakt_id / adresse_id of a change has to be unique
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTwice_error')));
return;
}
//? if it is not updating any kontakt/adresse, the topic has to be unique
elseif (!$identifier && $update_request->topic == $json->topic) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTopicTwice_error', ['0' => $update_request->topic])));
return;
}
}
}
$insertID = $this->ProfilUpdateModel->insert($data);
if (isError($insertID)) {
show_error(getData($insertID));
} else {
$insertID = hasData($insertID) ? getData($insertID) : null;
//? sends emails to the correspondents of the $uid
$this->sendEmail_onProfilUpdate_insertion($this->uid, $insertID, $json->topic);
echo json_encode(success($insertID));
}
}
public function updateProfilRequest()
{
$json = json_decode($this->input->raw_input_stream);
$updateData = ["requested_change" => json_encode($json->payload), "updateamum" => "NOW()", "updatevon" => $this->uid];
if (isset($json->fileID)) {
$updateData['attachment_id'] = json_decode($json->fileID);
}
$updateID = $this->ProfilUpdateModel->update([$json->ID], $updateData);
//? insert fileID in the dataset if sent with post request
if (isError($updateID)) {
//catch error
} else {
$updateID = hasData($updateID) ? getData($updateID)[0] : null;
//TODO: should an email be sent to the responsable people when the user changes his profil update
echo json_encode(success($updateID));
}
}
public function deleteProfilRequest()
{
$json = json_decode($this->input->raw_input_stream);
$delete_res = $this->ProfilUpdateModel->delete([$json]);
echo json_encode($delete_res);
}
public function getProfilUpdateWithPermission($status = null)
{
// early return if no status has been passed as argument
if (!isset($status)) {
echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission());
return;
}
// get the sprache of the user
$sprachenIndex = $this->SpracheModel->loadWhere(["sprache" => getUserLanguage()]);
$sprachenIndex = hasData($sprachenIndex) ? getData($sprachenIndex)[0]->index : null;
if (isset($sprachenIndex) && isset($status)) {
// get the corresponding status kurz_bz primary key out of the translation
$status = $this->ProfilUpdateStatusModel->execReadOnlyQuery("select * from public.tbl_profil_update_status where ? = ANY(bezeichnung_mehrsprachig)", [$status]);
$status = hasData($status) ? getData($status)[0]->status_kurzbz : null;
$res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null);
echo json_encode($res);
}
}
private function getOE_from_student($student_uid)
{
//? returns the oe_einheit eines Studenten
$query = "SELECT public.tbl_studiengang.oe_kurzbz
FROM public.tbl_student
JOIN public.tbl_studiengang ON tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
WHERE public.tbl_student.student_uid = ?;";
$res = $this->StudentModel->execReadOnlyQuery($query, [$student_uid]);
if (!isSuccess($res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_loadingOE_error'));
}
$res = hasData($res) ? getData($res) : [];
$res = array_map(
function ($item) {
return $item->oe_kurzbz;
},
$res
);
return $res;
}
public function acceptProfilRequest()
{
$_POST = json_decode($this->input->raw_input_stream, true);
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
//? fetching person_id using UID
$personID = $this->PersonModel->getByUid($uid);
$personID = hasData($personID) ? getData($personID)[0]->person_id : null;
$status_message = $this->input->post('status_message', true);
$topic = $this->input->post('topic', true);
//! somehow the xss check converted boolean false to empty string
$requested_change = $this->input->post('requested_change');
//! check for required information
if (!isset($id) || !isset($uid) || !isset($personID) || !isset($requested_change) || !isset($topic)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_requiredInformation_error')));
}
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($uid));
//? check if the permissions are set correctly
if (
$this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update
) {
if (is_array($requested_change) && array_key_exists("adresse_id", $requested_change)) {
$insertID = $this->handleAdresse($requested_change, $personID);
$insertID = hasData($insertID) ? getData($insertID) : null;
if (isset($insertID)) {
$requested_change['adresse_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_address_error', [$insertID])));
return;
}
}
} else if (is_array($requested_change) && array_key_exists("kontakt_id", $requested_change)) {
$insertID = $this->handleKontakt($requested_change, $personID);
$insertID = hasData($insertID) ? getData($insertID) : null;
if (isset($insertID)) {
$requested_change['kontakt_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_kontakt_error', [$insertID])));
return;
}
}
} else {
switch ($topic) {
// mapping phrasen to database columns to make the update with the correct column names
case self::$TOPICS['Titel']:
$topic = "titelpre";
break;
case self::$TOPICS['Postnomen']:
$topic = "titelpost";
break;
case self::$TOPICS['Vorname']:
$topic = "vorname";
break;
case self::$TOPICS['Nachname']:
$topic = "nachname";
break;
default:
show_error($this->p->t('profilUpdate', 'profilUpdate_topic_error', [$topic]));
return;
}
$result = $this->PersonModel->update($personID, [$topic => $requested_change["value"]]);
if (isError($result)) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_insert_error')));
return;
}
}
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_ACCEPTED);
echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_ACCEPTED, $status_message, $requested_change));
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
}
public function denyProfilRequest()
{
$_POST = json_decode($this->input->raw_input_stream, true);
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
$topic = $this->input->post('topic', true);
$status_message = $this->input->post('status_message', true);
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($uid));
if (
$this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update
) {
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_REJECTED);
echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_REJECTED, $status_message));
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
}
private function updateRequestedChange($id, $requested_change)
{
return $this->ProfilUpdateModel->update([$id], ['requested_change' => json_encode($requested_change)]);
}
private function setStatusOnUpdateRequest($id, $status, $status_message)
{
return $this->ProfilUpdateModel->update([$id], ["status" => $status, "status_timestamp" => "NOW()", "status_message" => $status_message]);
}
private function deleteOldVersionFile($dms_id)
{
if (!isset($dms_id)) {
return;
}
//? collect all the results of the deleted versions in an array
$res = array();
//? delete all the different versions of the dms_file
$dmsVersions = $this->DmsVersionModel->loadWhere(["dms_id" => $dms_id]);
$dmsVersions = hasData($dmsVersions) ? getData($dmsVersions) : null;
if (isset($dmsVersions)) {
$zwischen_res = array_map(function ($item) {
return $item->version;
}, $dmsVersions);
foreach ($zwischen_res as $version) {
array_push($res, $this->DmsVersionModel->delete([$dms_id, $version]));
}
} else {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error')));
}
//? returns a result for each deleted dms_file
return $res;
}
private function handleKontakt($requested_change, $personID)
{
$kontakt_id = $requested_change["kontakt_id"];
//? removes the kontakt_id because we don't want to update the kontakt_id in the database
unset($requested_change["kontakt_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['person_id'] = $personID;
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$insertID = $this->KontaktModel->insert($requested_change);
$insert_kontakt_id = $insertID;
if (isError($insert_kontakt_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_insertKontakt_error'));
}
$insert_kontakt_id = hasData($insert_kontakt_id) ? getData($insert_kontakt_id) : null;
if ($insert_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $insert_kontakt_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$this->KontaktModel->delete($kontakt_id);
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_kontakt_id = $this->KontaktModel->update($kontakt_id, $requested_change);
if (isError($update_kontakt_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_updateKontakt_error'));
}
$update_kontakt_id = hasData($update_kontakt_id) ? getData($update_kontakt_id) : null;
if ($update_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $update_kontakt_id);
}
}
return isset($insertID) ? $insertID : null;
}
private function handleAdresse($requested_change, $personID)
{
$this->AdressenTypModel->addSelect(["adressentyp_kurzbz"]);
$adr_kurzbz = $this->AdressenTypModel->loadWhere(["bezeichnung" => $requested_change['typ']]);
$adr_kurzbz = hasData($adr_kurzbz) ? getData($adr_kurzbz)[0]->adressentyp_kurzbz : null;
//? replace the address_typ with its correct kurzbz foreign key
$requested_change['typ'] = $adr_kurzbz;
$adresse_id = $requested_change["adresse_id"];
//? removes the adresse_id because we don't want to update the kontakt_id in the database
unset($requested_change["adresse_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$requested_change['person_id'] = $personID;
//TODO: zustelladresse, heimatadresse, rechnungsadresse und nation werden nicht beachtet
$insertID = $this->AdresseModel->insert($requested_change);
$insert_adresse_id = $insertID;
if (isError($insert_adresse_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_insertAdresse_error'));
}
$insert_adresse_id = hasData($insert_adresse_id) ? getData($insert_adresse_id) : null;
if ($insert_adresse_id) {
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $insert_adresse_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$this->AdresseModel->delete($adresse_id);
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_adresse_id = $this->AdresseModel->update($adresse_id, $requested_change);
if (isError($update_adresse_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_updateAdresse_error'));
}
$update_adresse_id = hasData($update_adresse_id) ? getData($update_adresse_id) : null;
if ($update_adresse_id) {
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $update_adresse_id);
}
}
return isset($insertID) ? $insertID : null;
}
private function handleDupplicateZustellKontakte($zustellung, $kontakt_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_kontakt.kontakt_id");
$this->PersonModel->addJoin("public.tbl_kontakt", "public.tbl_kontakt.person_id = public.tbl_person.person_id");
$zustellKontakteArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustellung" => TRUE]);
if (!isSuccess($zustellKontakteArray)) {
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellkontakte_error'));
}
$zustellKontakteArray = hasData($zustellKontakteArray) ? getData($zustellKontakteArray) : null;
if ($zustellung && count($zustellKontakteArray) > 0) {
$zustellKontakteArray = array_filter($zustellKontakteArray, function ($kontakt) use ($kontakt_id) {
return $kontakt->kontakt_id != $kontakt_id;
});
foreach ($zustellKontakteArray as $kontakt) {
$this->KontaktModel->update($kontakt->kontakt_id, ["zustellung" => FALSE]);
}
}
}
}
private function handleDupplicateZustellAdressen($zustellung, $adresse_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_adresse.adresse_id");
$this->PersonModel->addJoin("public.tbl_adresse", "public.tbl_adresse.person_id = public.tbl_person.person_id");
$zustellAdressenArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustelladresse" => TRUE]);
if (!isSuccess($zustellAdressenArray)) {
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellAdressen_error'));
}
$zustellAdressenArray = hasData($zustellAdressenArray) ? getData($zustellAdressenArray) : null;
if ($zustellung && count($zustellAdressenArray) > 0) {
$zustellAdressenArray = array_filter($zustellAdressenArray, function ($adresse) use ($adresse_id) {
return $adresse->adresse_id != $adresse_id;
});
foreach ($zustellAdressenArray as $adresse) {
$this->AdresseModel->update($adresse->adresse_id, ["zustelladresse" => FALSE]);
}
}
}
}
}
}
+35
View File
@@ -0,0 +1,35 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Raumsuche extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r']
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Raumsuche']);
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Studium extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r'],
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* index loads the Studium view
* @access public
* @return void
*/
public function index()
{
$viewData = array(
);
$this->load->view('CisRouterView/CisRouterView.php',['viewData' => $viewData, 'route' => 'studium']);
}
}
+8 -4
View File
@@ -17,6 +17,9 @@ class Cis4 extends Auth_Controller
'index' => 'basis/cis:r'
)
);
// Load Config
$this->load->config('calendar');
}
// -----------------------------------------------------------------------------------------------------------------
@@ -27,15 +30,16 @@ class Cis4 extends Auth_Controller
*/
public function index()
{
$this->load->model('person/Person_model','PersonModel');
$this->load->model('person/Person_model', 'PersonModel');
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
$viewData = array(
'uid' => getAuthUID(),
'name' => $personData->vorname,
'person_id' => $personData->person_id
'person_id' => $personData->person_id,
'timezone' => $this->config->item('timezone')
);
$this->load->view('CisVue/Dashboard.php',['viewData' => $viewData]);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'FhcDashboard']);
}
}
}
+20 -46
View File
@@ -60,7 +60,14 @@ class Cms extends Auth_Controller
$content = current($content);
$this->load->view('CisVue/Cms/Content', ['content_id' => $content_id, 'template_kurzbz' => $content->template_kurzbz, 'version' => $version, 'sprache' => $sprache, 'sichtbar' => $sichtbar]);
$viewData = array(
'content_id' => $content_id,
'template_kurzbz' => $content->template_kurzbz,
'version' => $version,
'sichtbar' => $sichtbar
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Content']);
}
/**
@@ -75,53 +82,20 @@ class Cms extends Auth_Controller
* @return void
*/
public function news($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true)
{
$this->load->view('CisVue/Cms/Content', ['infoscreen' => $infoscreen, 'studiengang_kz' => $studiengang_kz, 'semester' => $semester, 'mischen' => $mischen, 'titel' => $titel, 'edit' => $edit, 'sichtbar' => $sichtbar]);
{
$viewData = array();
$this->load->view('CisRouterView/CisRouterView.php', ['viewData'=>$viewData, 'route' => 'News']);
}
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true)
public function getRoomInformation($ort_kurzbz)
{
$get_page = intval($this->input->get('page', true));
$get_page_size = intval($this->input->get('page_size', true));
if ($get_page) {
$page = $get_page;
}
if ($get_page_size) {
$page_size = $get_page_size;
} else {
$page_size = $this->page_size;
}
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size);
// Load Config
$this->load->config('calendar');
if (isError($news)) {
$this->terminateWithJsonError(getError($news));
}
$news = hasData($news) ? getData($news) : null;
if ($news) {
echo json_encode($news);
} else {
show_error("News: No data found");
}
}
public function getNewsRowCount($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $fachbereich_kurzbz = null, $maxalter = 0, $edit = false, $sichtbar = true, $page = 1, $page_size = 10)
{
list($studiengang_kz, $semester) = $this->cmslib->getStgAndSem($studiengang_kz, $semester);
$all = $edit;
$num_rows = $this->NewsModel->countNewsWithContent(getSprache(), $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $this->page_size, $all, $mischen);
if (isError($num_rows)) {
$this->terminateWithJsonError(getError($num_rows));
}
$num_rows = hasData($num_rows) ? getData($num_rows) : null;
if ($num_rows) {
echo json_encode($num_rows);
} else {
show_error("News number rows: No data found");
}
}
public function getRoomInformation($ort_kurzbz){
$this->load->view('CisVue/Cms/RoomInformation',['ort_kurzbz'=>$ort_kurzbz]);
$viewData = array(
'ort_kurzbz' => $ort_kurzbz,
'timezone' => $this->config->item('timezone')
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'CmsRoom']);
}
}
+6 -8
View File
@@ -29,17 +29,15 @@ class Dashboard extends Auth_Controller
{
$this->load->model('person/Person_model','PersonModel');
$begruesung = $this->PersonModel->getFirstName(getAuthUID());
if(isError($begruesung))
{
show_error("name couldn't be loaded for username ".getAuthUID());
}
$begruesung = getData($begruesung);
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
$viewData = array(
'name' => $begruesung
'uid' => getAuthUID(),
'name' => $personData->vorname,
'person_id' => $personData->person_id
);
$this->load->view('CisVue/Dashboard.php', ['viewData' => $viewData]);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData]);
}
}
+294
View File
@@ -0,0 +1,294 @@
<?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 handles output and access to documents.
* It creates a XML file, transforms it with the XSL-FO Vorlage from the
* database and generates a PDF file with unoconv or docsbox.
* This file is then outputted as download.
*
* It is the CodeIgniter version of content/pdfExport.php when not using the
* get paremeters: "archivdokument" and "archive".
* Use exportSigned() instead of providing the "sign" get parameter and
* export() otherwise.
*/
class Documents extends Auth_Controller
{
public function __construct()
{
parent::__construct([
'export' => self::PERM_LOGGED,
'exportSigned' => self::PERM_LOGGED
]);
// Load Phrases
$this->loadPhrases([
'stv'
]);
}
/**
* Download a not signed document.
*
* @param string $xml
* @param string $xsl
*
* @return void
*/
public function export($xml, $xsl)
{
return $this->_export($xml, $xsl);
}
/**
* Download a signed document.
*
* @param string $xml
* @param string $xsl
*
* @return void
*/
public function exportSigned($xml, $xsl)
{
return $this->_export($xml, $xsl, getAuthUID());
}
/**
* Helper function for export() and exportSigned()
*
* @param string $xml
* @param string $xsl
* @param string $sign_user (optional)
*
* @return void
*/
protected function _export($xml, $xsl, $sign_user = null)
{
$xsl_oe_kurzbz = null;
$version = $this->input->post_get('version') ?: null;
// Get the OE or STG of the document
$xsl_oe_kurzbz = $this->input->post_get('xsl_oe_kurzbz')
?: $this->input->post_get('xsl_stg_kz')
?: $this->input->post_get('stg_kz');
if (is_null($xsl_oe_kurzbz)) {
$uid = $this->input->post_get('uid');
if ($uid) {
$uid = current(explode(';', $uid));
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$uid]);
if (!isError($result) && hasData($result))
$xsl_oe_kurzbz = current(getData($result))->studiengang_kz;
}
}
if (is_null($xsl_oe_kurzbz)) {
$prestudent_id = $this->input->post_get('prestudent_id');
if ($prestudent_id) {
$prestudent_id = current(explode(';', $prestudent_id));
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->load($prestudent_id);
if (!isError($result) && hasData($result))
$xsl_oe_kurzbz = current(getData($result))->studiengang_kz;
}
}
if (is_null($xsl_oe_kurzbz))
$xsl_oe_kurzbz = 0;
// Access rights
if ($xsl == 'AccountInfo') {
$this->load->model('resource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$uids = $this->input->post_get('uid');
if ($uids) {
$uids = explode(';', $uids);
foreach ($uids as $uid) {
$result = $this->MitarbeiterModel->load($uid);
if (!isError($result) && hasData($result)) {
if (!$this->permissionlib->isBerechtigt('admin', 'suid', 0)
&& !$this->permissionlib->isBerechtigt('mitarbeiter', 'suid', 0))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'mitarbeiter:rw']]);
} else {
$result = $this->StudentModel->load([$uid]);
if (!isError($result) && hasData($result)) {
$student = current(getData($result));
if (!$this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz)
&& !$this->permissionlib->isBerechtigt('admin', 'suid', 0)
&& !$this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz)
&& !$this->permissionlib->isBerechtigt('assistenz', 'suid', 0)
&& !$this->permissionlib->isBerechtigt('support', 'suid', 0))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw', 'support:rw']]);
}
}
}
}
} else {
$this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel');
$result = $this->VorlagestudiengangModel->getCurrent($xsl, $xsl_oe_kurzbz, $version);
if (isError($result))
return show_error(getError($result));
if (!hasData($result))
return show_404();
$access_rights = current(getData($result))->berechtigung;
if (!$access_rights)
return show_404();
$allowed = false;
foreach ($access_rights as $access_right) {
if ($this->permissionlib->isBerechtigt($access_right)) {
$allowed = true;
break;
}
}
if (!$allowed)
return $this->_outputAuthError([$this->router->method => $access_rights]);
}
// Output format
$outputformat = $this->input->post_get('output') ?: 'pdf';
if ($outputformat != 'pdf'
// An der FHTW darf das Studienblatt und das Prüfungsprotokoll auch in anderen Formaten exportiert werden
&& !(CAMPUS_NAME == 'FH Technikum Wien'
&& ($xsl == 'Studienblatt'
|| $xsl == 'StudienblattEng'
|| $xsl == 'PrProtBA'
|| $xsl == 'PrProtBAEng'
|| $xsl == 'PrProtMA'
|| $xsl == 'PrProtMAEng'
)
)
&& !$this->permissionlib->isBerechtigt('system/change_outputformat', null, $xsl_oe_kurzbz)
) {
$outputformat = 'pdf';
}
// XML Params
$params = 'xmlformat=xml';
foreach ([
'uid',
'stg_kz',
'person_id',
'id',
'prestudent_id',
'buchungsnummern',
'ss',
'abschlusspruefung_id',
'typ',
'all',
'preoutgoing_id',
'lvid',
'projekt_kurzbz',
'von',
'bis',
'stundevon',
'stundebis',
'sem',
'lehreinheit',
'mitarbeiter_uid',
'studienordnung_id',
'fixangestellt',
'standort',
'abrechnungsmonat',
'form',
'projektarbeit_id',
'betreuerart_kurzbz',
'studiensemester_kurzbz'
] as $key) {
$value = $this->input->post_get($key);
if ($value !== null)
$params .= '&' . $key . '=' . urlencode($value);
}
$value = $this->input->post_get('vertrag_id');
if ($value !== null) {
foreach ($value as $id)
$params .= '&vertrag_id[]=' . urlencode($id);
}
$this->load->library('DocumentExportLib');
$this->load->model('system/Vorlage_model', 'VorlageModel');
$result = $this->VorlageModel->load($xsl);
if (isError($result))
return show_error(getError($result));
if (!hasData($result))
show_404();
$vorlage = current(getData($result));
if ($sign_user && !$vorlage->signierbar)
return show_error($this->p->t("stv", "grades_error_sign"));
// Filename
$filename = ($vorlage->bezeichnung ?: $vorlage->vorlage_kurzbz);
switch ($xsl) {
case 'LV_Informationen':
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$result = $this->StudiengangModel->load($this->input->post_get('stg_kz'));
if (!isError($result) && hasData($result))
$filename .= '_' . sanitizeProblemChars(current(getData($result))->kurzbzlang);
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudiensemesterModel->load($this->input->post_get('ss'));
if (!isError($result) && hasData($result))
$filename .= '_' . sanitizeProblemChars(current(getData($result))->studiensemester_kurzbz);
break;
case 'Honorarvertrag':
$uid = str_replace(';', '', $this->input->post_get('uid') ?: '');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->BenutzerModel->addJoin('public.tbl_person', 'person_id', 'LEFT');
$result = $this->BenutzerModel->load([$uid]);
if (!isError($result) && hasData($result)) {
$user = current(getData($result));
$filename .= '_' . sanitizeProblemChars($user->nachname) . '_' . sanitizeProblemChars($user->vorname);
}
break;
case 'Studienordnung':
$filename = 'Studienordnung-Studienplan-';
$this->load->model('organisation/Studienordnung_model', 'StudienordnungModel');
$result = $this->StudienordnungModel->load($this->input->post_get('studienordnung_id'));
if (!isError($result) && hasData($result)) {
$so = current(getData($result));
$filename .= sprintf("%'.04d", $so->studiengang_kz) . '-' . $so->studiengangkurzbzlang;
}
break;
default:
$uid = str_replace(';', '', $this->input->post_get('uid') ?: '');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->BenutzerModel->addJoin('public.tbl_person', 'person_id', 'LEFT');
$result = $this->BenutzerModel->load([$uid]);
if (!isError($result) && hasData($result)) {
$user = current(getData($result));
$filename .= '_' . sanitizeProblemChars($user->nachname);
}
break;
}
// XML Data
$result = $this->documentexportlib->getDataURL($xml, $params);
if (isError($result))
return show_error(getError($result));
$data = getData($result);
// Output
$this->documentexportlib->showContent($filename, $vorlage, $data, $xsl_oe_kurzbz, $version, $outputformat, $sign_user);
}
}
+42
View File
@@ -0,0 +1,42 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class LVVerwaltung extends Auth_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['admin:r', 'assistenz:r'];
parent::__construct($permissions);
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
/**
* @return void
*/
public function _remap()
{
$this->load->view('LVVerwaltung', [
'permissions' => [
'lehre/lehrveranstaltung' => $this->permissionlib->isBerechtigt('lehre/lehrveranstaltung'),
'lv-plan/gruppenentfernen' => $this->permissionlib->isBerechtigt('lv-plan/gruppenentfernen'),
'lv-plan/lektorentfernen' => $this->permissionlib->isBerechtigt('lv-plan/lektorentfernen'),
],
'variables' => [
'semester_aktuell' => $this->variablelib->getVar('semester_aktuell')
],
'configs' => [
'showVertragsdetails' => defined('FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN') && FAS_LV_LEKTORINNENZUTEILUNG_VERTRAGSDETAILS_ANZEIGEN,
'showGewichtung' => defined('CIS_GESAMTNOTE_GEWICHTUNG') && CIS_GESAMTNOTE_GEWICHTUNG,
'lehreinheitAnmerkungDefault' => defined('LEHREINHEIT_ANMERKUNG_DEFAULT') ? LEHREINHEIT_ANMERKUNG_DEFAULT : '',
'lehreinheitRaumtypDefault' => defined('DEFAULT_LEHREINHEIT_RAUMTYP') ? DEFAULT_LEHREINHEIT_RAUMTYP : '',
'lehreinheitRaumtypAlternativeDefault' => defined('DEFAULT_LEHREINHEIT_RAUMTYP_ALTERNATIV') ? DEFAULT_LEHREINHEIT_RAUMTYP_ALTERNATIV : ''
]
]);
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class NeueNachricht extends Auth_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['vertrag/mitarbeiter:r'];
parent::__construct($permissions);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
/**
* @return void
*/
public function _remap()
{
//now working
$this->load->view('Nachrichten', [
'permissions' => [
'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'),
]
]);
}
}
@@ -30,7 +30,8 @@ class Studentenverwaltung extends Auth_Controller
'admin' => $this->permissionlib->isBerechtigt('admin'),
'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'),
'student/keine_studstatuspruefung' => $this->permissionlib->isBerechtigt('student/keine_studstatuspruefung'),
'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht')
'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht'),
'system/change_outputformat' => $this->permissionlib->getOE_isEntitledFor('system/change_outputformat'),
],
'variables' => [
'semester_aktuell' => $this->variablelib->getVar('semester_aktuell')
@@ -0,0 +1,70 @@
<?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');
class AuthInfo extends FHCAPI_Controller
{
protected $uid;
protected $pid;
protected $isMitarbeiter;
protected $isStudent;
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getAuthUID' => self::PERM_LOGGED,
'getAuthInfo' => self::PERM_LOGGED,
]);
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
$this->isMitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter($this->uid)) ?? false;
$this->isStudent = getData($this->StudentModel->isStudent($this->uid)) ?? false;
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* returns the uid of the currently logged in user
* @access public
*
*/
public function getAuthUID()
{
$this->terminateWithSuccess(['uid'=>$this->uid]);
}
public function getAuthInfo()
{
$data = (object) array(
'uid' => $this->uid,
'isMitarbeiter' => $this->isMitarbeiter,
'isStudent' => $this->isStudent
);
$this->terminateWithSuccess($data);
}
}
@@ -30,6 +30,7 @@ class Bookmark extends FHCAPI_Controller
'getBookmarks' => self::PERM_LOGGED,
'delete' => self::PERM_LOGGED,
'insert' => self::PERM_LOGGED,
'update' => self::PERM_LOGGED,
]);
$this->load->model('dashboard/Bookmark_model', 'BookmarkModel');
@@ -50,7 +51,8 @@ class Bookmark extends FHCAPI_Controller
*/
public function getBookmarks()
{
$bookmarks = $this->BookmarkModel->loadWhere(["uid"=>$this->uid]);
$this->BookmarkModel->addOrder("bookmark_id");
$bookmarks = $this->BookmarkModel->loadWhere(["uid"=>$this->uid]);
$bookmarks = $this->getDataOrTerminateWithError($bookmarks);
@@ -104,6 +106,33 @@ class Bookmark extends FHCAPI_Controller
$this->terminateWithSuccess($insert_into_result);
}
/**
* updates bookmark in the bookmark table
* @access public
* @return void
*/
public function update($bookmark_id)
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_rules('url', 'URL', 'required|valid_url|max_length[511]');
$this->form_validation->set_rules('title', 'Title', 'required|max_length[255]');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$url = $this->input->post('url',true);
$title = $this->input->post('title',true);
$now = new DateTime();
$now = $now->format('Y-m-d H:i:s');
$update_result = $this->BookmarkModel->update($bookmark_id,['url'=>$url, 'title'=>$title,'updateamum'=>$now]);
$update_result = $this->getDataOrTerminateWithError($update_result);
$this->terminateWithSuccess($update_result);
}
}
@@ -0,0 +1,58 @@
<?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');
class Cis4FhcApi extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getViewData' => self::PERM_LOGGED,
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* fetches ViewData
*/
public function getViewData()
{
$this->load->model('person/Person_model','PersonModel');
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
$viewData = array(
'uid' => getAuthUID(),
'name' => $personData->vorname,
'person_id' => $personData->person_id
);
$this->terminateWithSuccess($viewData);
}
}
@@ -0,0 +1,58 @@
<?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');
class CisMenu extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getMenu' => self::PERM_LOGGED,
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* fetches the menu for CIS from the database based on the userLanguage
*/
public function getMenu()
{
$this->load->model('content/Content_model', 'ContentModel');
$this->load->config('cis');
$cis4_content_id =$this->config->item('cis_menu_root_content_id');
$result = $this->ContentModel->getMenu($cis4_content_id, getAuthUID(),getUserLanguage());
$result = $this->getDataOrTerminateWithError($result);
$menu = $result->childs ?? [];
$this->terminateWithSuccess($menu);
}
}
+27 -15
View File
@@ -106,7 +106,6 @@ class Cms extends FHCAPI_Controller
$this->terminateWithSuccess($content_id);
}
//todo: there is the method news and getNews but only one should exist
public function news()
{
@@ -125,25 +124,35 @@ class Cms extends FHCAPI_Controller
//get the data or terminate with error
$news = $this->getDataOrTerminateWithError($news);
// array that keeps track of which news don't have a betreff and have to be removed from the news array
$newsToRemove = array();
// collect the content of the news
foreach($news as $news_element){
$this->addMeta("content_id",$news_element->content_id);
foreach($news as $index=>$news_element){
//todo: quick fix, for query builder error when fetching content
$this->NewsModel->resetQuery();
$content = $this->cmslib->getContent($news_element->content_id);
$content = getData($content);
$news_element->content_obj = $content;
if(isError($content))
{
// removes the news from the news array, so that the response does not include a invalid news
array_push($newsToRemove,$index);
//add the error to the api response? visual feedback
//$this->addError(print_r($content->retval,true));
continue;
}
$content = getData($content);
$news_element->content_obj = $content;
}
//removes all news that don't have a betreff
foreach($newsToRemove as $removeNewsIndex)
{
unset($news[$removeNewsIndex]);
}
$withContent = function($news) {
return $news->content_obj != null;
};
};
$newsWithContent = array_filter($news, $withContent);
$this->terminateWithSuccess($newsWithContent);
}
@@ -176,15 +185,18 @@ class Cms extends FHCAPI_Controller
// getting the GET parameters
$page = intval($this->input->get('page', true));
$page_size = intval($this->input->get('page_size', true));
$sprache = $this->input->get('sprache', true);
if(!$sprache)
{
$sprache = getUserLanguage();
}
// default value for the page_size is 10
$page_size = $page_size ?? 10;
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size);
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size, $sprache);
$news = $this->getDataOrTerminateWithError($news);
$this->addMeta('test', $this->p->t('global', 'studiengangsleitung'));
$this->addMeta('phrases', json_decode($this->p->getJson()));
$this->terminateWithSuccess($news);
@@ -0,0 +1,489 @@
<?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 documents
* Listens to ajax post calls to change the documents data
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*
* This controller handles output and access to documents.
* It checks permissions to render documents in an alternative format
* or it creates a XML file, transforms it with the XSL-FO Vorlage from the
* database and generates a PDF file with unoconv or docsbox.
* This file is then archivated in the database.
*
* The last part is the CodeIgniter version of content/pdfExport.php when not
* using the get paremeter: "archivdokument" but using the get parameter:
* "archive".
* Use archiveSigned() instead of providing the "sign" get parameter and
* archive() otherwise.
*/
class Documents extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'permissionAlternativeFormat' => self::PERM_LOGGED,
'archive' => ['admin:rw', 'assistenz:rw'],
'archiveSigned' => ['admin:rw', 'assistenz:rw'],
'download' => ['admin:rw', 'assistenz:rw']
]);
// Load Phrases
$this->loadPhrases([
'stv'
]);
}
/**
* Checks if the current user has permission to render documents in an
* alternative format.
*
* @param string $oe_kurzbz Or studiengang_kz
*
* @return void
*/
public function permissionAlternativeFormat($oe_kurzbz)
{
$this->terminateWithSuccess($this->permissionlib->isBerechtigt('system/change_outputformat', null, $oe_kurzbz));
}
/**
* Archive a not signed document.
*
* @param string $xml (optional)
* @param string $xsl (optional)
*
* @return void
*/
public function archive($xml = null, $xsl = null)
{
return $this->_archive($xml, $xsl);
}
/**
* Archive a signed document.
*
* @param string $xml (optional)
* @param string $xsl (optional)
*
* @return void
*/
public function archiveSigned($xml = null, $xsl = null)
{
return $this->_archive($xml, $xsl, getAuthUID());
}
/**
*
* @return void
*/
public function download($xml, $xsl, $sign_user = null)
{
$akteExportData = $this->_getAkteExportData($xml, $xsl, $sign_user);
$akteData = $akteData['akteData'];
$exportData = $akteData['exportData'];
/**
* [
'vorlage' => $vorlage,
'xml_data' => $data,
'oe_kurzbz' => $xsl_oe_kurzbz,
'version' => $version,
'outputformat' => $outputformat,
'sign_user' => $sign_user
]
*/
// Output
$result = $this->documentexportlib->showContent(
$akteData['akteData']['inhalt'],
$exportData['vorlage'],
$exportData['xml_data'],
$exportData['oe_kurzbz'],
$exportData['version'],
$exportData['outputformat'],
$exportData['sign_user']
);
$this->terminateWithSuccess(true);
}
/**
* Helper function for archive() and archiveSigned()
*
* @param string $xml
* @param string $xsl
* @param string $sign_user (optional)
*
* @return void
*/
private function _archive($xml, $xsl, $sign_user = null)
{
$akteData = $this->_getAkteExportData($xml, $xsl, $sign_user);
$this->load->model('crm/Akte_model', 'AkteModel');
$result = $this->AkteModel->insert($akteData['akteData']);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
}
/**
* @param string $xml
* @param string $xsl
* @param string $sign_user (optional)
*
* @return array with Akte data and export data
*/
private function _getAkteExportData($xml, $xsl, $sign_user = null)
{
if (!$xml || !$xsl) {
$this->load->library('form_validation');
if (!$xml) {
$xml = $this->input->post_get('xml');
$this->addMeta('xml', $xml);
$this->form_validation->set_rules('xml', 'xml', 'required');
}
if (!$xsl) {
$xsl = $this->input->post_get('xsl');
$this->addMeta('xsl', $xsl);
$this->form_validation->set_rules('xsl', 'xsl', 'required');
}
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$xsl_oe_kurzbz = null;
$version = $this->input->post_get('version') ?: null;
// Get the OE or STG of the document
$xsl_oe_kurzbz = $this->input->post_get('xsl_oe_kurzbz')
?: $this->input->post_get('xsl_stg_kz')
?: $this->input->post_get('stg_kz');
if (is_null($xsl_oe_kurzbz)) {
$uid = $this->input->post_get('uid');
if ($uid) {
$uid = current(explode(';', $uid));
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$uid]);
if (!isError($result) && hasData($result))
$xsl_oe_kurzbz = current(getData($result))->studiengang_kz;
}
}
if (is_null($xsl_oe_kurzbz)) {
$prestudent_id = $this->input->post_get('prestudent_id');
if ($prestudent_id) {
$prestudent_id = current(explode(';', $prestudent_id));
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->load($prestudent_id);
if (!isError($result) && hasData($result))
$xsl_oe_kurzbz = current(getData($result))->studiengang_kz;
}
}
if (is_null($xsl_oe_kurzbz))
$xsl_oe_kurzbz = 0;
// Vorlage
$this->load->model('system/Vorlage_model', 'VorlageModel');
$result = $this->VorlageModel->load($xsl);
$this->addMeta("ress", $result);
$vorlage = current($this->getDataOrTerminateWithError($result));
if (!$vorlage)
show_404();
// Akte Data
$akteData = [
'dokument_kurzbz' => $vorlage->dokument_kurzbz ?: 'Zeugnis',
'mimetype' => 'application/pdf',
'erstelltam' => date('Y-m-d'),
'gedruckt' => true,
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
'uid' => $this->input->post_get('uid') ?: '',
'archiv' => true,
'signiert' => !!$sign_user,
'stud_selfservice' => $vorlage->stud_selfservice
];
$studiengang_kz = null;
if ($akteData['uid']) {
$this->load->model('crm/Student_model', 'StudentModel');
$this->StudentModel->addSelect('tbl_student.*, UPPER(typ || kurzbz) AS kuerzel');
$this->StudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT');
$result = $this->StudentModel->load([$akteData['uid']]);
$student = current($this->getDataOrTerminateWithError($result));
$ss = $this->input->post_get('ss');
if ($ss !== null) {
$this->load->model('crm/prestudentstatus_model', 'PrestudentstatusModel');
$result = $this->PrestudentstatusModel->getLastStatus($student->prestudent_id, $ss);
$status = current($this->getDataOrTerminateWithError($result));
if (!$status)
$this->terminateWithError($this->p->t("stv", "grades_error_prestudentstatus"));
$semester = $status->ausbildungssemester;
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->StudentlehrverbandModel->addJoin('public.tbl_benutzer', 'uid = student_uid');
$this->StudentlehrverbandModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$result = $this->StudentlehrverbandModel->load([
'studiensemester_kurzbz' => $ss,
'student_uid' => $akteData['uid']
]);
$res = current($this->getDataOrTerminateWithError($result));
$studiengang_kz = $res->studiengang_kz;
$akteData['person_id'] = $res->person_id;
switch ($xsl) {
case 'Ausbildungsver':
case 'AusbVerEng':
$akteData['titel'] = mb_substr($xsl .
"_" .
strtoupper($res->typ) .
strtoupper($res->kurzbz) .
"_" .
$semester .
"_" .
$ss, 0, 64);
$akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64);
break;
case 'LVZeugnisEng':
case 'LVZeugnis':
case 'Zertifikat':
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->load($this->input->post_get('lvid'));
$lv = current($this->getDataOrTerminateWithError($result));
$akteData['dokument_kurzbz'] = $xsl;
$akteData['titel'] = mb_substr($xsl .
"_" .
strtoupper($res->typ) .
strtoupper($res->kurzbz) .
"_" .
$semester .
'_' .
$ss .
'_' .
str_replace(' ', '_', $lv->bezeichnung), 0, 60);
$akteData['bezeichnung'] = mb_substr($xsl .
" " .
strtoupper($res->typ) .
strtoupper($res->kurzbz) .
" " .
$semester .
". Semester" .
' ' .
$ss .
' ' .
$lv->bezeichnung, 0, 64);
break;
case 'SZeugnis':
$akteData['titel'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64);
$akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64);
break;
default:
$akteData['titel'] = mb_substr($xsl .
"_" .
strtoupper($res->typ) .
strtoupper($res->kurzbz) .
"_" .
$semester .
"_" .
$ss, 0, 64);
$akteData['bezeichnung'] = mb_substr($xsl .
" " .
strtoupper($res->typ) .
strtoupper($res->kurzbz) .
" " .
$semester .
". Semester" .
' ' .
$ss, 0, 64);
break;
}
} else {
$studiengang_kz = $student->studiengang_kz;
$akteData['person_id'] = $student->person_id;
$akteData['titel'] = $vorlage->bezeichnung . '_' . $student->kuerzel;
$akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $student->kuerzel, 0, 64);
}
} else {
$prestudent_id = $this->input->post_get('prestudent_id');
if ($prestudent_id) {
$this->load->model('crm/prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT');
$result = $this->PrestudentModel->load($prestudent_id);
$prestudent = current($this->getDataOrTerminateWithError($result));
$studiengang_kz = $prestudent->studiengang_kz;
$akteData['person_id'] = $prestudent->person_id;
$akteData['titel'] = mb_substr($xsl . "_" . $prestudent->kuerzel, 0, 64);
$akteData['bezeichnung'] = mb_substr($vorlage->bezeichnung . " " . $prestudent->kuerzel, 0, 64);
}
}
// Access rights
if (!$this->permissionlib->isBerechtigt('admin', 'suid', $studiengang_kz)
&& !$this->permissionlib->isBerechtigt('assistenz', 'suid', $studiengang_kz))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
if ($xsl == 'AccountInfo') {
$this->load->model('resource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$uids = $this->input->post_get('uid');
if ($uids) {
$uids = explode(';', $uids);
foreach ($uids as $uid) {
$result = $this->MitarbeiterModel->load($uid);
if (!isError($result) && hasData($result)) {
if (!$this->permissionlib->isBerechtigt('admin', 'suid', 0)
&& !$this->permissionlib->isBerechtigt('mitarbeiter', 'suid', 0))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'mitarbeiter:rw']]);
} else {
$result = $this->StudentModel->load([$uid]);
if (!isError($result) && hasData($result)) {
$student = current(getData($result));
if (!$this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz)
&& !$this->permissionlib->isBerechtigt('admin', 'suid', 0)
&& !$this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz)
&& !$this->permissionlib->isBerechtigt('assistenz', 'suid', 0)
&& !$this->permissionlib->isBerechtigt('support', 'suid', 0))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw', 'support:rw']]);
}
}
}
}
} else {
$this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel');
$result = $this->VorlagestudiengangModel->getCurrent($xsl, $xsl_oe_kurzbz, $version);
$access_rights = current($this->getDataOrTerminateWithError($result));
// TODO: was bedeutet wenn keine berechtigung?
if (!$access_rights || !$access_rights->berechtigung)
return show_404();
$allowed = false;
foreach ($access_rights->berechtigung as $access_right) {
if ($this->permissionlib->isBerechtigt($access_right)) {
$allowed = true;
break;
}
}
if (!$allowed)
return $this->_outputAuthError([$this->router->method => $access_rights]);
}
// Output format
$outputformat = $this->input->post_get('output') ?: 'pdf';
if ($outputformat != 'pdf'
// An der FHTW darf das Studienblatt und das Prüfungsprotokoll auch in anderen Formaten exportiert werden
&& !(CAMPUS_NAME == 'FH Technikum Wien'
&& ($xsl == 'Studienblatt'
|| $xsl == 'StudienblattEng'
|| $xsl == 'PrProtBA'
|| $xsl == 'PrProtBAEng'
|| $xsl == 'PrProtMA'
|| $xsl == 'PrProtMAEng'
)
)
&& !$this->permissionlib->isBerechtigt('system/change_outputformat', null, $xsl_oe_kurzbz)
) {
$outputformat = 'pdf';
}
// XML Params
$params = 'xmlformat=xml';
foreach ([
'uid',
'stg_kz',
'person_id',
'id',
'prestudent_id',
'buchungsnummern',
'ss',
'abschlusspruefung_id',
'typ',
'all',
'preoutgoing_id',
'lvid',
'projekt_kurzbz',
'von',
'bis',
'stundevon',
'stundebis',
'sem',
'lehreinheit',
'mitarbeiter_uid',
'studienordnung_id',
'fixangestellt',
'standort',
'abrechnungsmonat',
'form',
'projektarbeit_id',
'betreuerart_kurzbz',
'studiensemester_kurzbz'
] as $key) {
$value = $this->input->post_get($key);
if ($value !== null)
$params .= '&' . $key . '=' . urlencode($value);
}
$value = $this->input->post_get('vertrag_id');
if ($value !== null) {
foreach ($value as $id)
$params .= '&vertrag_id[]=' . urlencode($id);
}
if (!$vorlage->archivierbar)
$this->terminateWithError($this->p->t("stv", "grades_error_archive"));
if ($sign_user && !$vorlage->signierbar)
$this->terminateWithError($this->p->t("stv", "grades_error_sign"));
$this->load->library('DocumentExportLib');
// XML Data
$result = $this->documentexportlib->getDataURL($xml, $params);
$data = $this->getDataOrTerminateWithError($result);
$this->documentexportlib->addArchiveToData($data);
// Output
$result = $this->documentexportlib->getContent($vorlage, $data, $xsl_oe_kurzbz, $version, $outputformat, $sign_user);
$content = $this->getDataOrTerminateWithError($result);
$akteData['titel'] .= '.pdf';
$akteData['inhalt'] = base64_encode($content);
return [
'akteData' => $akteData,
'exportData' =>
[
'vorlage' => $vorlage,
'xml_data' => $data,
'oe_kurzbz' => $xsl_oe_kurzbz,
'version' => $version,
'outputformat' => $outputformat,
'sign_user' => $sign_user
]
];
}
}
@@ -0,0 +1,47 @@
<?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 languages
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class Language extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'get' => self::PERM_LOGGED
]);
// Load models
$this->load->model('system/Sprache_model', 'SpracheModel');
}
public function get()
{
$this->SpracheModel->addOrder('sprache');
$result = $this->SpracheModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -18,6 +18,14 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
//require_once('../../../include/studiengang.class.php');
//require_once('../../../include/student.class.php');
//require_once('../../../include/datum.class.php');
//require_once('../../../include/mail.class.php');
//require_once('../../../include/benutzerberechtigung.class.php');
//require_once('../../../include/phrasen.class.php');
//require_once('../../../include/projektarbeit.class.php');
//require_once('../../../include/projektbetreuer.class.php');
class Lehre extends FHCAPI_Controller
{
@@ -30,10 +38,34 @@ class Lehre extends FHCAPI_Controller
parent::__construct([
'lvStudentenMail' => self::PERM_LOGGED,
'LV' => self::PERM_LOGGED,
'Pruefungen' => self::PERM_LOGGED,
'getStudentProjektarbeiten' => self::PERM_LOGGED, // TODO: abgabetool berechtigung?
'getStudentProjektabgaben' => self::PERM_LOGGED,
'postStudentProjektarbeitZwischenabgabe' => self::PERM_LOGGED,
'postStudentProjektarbeitEndupload' => self::PERM_LOGGED,
'getMitarbeiterProjektarbeiten' => self::PERM_LOGGED,
'postProjektarbeitAbgabe' => self::PERM_LOGGED,
'deleteProjektarbeitAbgabe' => self::PERM_LOGGED,
'postSerientermin' => self::PERM_LOGGED,
'fetchDeadlines' => self::PERM_LOGGED // TODO: mitarbeiter recht prüfen
]);
$this->load->library('PhrasesLib');
$this->loadPhrases(
array(
'global',
'ui',
'abgabetool'
)
);
$this->load->helper('hlp_sancho_helper');
require_once(FHCPATH . 'include/studiengang.class.php');
require_once(FHCPATH . 'include/student.class.php');
require_once(FHCPATH . 'include/projektarbeit.class.php');
require_once(FHCPATH . 'include/projektbetreuer.class.php');
}
//------------------------------------------------------------------------------------------------------------------
@@ -76,10 +108,574 @@ class Lehre extends FHCAPI_Controller
$this->terminateWithSuccess($result);
}
/**
* fetches all Pruefungen of a student for a specific lehrveranstaltung
* if the student passed the Pruefung on the first attempt, no information about the Pruefungen is stored in the database
* @param mixed $lehrveranstaltung_id
* @return void
*/
public function Pruefungen($lehrveranstaltung_id)
{
$this->load->model('education/Pruefung_model', 'PruefungModel');
$result = $this->PruefungModel->getByStudentAndLv(getAuthUID(), $lehrveranstaltung_id, getUserLanguage());
$result = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
/**
* fetches all projektabgabetermine for a given projektarbeit_id used in cis4 student abgabetool
*/
public function getStudentProjektabgaben() {
$projektarbeit_id = $this->input->get("projektarbeit_id",TRUE);
// TODO: error messages
if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
$projektarbeit_obj = new projektarbeit();
if($projektarbeit_id==-1)
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
if(!$projektarbeit_obj->load($projektarbeit_id))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
$paIsCurrent = $projektarbeit_obj->projektarbeitIsCurrent($projektarbeit_id);
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$ret = $this->ProjektarbeitModel->getProjektarbeitAbgabetermine($projektarbeit_id);
// TODO: fetch zweitbetreuer
$this->terminateWithSuccess(array($ret, $paIsCurrent));
}
/**
* fetches all projektarbeiten and betreuer for a given student_uid used in cis4 student abgabetool
*/
public function getStudentProjektarbeiten($uid)
{
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
if (!isset($uid) || isEmptyString($uid))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
$isZugeteilterBetreuer = count($this->ProjektarbeitModel->checkZuordnung($uid, getAuthUID())->retval) > 0;
$this->addMeta('isZugeteilterBetreuer', $isZugeteilterBetreuer);
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID());
if ($isMitarbeiter && $isZugeteilterBetreuer){
$projektarbeiten = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer($uid);
} else {
$projektarbeiten = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer(getAuthUID());
}
$this->terminateWithSuccess(array($projektarbeiten, DOMAIN, $uid));
}
/**
* projektarbeit - upload for zwischenabgaben in cis4 student abgabetool
*/
public function postStudentProjektarbeitZwischenabgabe()
{
$projektarbeit_id = $_POST['projektarbeit_id'];
$paabgabe_id = $_POST['paabgabe_id'];
$student_uid = $_POST['student_uid'];
$bperson_id = $_POST['bperson_id'];
$paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz'];
if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id)
|| !isset($paabgabe_id) || isEmptyString($paabgabe_id)
|| !isset($student_uid) || isEmptyString($student_uid)
|| !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
if ((isset($_FILES) and isset($_FILES['file']) and ! $_FILES['file']['error'])) {
move_uploaded_file($_FILES['file']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf');
if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf')) {
exec('chmod 640 "'.PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf'.'"');
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$res = $this->PaabgabeModel->update($paabgabe_id, array(
'abgabedatum' => date('Y-m-d'),
'updatevon' => getAuthUID(),
'updateamum' => date('Y-m-d H:i:s')
));
$this->sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid);
$this->terminateWithSuccess($res);
} else {
$this->terminateWithError('Error moving File');
}
} else {
$this->terminateWithError('File missing');
}
}
/**
* upload für finale abgaben aka Endupload in cis4 student abgabetool
*/
public function postStudentProjektarbeitEndupload()
{
$projektarbeit_id = $_POST['projektarbeit_id'];
$paabgabe_id = $_POST['paabgabe_id'];
$student_uid = $_POST['student_uid'];
$sprache = $_POST['sprache'];
$abstract = $_POST['abstract'];
$abstract_en = $_POST['abstract_en'];
$schlagwoerter = $_POST['schlagwoerter'];
$schlagwoerter_en = $_POST['schlagwoerter_en'];
$seitenanzahl = $_POST['seitenanzahl'];
$bperson_id = $_POST['bperson_id'];
$paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz'];
if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id)
|| !isset($paabgabe_id) || isEmptyString($paabgabe_id)
|| !isset($student_uid) || isEmptyString($student_uid)
|| !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
// TODO: maybe check for other params aswell?
if ((isset($_FILES) and isset($_FILES['file']) and ! $_FILES['file']['error'])) {
move_uploaded_file($_FILES['file']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf');
if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf')) {
// Loads Libraries
$this->load->library('SignatureLib');
// Check if the document is signed
$signaturVorhanden = true;
$signList = SignatureLib::list(PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf');
if (is_array($signList) && count($signList) > 0)
{
// The document is signed
$uploadedDocumentSigned = 'The document is signed';
}
elseif ($signList === null)
{
$uploadedDocumentSigned = 'WARNING: signature server error';
}
else
{
$signaturVorhanden = false;
$uploadedDocumentSigned = 'No document signature found';
}
$this->addMeta('signaturInfo', $uploadedDocumentSigned);
if ($signaturVorhanden === false)
{
$this->signaturFehltEmail($student_uid);
}
// TODO error handle get data has data the updates
// update projektarbeit cols
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$this->ProjektarbeitModel->updateProjektarbeit($projektarbeit_id,$sprache,$abstract,$abstract_en
,$schlagwoerter, $schlagwoerter_en, $seitenanzahl);
// update paabgabe datum
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$res = $this->PaabgabeModel->update($paabgabe_id, array(
'abgabedatum' => date('Y-m-d'),
'updatevon' => getAuthUID(),
'updateamum' => date('Y-m-d H:i:s')
));
$this->sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid);
$this->terminateWithSuccess($res);
} else {
$this->terminateWithError('Error moving File');
}
} else {
$this->terminateWithError('File missing');
}
}
private function signaturFehltEmail($student_uid) {
// Mail an Studiengang wenn keine Signatur gefunden wurde
$student = new student();
if(!$student->load($student_uid))
$this->terminateWithError($this->p->t('global','userNichtGefunden'), 'general');
$stg_obj = new studiengang();
if(!$stg_obj->load($student->studiengang_kz))
$this->terminateWithError($this->p->t('global','fehlerBeimLesenAusDatenbank'), 'general');
$subject = 'Abgabe ohne Signatur';
$tomail = $stg_obj->email;
$data = array(
'vorname' => $student->vorname,
'nachname' => $student->nachname,
'studiengang' => $stg_obj->bezeichnung
);
$mailres = sendSanchoMail(
'ParbeitsbeurteilungSiganturFehlt',
$data,
$tomail,
$subject,
'sancho_header_min_bw.jpg',
'sancho_footer_min_bw.jpg'
);
}
private function sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid) {
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$resBetr = $this->ProjektarbeitModel->getProjektbetreuerAnrede($bperson_id);
$projektarbeit_obj = new projektarbeit();
if(!$projektarbeit_obj->load($projektarbeit_id))
$this->terminateWithError('Ungueltiger Eintrag');
$num_rows_sem = $projektarbeit_obj->projektarbeitIsCurrent($projektarbeit_id);
if( null === $num_rows_sem || false === $num_rows_sem )
{
$this->terminateWithError($this->p->t('abgabetool','fehlerAktualitaetProjektarbeit'), 'general');
}
foreach($resBetr->retval as $betreuerRow) {
// query student benutzer view for every betreuer row
$studentUser = $this->ProjektarbeitModel->getProjektarbeitBenutzer($student_uid)->retval[0];
// TODO: hasdata, getData etc
// 1. Begutachter mail ohne Token
$mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter";
$mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$studentUser->uid;
$projekttyp_kurzbz = $projektarbeit_obj->projekttyp_kurzbz;
$subject = $projektarbeit_obj->projekttyp_kurzbz == 'Diplom' ? 'Masterarbeitsbetreuung' : 'Bachelorarbeitsbetreuung';
$abgabetyp = $paabgabetyp_kurzbz == 'end' ? 'Endabgabe' : 'Zwischenabgabe';
$maildata = array();
$maildata['geehrt'] = "geehrte".($betreuerRow->anrede=="Herr"?"r":"");
$maildata['anrede'] = $betreuerRow->anrede;
$maildata['betreuer_voller_name'] = $betreuerRow->first;
$maildata['student_anrede'] = $studentUser->anrede;
$maildata['student_voller_name'] = trim($studentUser->titelpre." ".$studentUser->vorname." ".$studentUser->nachname." ".$studentUser->titelpost);
$maildata['abgabetyp'] = $abgabetyp;
$maildata['parbeituebersichtlink'] = "<p><a href='".APP_ROOT."cis/private/lehre/abgabe_lektor_frameset.html'>Zur Projektarbeitsübersicht</a></p>";
$maildata['bewertunglink'] = $num_rows_sem >= 1 && $paabgabetyp_kurzbz == 'end' ? "<p><a href='$mail_fulllink'>Zur Beurteilung der Arbeit</a></p>" : "";
$maildata['token'] = "";
$mailres = sendSanchoMail(
'ParbeitsbeurteilungEndupload',
$maildata,
$betreuerRow->mitarbeiter_uid."@".DOMAIN,
$subject,
'sancho_header_min_bw.jpg',
'sancho_footer_min_bw.jpg',
get_uid()."@".DOMAIN);
if(!$mailres)
{
$this->terminateWithError($this->p->t('abgabetool', 'fehlerMailBegutachter'), 'general');
}
// 2. Begutachter mail, wenn Endabgabe, mit Token wenn extern
if ($paabgabetyp_kurzbz == 'end')
{
// Zweitbegutachter holen
$zweitbegutachter = new projektbetreuer();
$zweitbegutachterRes = $zweitbegutachter->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $studentUser->uid);
if ($zweitbegutachterRes)
{
$zweitbegutachterResults = $zweitbegutachter->result;
foreach ($zweitbegutachterResults as $begutachter)
{
// token generieren, wenn noch nicht vorhanden und notwendig (wird in methode überprüft)
$tokenGenRes = $zweitbegutachter->generateZweitbegutachterToken($begutachter->person_id, $projektarbeit_id);
if (!$tokenGenRes)
{
$this->terminateWithError($this->p->t('abgabetool', 'fehlerMailZweitBegutachter'), 'general');
}
// Zweitbegutachter (evtl. mit Token) holen
$zweitbegutachterMitToken = new projektbetreuer();
$begutachterMitTokenRes = $zweitbegutachterMitToken->getZweitbegutachterWithToken($bperson_id, $projektarbeit_id, $studentUser->uid, $begutachter->person_id);
if (!$begutachterMitTokenRes)
{
$this->terminateWithError($this->p->t('abgabetool', 'fehlerMailZweitBegutachter'), 'general');
}
// Email an Zweitbegutachter senden
if (isset($zweitbegutachterMitToken->result[0]))
{
$begutachterMitToken = $zweitbegutachterMitToken->result[0];
$path = $begutachterMitToken->betreuerart_kurzbz == 'Zweitbegutachter' ? 'ProjektarbeitsbeurteilungZweitbegutachter' : 'ProjektarbeitsbeurteilungErstbegutachter';
$mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/$path";
$mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$studentUser->uid;
$intern = isset($begutachterMitToken->uid);
$mail_link = $intern ? $mail_fulllink : $mail_baselink;
$zweitbetmaildata = array();
$zweitbetmaildata['geehrt'] = "geehrte" . ($begutachterMitToken->anrede == "Herr" ? "r" : "");
$zweitbetmaildata['anrede'] = $begutachterMitToken->anrede;
$zweitbetmaildata['betreuer_voller_name'] = $begutachterMitToken->voller_name;
$zweitbetmaildata['student_anrede'] = $maildata['student_anrede'];
$zweitbetmaildata['student_voller_name'] = $maildata['student_voller_name'];
$zweitbetmaildata['abgabetyp'] = $abgabetyp;
$zweitbetmaildata['parbeituebersichtlink'] = $intern ? $maildata['parbeituebersichtlink'] : "";
$zweitbetmaildata['bewertunglink'] = $num_rows_sem >= 1 ? "<p><a href='$mail_link'>Zur Beurteilung der Arbeit</a></p>" : "";
$zweitbetmaildata['token'] = $num_rows_sem >= 1 && isset($begutachterMitToken->zugangstoken) && !$intern ? "<p>Zugangstoken: " . $begutachterMitToken->zugangstoken . "</p>" : "";
$mailres = sendSanchoMail(
'ParbeitsbeurteilungEndupload',
$zweitbetmaildata,
$begutachterMitToken->email,
$subject,
'sancho_header_min_bw.jpg',
'sancho_footer_min_bw.jpg',
get_uid()."@".DOMAIN
);
if (!$mailres)
{
$this->terminateWithError($this->p->t('abgabetool', 'fehlerMailBegutachter'), 'general');
}
}
}
}
}
}
}
public function getMitarbeiterProjektarbeiten() {
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$boolParamStr = $this->input->get('showall');
$trueStrings = ['true', '1'];
$falseStrings = ['false', '0'];
// Handle missing or invalid parameter
if ($boolParamStr === null) {
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
}
$boolParamStrLower = strtolower($boolParamStr);
if (in_array($boolParamStrLower, $trueStrings, true)) {
$showAllBool = true;
} elseif (in_array($boolParamStrLower, $falseStrings, true)) {
$showAllBool = false;
} else {
// $this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
}
$projektarbeiten = $this->ProjektarbeitModel->getMitarbeiterProjektarbeiten(getAuthUID(), $showAllBool);
$this->terminateWithSuccess(array($projektarbeiten, DOMAIN));
}
public function postProjektarbeitAbgabe() {
$projektarbeit_id = $_POST['projektarbeit_id'];
$paabgabe_id = $_POST['paabgabe_id'];
$paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz'];
$datum = $_POST['datum'];
$fixtermin = $_POST['fixtermin'];
$kurzbz = $_POST['kurzbz'];
if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id)
|| !isset($paabgabe_id) || isEmptyString($paabgabe_id)
|| !isset($datum) || isEmptyString($datum)
|| !isset($datum) || isEmptyString($datum)
|| !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
if($paabgabe_id == -1) {
$result = $this->PaabgabeModel->insert(
array(
'projektarbeit_id' => $projektarbeit_id,
'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz,
'fixtermin' => $fixtermin,
'datum' => $datum,
'kurzbz' => $kurzbz,
'insertvon' => getAuthUID(),
'insertamum' => date('Y-m-d H:i:s')
)
);
$this->terminateWithSuccess($result);
} else {
$result = $this->PaabgabeModel->update(
$paabgabe_id,
array(
'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz,
'datum' => $datum,
'kurzbz' => $kurzbz,
'updatevon' => getAuthUID(),
'updateamum' => date('Y-m-d H:i:s')
)
);
$this->terminateWithSuccess($result);
}
}
public function deleteProjektarbeitAbgabe() {
$paabgabe_id = $_POST['paabgabe_id'];
if (!isset($paabgabe_id) || isEmptyString($paabgabe_id))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$result = $this->PaabgabeModel->load($paabgabe_id);
$result = $this->getDataOrTerminateWithError($result);
if(count($result) == 0)
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
// TODO: berechtigung?
if($result[0]->insertvon === getAuthUID()) {
$result = $this->PaabgabeModel->delete($paabgabe_id);
$result = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
}
/**
* endpoint for adding the same paabgabe for multiple projektarbeiten
* can be slow for large n since it queries twice per projektarbeit_id
*/
public function postSerientermin() {
$projektarbeit_ids = $_POST['projektarbeit_ids'];
$datum = $_POST['datum'];
$paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz'];
$bezeichnung = $_POST['bezeichnung'];
$kurzbz = $_POST['kurzbz'];
if (!isset($projektarbeit_ids) || !is_array($projektarbeit_ids) || empty($projektarbeit_ids)
|| !isset($datum) || isEmptyString($datum)
|| !isset($kurzbz) || isEmptyString($kurzbz)
|| !isset($bezeichnung) || isEmptyString($bezeichnung)
|| !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
// old script checks if there already are tbl_paabgabe entries with exact date, type & kurzbz
// for each termin - good to check that in principle but should not matter in this place. if necessary
// duplicate abgabetermine can be easily deleted manually, also via cronjob@night.
// since this entry includes the kurzbz string match, it should have only ever mattered when there were
// multiple users entering the exact same set of (date, type, kurzbz) - which is a much more narrow case than the
// general "saveMultiple" function should handle
// old script afterwards again queries if user is not the zweitbetreuer of any id - this is blocked in the ui
// and should never unintentionally happen
// TODO: check berechtigung &/|| zuordnung?
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$res = [];
foreach ($projektarbeit_ids as $projektarbeit_id) {
$result = $this->PaabgabeModel->insert(
array(
'projektarbeit_id' => $projektarbeit_id,
'paabgabetyp_kurzbz' => $paabgabetyp_kurzbz,
'fixtermin' => false,
'datum' => $datum,
'kurzbz' => $kurzbz,
'insertvon' => getAuthUID(),
'insertamum' => date('Y-m-d H:i:s')
)
);
$data = $this->getDataOrTerminateWithError($result);
// $res[] = $data;
// send mail to student
$result = $this->ProjektarbeitModel->getStudentInfoForProjektarbeitId($projektarbeit_id);
$data = $this->getDataOrTerminateWithError($result);
// $this->addMeta('emaildata'.$projektarbeit_id, $data);
$datetime = new DateTime($datum);
$dateEmailFormatted = $datetime->format('d.m.Y');
$anredeFillString = $data[0]->anrede=="Herr"?"r":"";
$fullFormattedNameString = trim($data[0]->titelpre." ".$data[0]->vorname." ".$data[0]->nachname." ".$data[0]->titelpost);
$res[] = $fullFormattedNameString;
// Prepare mail content
$body_fields = array(
'anrede' => $data[0]->anrede,
'anredeFillString' => $anredeFillString,
'datum' => $dateEmailFormatted,
'bezeichnung' => $bezeichnung,
'fullFormattedNameString' => $fullFormattedNameString,
'kurzbz' => $kurzbz
);
$email = $data[0]->uid."@".DOMAIN;
sendSanchoMail(
'neuerAbgabetermin',
$body_fields,
$email,
$this->p->t('abgabetool', 'neuerTerminBachelorMasterbetreuung')
);
}
$this->terminateWithSuccess($res);
}
public function fetchDeadlines() {
$person_id = $_POST['person_id'];
if (!isset($person_id) || isEmptyString($person_id))
$person_id = getAuthPersonId();
if($person_id !== getAuthPersonId()) {
$this->load->library('PermissionLib');
$isAdmin = $this->permissionlib->isBerechtigt('admin');
if(!$isAdmin) $this->terminateWithError($this->p->t('ui', 'keineBerechtigung'), 'general');
}
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$result = $this->PaabgabeModel->getDeadlines($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,265 @@
<?php
/**
* Copyright (C) 2025 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');
class Lehrveranstaltung extends FHCAPI_Controller
{
private $_ci;
private $_uid;
public function __construct()
{
parent::__construct([
'getByEmp' => ['admin:r', 'assistenz:r'],
'getByStg' => ['admin:r', 'assistenz:r'],
'loadByLV' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
$this->loadPhrases(
array(
'ui'
)
);
}
public function getByEmp($studiensemester_kurzbz = null, $mitarbeiter_uid = null, $stg_kz = null)
{
if (is_null($mitarbeiter_uid))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$lehrveranstaltungen = $this->_ci->LehreinheitModel->getLvsByEmployee($mitarbeiter_uid, $studiensemester_kurzbz, $stg_kz);
$lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen);
$tree = [];
foreach ($lehrveranstaltungen_data as $lehrveranstaltung)
{
$lehreinheiten = $this->_ci->LehreinheitModel->getByLvidStudiensemester($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz, $mitarbeiter_uid);
$lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten);
if (!isset($lehrveranstaltung->_children))
{
$lehrveranstaltung->_children = $lehreinheiten_data;
}
$tree[] = $lehrveranstaltung;
}
$this->terminateWithSuccess($tree);
}
public function getByStg($studiensemester_kurzbz = null, $studiengang_kz = null, $semester = null)
{
if (is_null($studiengang_kz) || !preg_match("/^-?[1-9][0-9]*$/", (string)$studiengang_kz))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$verband = null;
if (!is_null($semester) && !is_numeric($semester))
{
$verband = $semester;
$semester = null;
}
$this->_ci->load->model('organisation/Studienplan_model', 'StudienplanModel');
$studiensemester_kurzbz = $this->getStudiensemesterKurzbz($studiensemester_kurzbz);
$studienplan_data = $this->_ci->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $semester, $verband);
$studienplan_ids = array();
$only_ids = array();
$placeholders = array();
if (hasData($studienplan_data))
{
foreach (getData($studienplan_data) as $studienplan) {
$placeholders[] = "(?, ?)";
$studienplan_ids[] = $studienplan->studienplan_id;
$studienplan_ids[] = $studienplan->semester;
$only_ids[] = $studienplan->studienplan_id;
}
}
$lehrveranstaltungen_data = $this->_ci->LehrveranstaltungModel->getLvsByStudiengang($studienplan_ids, $placeholders, $only_ids, $studiengang_kz, $studiensemester_kurzbz, $semester, $verband);
$lehrveranstaltungen_data = hasData($lehrveranstaltungen_data) ? getData($lehrveranstaltungen_data) : array();
$tree = [];
foreach ($lehrveranstaltungen_data as $row)
{
$rowData = $row;
$lehreinheiten_data = $this->_ci->LehreinheitModel->getByLvidStudiensemester($row->lehrveranstaltung_id, $studiensemester_kurzbz);
if (hasData($lehreinheiten_data))
{
$lehreinheiten = getData($lehreinheiten_data);
$rowData->_children = $lehreinheiten;
}
if (!isEmptyString($row->studienplan_lehrveranstaltung_id_parent))
{
$child = $this->_ci->StudienplanModel->loadStudienplanLehrveranstaltung($row->studienplan_lehrveranstaltung_id_parent);
if (hasData($child))
{
$child = getData($child)[0];
$searchId = $child->lehrveranstaltung_id;
foreach ($lehrveranstaltungen_data as &$searchParent)
{
if ($searchParent->lehrveranstaltung_id === $searchId)
{
if (!isset($searchParent->_children))
{
$searchParent->_children = [];
}
if (is_array($searchParent->_children))
{
$searchParent->_children[] = $row;
}
else
{
$searchParent->_children = [$searchParent->_children, $row];
}
break;
}
}
}
}
else
{
$tree[] = $rowData;
}
}
$counter = 0;
$this->assignUniqueIndex($tree, $counter);
$this->terminateWithSuccess($tree);
}
public function loadByLV($lehrveranstaltung_id = null)
{
if (is_null($lehrveranstaltung_id) || !ctype_digit((string)$lehrveranstaltung_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->_ci->LehrveranstaltungModel->addSelect('lehrveranstaltung_id, lehrform_kurzbz, lehre, bezeichnung as lvbezeichnung, sprache');
$lehrveranstaltung_result = $this->_ci->LehrveranstaltungModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung_id));
$lehrveranstaltung_result = $this->getDataOrTerminateWithError($lehrveranstaltung_result);
$lehrveranstaltung = $lehrveranstaltung_result[0];
$this->_ci->LehreinheitModel->addSelect('lehrveranstaltung_id_kompatibel');
$this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung_kompatibel', 'lehrveranstaltung_id');
$lehrfaecher = $this->_ci->LehreinheitModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung->lehrveranstaltung_id));
$lehrfaecher_array = [];
if (hasData($lehrfaecher))
$lehrfaecher_array = array_merge($lehrfaecher_array, array_column(getData($lehrfaecher), 'lehrveranstaltung_id_kompatibel'));
$lehrfaecher_array[] = $lehrveranstaltung->lehrveranstaltung_id;
$this->_ci->LehrveranstaltungModel->addDistinct('lehrfach_id');
$this->_ci->LehrveranstaltungModel->addSelect("tbl_lehrveranstaltung.lehrveranstaltung_id, CONCAT(tbl_lehrveranstaltung.bezeichnung || '(' || tbl_lehrveranstaltung.oe_kurzbz || ')') as lehrfach");
$this->_ci->LehrveranstaltungModel->db->where_in('tbl_lehrveranstaltung.lehrveranstaltung_id', $lehrfaecher_array);
$lehrfaecher_result = $this->_ci->LehrveranstaltungModel->load();
$lehrfaecher_array = hasData($lehrfaecher_result) ? getData($lehrfaecher_result) : array();
$lehrveranstaltung->lehrfaecher = $lehrfaecher_array;
$this->terminateWithSuccess($lehrveranstaltung);
}
/*
* (david) ggf. im naechsten release
* public function loadByOrganization($oe_kurzbz)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$lehrveranstaltungen = $this->LehrveranstaltungModel->getLvsByOrganization($oe_kurzbz);
$lehrveranstaltungen_data = $this->getDataOrTerminateWithError($lehrveranstaltungen);
$tree = [];
foreach ($lehrveranstaltungen_data as $lehrveranstaltung)
{
$lehreinheiten = $this->LehreinheitModel->getByLvidStudiensemester($lehrveranstaltung->lehrveranstaltung_id, $studiensemester_kurzbz);
$lehreinheiten_data = $this->getDataOrTerminateWithError($lehreinheiten);
if (!isset($lehrveranstaltung->_children))
{
$lehrveranstaltung->_children = $lehreinheiten_data;
}
$tree[] = $lehrveranstaltung;
}
$this->terminateWithSuccess($tree);
}*/
/*public function loadByFachbereich($fachbereich, $mitarbeiter_uid = null)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->LehreinheitModel->getLvsByFachbereich($fachbereich, $studiensemester_kurzbz, $mitarbeiter_uid);
}*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
private function assignUniqueIndex(&$nodes, &$counter)
{
foreach ($nodes as &$node)
{
$node->uniqueindex = $counter++;
if (!empty($node->_children) && is_array($node->_children))
{
$this->assignUniqueIndex($node->_children, $counter);
}
}
}
private function getStudiensemesterKurzbz($studiensemester_kurzbz = null)
{
if (!is_null($studiensemester_kurzbz))
{
$studiensemester_result = $this->_ci->StudiensemesterModel->load($studiensemester_kurzbz);
if (isError($studiensemester_result) || !hasData($studiensemester_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
return getData($studiensemester_result)[0]->studiensemester_kurzbz;
}
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
}
}
@@ -51,13 +51,29 @@ class LvMenu extends FHCAPI_Controller
$this->load->library("PermissionLib", null, 'PermissionLib');
$this->load->library("PhrasesLib");
$this->load->library("PhrasesLib", null, 'PhrasesLib');
$this->loadPhrases(array('global', 'lehre'));
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* alternative function to get multiple lvMenus with a single http request
*/
public function getMultipleLvMenu($lvMenuOptionList){
$result =[];
foreach($lvMenuOptionList as $lvMenuOptions){
$lvMenu = $this->getLvMenu($lvMenuOptions['lvid'],$lvMenuOptions['studiensemester_kurzbz']);
if(isError($lvMenu)){
// TODO: some lvMenu threw an error, handle error here
}
$result[$lvMenuOptions['lvid']]=$lvMenu;
}
$this->terminateWithSuccess($result);
}
/**
*
*/
@@ -91,20 +107,24 @@ class LvMenu extends FHCAPI_Controller
$lvres = $this->Lehrveranstaltung_model->load($lvid);
if(!hasData($lvres))
{
$this->terminateWithError('LV ' . $lvid . ' not found.');
$this->terminateWithError('LV ' . $lvid . ' not found.');
}
$lv = (getData($lvres))[0];
$this->addMeta('lvInfo',$lv);
// define studiengang_kz / semester / lehrverzeichnis
$studiengang_kz = $lv->studiengang_kz;
$semester = $lv->semester;
$short = $lv->lehreverzeichnis;
// return empty menu for studiengang_kz = 0
if($studiengang_kz == 0){
$this->terminateWithSuccess("organisatorische_einheit");
}
// load studiengang
$stgres = $this->Studiengang_model->load($lv->studiengang_kz);
$stgres = $this->Studiengang_model->load(strval($studiengang_kz));
if(!hasData($stgres))
{
$this->terminateWithError('Stg ' . $lv->studiengang_kz . ' nof found.');
$this->terminateWithError('Stg ' . $lv->studiengang_kz . ' not found.');
}
$stg = (getData($stgres))[0];
$kurzbz = strtoupper($stg->typ . $stg->kurzbz);
@@ -249,6 +269,8 @@ class LvMenu extends FHCAPI_Controller
'lehrfach_id'=>$lehrfach_id,
'lektor_der_lv'=>$lektor_der_lv,
'lehrfach_oe_kurzbz_arr'=>$lehrfach_oe_kurzbz_arr,
'permissionLib' => &$this->PermissionLib,
'phrasesLib' => &$this->PhrasesLib
];
Events::trigger('lvMenuBuild',
@@ -284,24 +306,6 @@ class LvMenu extends FHCAPI_Controller
}
private function fhc_menu_digitale_anwesenheiten(&$menu, $angemeldet, $studiengang_kz, $semester, $lvid, $angezeigtes_stsem){
// DIGITALE ANWESENHEITEN
if (defined('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN && $angemeldet) {
$menu[] = array
(
'id' => 'core_menu_digitale_anwesenheitslisten',
'position' => '50',
'name' => $this->p->t('lehre', 'digiAnw'),
'c4_icon' => base_url('skin/images/button_kreuzerltool.png'),
'c4_link' => base_url("index.ci.php/extensions/FHC-Core-Anwesenheiten/?stg_kz=$studiengang_kz&sem=$semester&lvid=$lvid&sem_kurzbz=$angezeigtes_stsem&nav=false"),
'c4_linkList' => []
);
}
}
private function fhc_menu_lvinfo(&$menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr){
// LVINFO
@@ -329,6 +333,7 @@ class LvMenu extends FHCAPI_Controller
'id'=>'core_menu_lvinfo',
'position'=>'10',
'name'=>$this->p->t('lehre', 'lehrveranstaltungsinformation'),
'phrase' => 'lehre/lehrveranstaltungsinformation',
'icon'=>'../../../skin/images/button_lvinfo.png',
'link'=>'',
'c4_icon'=> base_url('skin/images/button_lvinfo.png'),
@@ -347,6 +352,7 @@ class LvMenu extends FHCAPI_Controller
'id'=>'core_menu_feedback',
'position'=>'60',
'name'=>$this->p->t('lehre', 'feedback'),
'phrase' => 'lehre/feedback',
'c4_icon'=> base_url('skin/images/button_feedback.png'),
'c4_link'=> base_url('feedback.php?lvid='.$lvid),
);
@@ -364,6 +370,7 @@ class LvMenu extends FHCAPI_Controller
'id'=>'core_menu_gesamtnote',
'position'=>'80',
'name'=>$this->p->t('lehre', 'gesamtnote'),
'phrase' => 'lehre/gesamtnote',
'c4_icon'=> base_url('skin/images/button_endnote.png'),
'c4_link'=> base_url('cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
//'c4_link'=> base_url('benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
@@ -376,6 +383,7 @@ class LvMenu extends FHCAPI_Controller
'id'=>'core_menu_gesamtnote',
'position'=>'80',
'name'=>$this->p->t('lehre', 'gesamtnote'),
'phrase'=>'lehre/gesamtnote',
'c4_icon'=>base_url('skin/images/button_endnote.png'),
'c4_link'=>'#',
'c4_linkList'=>[[$this->p->t('lehre', 'noteneingabedeaktiviert'),'#']],
@@ -448,6 +456,7 @@ class LvMenu extends FHCAPI_Controller
'id'=>'core_menu_mailanstudierende',
'position'=>'100',
'name'=>$this->p->t('lehre', 'mail'),
'phrase' => 'lehre/mail',
'c4_icon'=>base_url('skin/images/button_feedback.png'),
'c4_icon2' => 'fa-regular fa-envelope',
'c4_link'=>$mailto,
@@ -472,6 +481,7 @@ class LvMenu extends FHCAPI_Controller
'id'=>'core_menu_abmeldung',
'position'=>'120',
'name'=>$this->p->t('lehre', 'abmelden'),
'phrase'=>'lehre/abmelden',
'c4_icon'=>base_url('skin/images/button_studiupload.png'),
'c4_link'=>base_url('abmeldung.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem)),
);
@@ -506,6 +516,7 @@ class LvMenu extends FHCAPI_Controller
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse',
'position' => '128',
'name' => $this->p->t('lehre', 'anrechnung'),
'phrase' => 'lehre/anrechnung',
'c4_icon' => base_url('skin/images/button_listen.png'),
'c4_icon2' => 'fa-regular fa-folder-open',
'c4_link' => base_url('cis.php/lehre/anrechnung/RequestAnrechnung?studiensemester='.urlencode($angezeigtes_stsem).'&lv_id='.urlencode($lvid))
@@ -523,6 +534,7 @@ class LvMenu extends FHCAPI_Controller
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse_empfehlen',
'position' => '128',
'name' => $this->p->t('lehre', 'anrechnungen'),
'phrase' => 'lehre/anrechnung',
'c4_icon'=> base_url('skin/images/button_listen.png'),
'c4_icon2' => 'fa-regular fa-folder-open',
'c4_link' => base_url('cis.php/lehre/anrechnung/ReviewAnrechnungUebersicht?studiensemester='.urlencode($angezeigtes_stsem))
@@ -0,0 +1,363 @@
<?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');
use CI3_Events as Events;
use \DateTime as DateTime;
use \DateTimeZone as DateTimeZone;
class LvPlan extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getRoomplan' => self::PERM_LOGGED,
'Stunden' => self::PERM_LOGGED,
'getReservierungen' => self::PERM_LOGGED,
'LvPlanEvents' => self::PERM_LOGGED,
'eventsPersonal' => self::PERM_LOGGED,
'eventsLv' => self::PERM_LOGGED,
'getLehreinheitStudiensemester' => self::PERM_LOGGED,
'studiensemesterDateInterval' => self::PERM_LOGGED,
'getLvPlanForStudiensemester' => self::PERM_LOGGED,
'getLv' => self::PERM_LOGGED
]);
$this->load->library('LogLib');
$this->loglib->setConfigs(array(
'classIndex' => 5,
'functionIndex' => 5,
'lineIndex' => 4,
'dbLogType' => 'API', // required
'dbExecuteUser' => 'RESTful API'
));
$this->load->library('form_validation');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* fetches LvPlan and Moodle events together
* @access public
*
*/
public function LvPlanEvents()
{
$hasLv = $this->input->post('lv_id');
return $hasLv ? $this->eventsLv() : $this->eventsPersonal();
}
/**
* fetches LvPlan, Moodle and Ferien events together for the logged in user
*
* @access public
*/
public function eventsPersonal()
{
$this->load->library('StundenplanLib');
// form validation
$this->form_validation->set_rules('start_date', "start_date", "required");
$this->form_validation->set_rules('end_date', "end_date", "required");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the post parameter in local variables
$start_date = $this->input->post('start_date', true);
$end_date = $this->input->post('end_date', true);
// fetching lvplan events
$result = $this->stundenplanlib->getEventsUser($start_date, $end_date);
$lvplanEvents = $this->getDataOrTerminateWithError($result);
// fetching moodle events
$moodleEvents = $this->fetchMoodleEvents($start_date, $end_date);
// fetching ferien events
$ferienEvents = $this->fetchFerienEvents($start_date, $end_date);
$this->terminateWithSuccess(array_merge(
$lvplanEvents,
$moodleEvents,
$ferienEvents
));
}
/**
* fetches LvPlan and Ferien events together for the lv
*
* @access public
*/
public function eventsLv()
{
$this->load->library('StundenplanLib');
// form validation
$this->form_validation->set_rules('start_date', "start_date", "required");
$this->form_validation->set_rules('end_date', "end_date", "required");
$this->form_validation->set_rules('lv_id', "lv_id", "required|integer");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the post parameter in local variables
$start_date = $this->input->post('start_date', true);
$end_date = $this->input->post('end_date', true);
$lv_id = $this->input->post('lv_id', true);
// fetching lvplan events
$result = $this->stundenplanlib->getEventsLv($lv_id, $start_date, $end_date);
$lvplanEvents = $this->getDataOrTerminateWithError($result);
// fetching ferien events
$ferienEvents = $this->fetchFerienEvents($start_date, $end_date);
$this->terminateWithSuccess(array_merge(
$lvplanEvents,
$ferienEvents
));
}
//TODO: delete this function if we don't use the old calendar export endpoints anymore
public function studiensemesterDateInterval($date){
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$studiensemester =$this->StudiensemesterModel->getByDate(date_format(date_create($date),'Y-m-d'));
$studiensemester =current($this->getDataOrTerminateWithError($studiensemester));
$this->terminateWithSuccess($studiensemester);
}
public function getLvPlanForStudiensemester($studiensemester,$lvid){
$this->load->library('StundenplanLib');
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$studiensemester_result = $this->StudiensemesterModel->loadWhere(["studiensemester_kurzbz"=>$studiensemester]);
$studiensemester_result = current($this->getDataOrTerminateWithError($studiensemester_result));
$timespan_start = new DateTime($studiensemester_result->start);
$timespan_ende = new DateTime($studiensemester_result->ende);
$lvplan = $this->stundenplanlib->getStundenplan(date_format($timespan_start, 'Y-m-d'),date_format($timespan_ende, 'Y-m-d'), $lvid);
$this->terminateWithSuccess($lvplan);
}
/**
* fetches Stunden layout from database
* @access public
*
*/
public function Stunden()
{
$this->load->model('ressource/Stunde_model', 'StundeModel');
$this->StundeModel->addOrder('stunde', 'ASC');
$stunden = $this->StundeModel->load();
$stunden = $this->getDataOrTerminateWithError($stunden);
$this->terminateWithSuccess($stunden);
}
/**
* fetches room events from a certain date
* @access public
*
* @return void
*/
public function getRoomplan()
{
$this->form_validation->set_rules('ort_kurzbz', "Ort", "required");
$this->form_validation->set_rules('start_date', "start_date", "required");
$this->form_validation->set_rules('end_date', "end_date", "required");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the post parameter in local variables
$ort_kurzbz = $this->input->post('ort_kurzbz', true);
$start_date = $this->input->post('start_date', true);
$end_date = $this->input->post('end_date', true);
// get data
$this->load->library('StundenplanLib');
$roomplan_data = $this->stundenplanlib->getRoomplan($ort_kurzbz, $start_date, $end_date);
$roomplan_data = $this->getDataOrTerminateWithError($roomplan_data);
$this->terminateWithSuccess($roomplan_data);
}
/**
* gets the reservierungen of a room if the ort_kurzbz parameter is
* supplied otherwise gets the reservierungen of the lvplan of a student
* @access public
*
* @param string $ort_kurzbz
* @return void
*/
public function getReservierungen($ort_kurzbz = null)
{
$this->form_validation->set_rules('start_date', "StartDate", "required");
$this->form_validation->set_rules('end_date', "EndDate", "required");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the post parameter in local variables
$start_date = $this->input->post('start_date', true);
$end_date = $this->input->post('end_date', true);
// get data
$this->load->library('StundenplanLib');
$result = $this->stundenplanlib->getReservierungen($start_date, $end_date, $ort_kurzbz);
$result = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
public function getLehreinheitStudiensemester($lehreinheit_id){
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->LehreinheitModel->addSelect(["studiensemester_kurzbz"]);
$result = $this->LehreinheitModel->load($lehreinheit_id);
$result = current($this->getDataOrTerminateWithError($result))->studiensemester_kurzbz;
$this->terminateWithSuccess($result);
}
/**
* get details for a lv
* @access public
*
* @param integer $lehrveranstaltung_id
* @return void
*/
public function getLv($lehrveranstaltung_id)
{
if (!$lehrveranstaltung_id && $lehrveranstaltung_id !== 0 && $lehrveranstaltung_id !== '0')
return show_404();
// Load Phrases
$this->loadPhrases(['lehre']);
// Validation
$this->form_validation->set_data([
'lehrveranstaltung_id' => $lehrveranstaltung_id
]);
$this->form_validation->set_rules('lehrveranstaltung_id', $this->p->t('lehre', 'lehrveranstaltung_id'), 'integer');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// Get Data
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
$result = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess(current($result));
}
/**
* fetch moodle events
*
* @param string $start_date
* @param string $end_date
* @return array
*/
private function fetchMoodleEvents($start_date, $end_date)
{
$this->load->config('calendar');
$tz = new DateTimeZone($this->config->item('timezone'));
$start = new DateTime($start_date);
$start->setTimezone($tz);
$end = new DateTime($end_date);
$end->setTimezone($tz);
$end->modify('+1 day -1 second');
$moodle_events = [];
Events::trigger(
'moodleCalendarEvents',
function & () use (&$moodle_events) {
return $moodle_events;
},
[
'start_date' => $start->format('c'),
'end_date' => $end->format('c'),
'username' => getAuthUID()
]
);
return $moodle_events;
}
/**
* fetch ferien events
*
* @param string $start_date
* @param string $end_date
* @return array
*/
private function fetchFerienEvents($start_date, $end_date)
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('education/Studentlehrverband_model', 'StudentLehrverbandModel');
$currentStudiensemester = $this->StudiensemesterModel->getByDate($start_date);
$currentStudiensemester = $this->getDataOrTerminateWithError($currentStudiensemester);
if ($currentStudiensemester) {
$studentsemester_kurzbz = current($currentStudiensemester)->studiensemester_kurzbz;
$studiengang = $this->StudentLehrverbandModel->loadWhere([
"student_uid" => getAuthUID(),
"studiensemester_kurzbz" => $studentsemester_kurzbz
]);
$studiengang = $this->getDataOrTerminateWithError($studiengang);
if ($studiengang)
$studiengang_kz = current($studiengang)->studiengang_kz;
else
$studiengang_kz = 0;
} else {
$studiengang_kz = 0;
}
$ferienEvents = $this->stundenplanlib->fetchFerienTageEvents($start_date, $end_date, $studiengang_kz);
return $this->getDataOrTerminateWithError($ferienEvents);
}
}
@@ -35,15 +35,98 @@ class Ort extends FHCAPI_Controller
parent::__construct([
'ContentID' => self::PERM_LOGGED,
'getOrtKurzbzContent' => self::PERM_LOGGED,
'getRooms' => self::PERM_LOGGED,
'getTypes' => self::PERM_LOGGED
]);
$this->load->model('ressource/Ort_model', 'OrtModel');
$this->config->load('raumsuche');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Retrieves all Ort entries filtered by the provided parameters
*/
public function getRooms()
{
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('datum','Datum','required');
$this->form_validation->set_rules('von','Uhrzeit Von','required|regex_match[/^[0-9]{2}:[0-9]{2}$/]');
$this->form_validation->set_rules('bis','Uhrzeit Bis','required|regex_match[/^[0-9]{2}:[0-9]{2}$/]');
if($this->form_validation->run() == FALSE) {
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$datum = $this->input->get('datum', TRUE);
$von = $this->input->get('von', TRUE);
$bis = $this->input->get('bis', TRUE);
$typ = $this->input->get('typ', TRUE);
$personenanzahl = $this->input->get('personenanzahl', TRUE);
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID())->retval;
$this->load->model('ressource/Stunde_model', 'StundeModel');
$vonStunde = getData($this->StundeModel->getStundeForTime($von))[0]->stunde;
$bisStunde = getData($this->StundeModel->getStundeForTime($bis))[0]->stunde;
$params = array();
$qry = "SELECT DISTINCT tbl_ort.*
FROM public.tbl_ort JOIN public.tbl_ortraumtyp USING(ort_kurzbz)
WHERE aktiv AND lehre AND ort_kurzbz NOT LIKE '\\\\_%'";
if($typ) {
$params[] = $typ;
$qry.= "AND raumtyp_kurzbz = ?";
}
if(!$isMitarbeiter) { // students are only allowed to get a subset defined by config
$qry.= ' AND raumtyp_kurzbz IN ?';
$params[] = $this->config->item('roomtypes_student');
$this->addMeta('config', $this->config->item('roomtypes_student'));
}
$qry.= "AND (max_person>= ? OR max_person is null)";
$params[] = $personenanzahl;
$qry.=" AND ort_kurzbz NOT IN
(
SELECT ort_kurzbz FROM lehre.tbl_stundenplandev WHERE datum = ? AND stunde >= ? AND stunde <= ?
UNION
SELECT ort_kurzbz FROM campus.tbl_reservierung WHERE datum= ? AND stunde >= ? AND stunde <= ?
)
";
$params = array_merge($params, [$datum, $vonStunde, $bisStunde, $datum, $vonStunde, $bisStunde]);
// $this->addMeta('qry', $qry);
// $this->addMeta('params', $params);
$result = $this->OrtModel->execReadOnlyQuery($qry, $params);
$this->terminateWithSuccess($result);
}
public function getTypes()
{
$this->load->model('ressource/Raumtyp_model', 'RaumtypModel');
$qry = "SELECT * FROM public.tbl_raumtyp WHERE aktiv = true";
$params = array();
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID())->retval;
if(!$isMitarbeiter) { // students are only allowed to get a subset defined by config
$qry.= ' AND raumtyp_kurzbz IN ?';
$params[] = $this->config->item('roomtypes_student');
}
$qry .= " ORDER BY raumtyp_kurzbz;";
$result = $this->OrtModel->execReadOnlyQuery($qry, $params);
$this->terminateWithSuccess(getData($result));
}
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
@@ -73,11 +73,22 @@ class Phrasen extends FHCAPI_Controller
// gets all languages that are set as active in the database
public function getAllLanguages()
{
$langs = getDBActiveLanguages();
$this->load->model('system/Sprache_model', 'SprachenModel');
// Add order clause by index and select the sprache,bezeichnung and index column
$this->SprachenModel->addOrder('index');
$this->SprachenModel->addSelect('sprache, bezeichnung, index');
// Retrieves from public.tbl_sprache
$langs = $this->SprachenModel->loadWhere(array('content' => true));
$langs = $this->getDataOrTerminateWithError($langs);
$langs = array_map(function($lang){
return $lang->sprache;
$data = new stdClass();
$data->sprache = $lang->sprache;
$data->bezeichnung = $lang->bezeichnung[($lang->index-1)];
return $data;
}, $langs);
$this->terminateWithSuccess($langs);
}
@@ -27,27 +27,17 @@ class Profil extends FHCAPI_Controller
public function __construct()
{
parent::__construct([
'getView' => self::PERM_LOGGED,
'fotoSperre' => self::PERM_LOGGED,
'getGemeinden' => self::PERM_LOGGED,
'getAllNationen' => self::PERM_LOGGED,
'isMitarbeiter' => self::PERM_LOGGED,
'profilViewData' => self::PERM_LOGGED,
]);
$this->load->library('PermissionLib');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('content/DmsVersion_model', 'DmsVersionModel');
//? put the uid and pid inside the controller for reusability
@@ -58,66 +48,25 @@ class Profil extends FHCAPI_Controller
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* function that returns the data used for the corresponding view
* the client side parses the @param $uid and calls this function to get the data to the correct view
* @access public
* @param boolean $uid the userID used to identify which information should be retrieved for which view
* @return stdClass all the data corresponding to a view of a user
*/
public function getView($uid)
{
$res = new stdClass();
$editAllowed = getAuthUID() == $uid || $this->permissionlib->isBerechtigt('admin');
// if parsing the URL did not found a UID then the UID of the logged in user is used
if ($uid == "Profil" || $uid == $this->uid) {
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($this->uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $this->uid . " is a mitarbeiter");
public function profilViewData($uid=null){
$this->load->library('ProfilLib');
$editable = false;
if(isset($uid) && $uid != null){
$profil_data = $this->profillib->getView($uid);
if($uid == getAuthUID()){
$editable = true;
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "MitarbeiterProfil";
$res->data = $this->mitarbeiterProfil();
$res->data->pid = $this->pid;
} else {
$res->view = "StudentProfil";
$res->data = $this->studentProfil();
$res->data->pid = $this->pid;
}
// editing your own profil - true
$editAllowed = true;
}else{
$editable = true;
$profil_data = $this->profillib->getView(getAuthUID());
}
// UID is availabe when accessing Profil/View/:uid
else {
$this->PersonModel->addSelect(["person_id"]);
$pid = $this->PersonModel->getByUid($uid);
if (isError($pid)) {
show_error("error while trying to update table public.tbl_person while searching for a person with UID: " . $uid);
}
$pid = hasData($pid) ? getData($pid)[0] : null;
if (!$pid) {
show_error("Person with UID: " . $uid . " does not exist");
}
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $uid . " is a mitarbeiter");
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "ViewMitarbeiterProfil";
$res->data = $this->viewMitarbeiterProfil($uid);
} else {
$res->view = "ViewStudentProfil";
$res->data = $this->viewStudentProfil($uid);
}
}
$res->data->editAllowed = $editAllowed;
$this->terminateWithSuccess($res);
$profil_data = hasData($profil_data) ? getData($profil_data) : null;
$viewData = array(
'editable'=>$editable,
'profil_data' => $profil_data,
);
$this->terminateWithSuccess($viewData);
}
/**
@@ -134,14 +83,11 @@ class Profil extends FHCAPI_Controller
$res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]);
if (isError($res)) {
show_error("error while trying to update table public.tbl_person");
$this->terminateWithError("error while trying to update table public.tbl_person");
}
$this->PersonModel->addSelect("foto_sperre");
$res = $this->PersonModel->load($this->pid);
if (isError($res)) {
show_error("error while trying to query table public.tbl_person");
}
$res = $this->getDataOrTerminateWithError($res);
$this->terminateWithSuccess(current($res));
@@ -194,91 +140,7 @@ class Profil extends FHCAPI_Controller
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* function that returns the data used for viewing another mitarbeiter profile
* @access private
* @param integer $uid the userID to retrieve the mitarbeiter data
* @return stdClass restricted mitarbeiter data
*/
private function viewMitarbeiterProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$benutzer_funktion_res = $this->getBenutzerFunktion($uid);
$benutzer_res = $this->getBenutzerAlias($uid);
$person_res = $this->getPersonInfo($uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($uid);
$telefon_res = $this->getTelefonInfo($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Info
foreach ($person_res as $key => $val) {
$res->$key = $val;
}
//? Mitarbeiter Info
foreach ($mitarbeiter_res as $key => $val) {
$res->$key = $val;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $benutzer_res->alias . "@" . DOMAIN;
$res->emails = array($intern_email, $extern_email);
$res->funktionen = $benutzer_funktion_res;
$res->mailverteiler = $mailverteiler_res;
$res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null;
return $res;
}
/**
* function that returns the data used for viewing another student profile
* @access private
* @param integer $uid the userID to retrieve the student data
* @return stdClass restricted student data
*/
private function viewStudentProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$person_res = $this->getPersonInfo($uid);
$student_res = $this->getStudentInfo($uid);
$matr_res = $this->getMatrikelNummer($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = $value;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->matrikelnummer = $matr_res->matr_nr;
$res->mailverteiler = $mailverteiler_res;
return $res;
}
/**
* checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php)
* @access public
@@ -302,394 +164,9 @@ class Profil extends FHCAPI_Controller
$this->terminateWithSuccess($result);
}
/**
* function that returns the data used for the mitarbeiter profile
* @access private
* @return stdClass mitarbeiter data
*/
private function mitarbeiterProfil()
{
// -----------------------------------------------------------------------------------------------------------------
// Private methods
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$benutzer_funktion_res = $this->getBenutzerFunktion($this->uid);
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$telefon_res = $this->getTelefonInfo($this->uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Mitarbeiter Information
foreach ($mitarbeiter_res as $key => $value) {
$res->$key = $value;
}
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->mailverteiler = $mailverteiler_res;
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $mitarbeiter_res->alias . "@" . DOMAIN;
$res->emails = [$intern_email, $extern_email];
$res->funktionen = $benutzer_funktion_res;
$res->standort_telefon = $telefon_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* function that returns the data used for the student profile
* @access private
* @return stdClass student data
*/
private function studentProfil()
{
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$zutrittsgruppe_res = $this->getZutrittsgruppen($this->uid);
$student_res = $this->getStudentInfo($this->uid);
$matr_res = $this->getMatrikelNummer($this->uid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = trim($value);
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->matrikelnummer = $matr_res->matr_nr;
$res->zuttritsgruppen = $zutrittsgruppe_res;
$res->mailverteiler = $mailverteiler_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe
* @access private
* @param integer $uid the userID used to retrieve the mailverteiler
* @return array returns the mailvertailer corresponding to a userID
*/
private function getMailverteiler($uid)
{
$this->PersonModel->addSelect('gruppe_kurzbz, beschreibung');
$this->PersonModel->addJoin('tbl_benutzer', 'person_id');
$this->PersonModel->addJoin('tbl_benutzergruppe', 'uid');
$this->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$mailverteiler_res = $this->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid));
if (isError($mailverteiler_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($mailverteiler_res));
}
$mailverteiler_res = hasData($mailverteiler_res) ? getData($mailverteiler_res) : null;
$mailverteiler_res = array_map(function ($element) {
$element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN;
return $element;
}, $mailverteiler_res);
return $mailverteiler_res;
}
/**
* gets all the Benutzerfunktionen of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Benutzerfunktionen
* @return array returns the Benutzerfunktionen corresponding to a userID
*/
private function getBenutzerFunktion($uid)
{
$this->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]);
$this->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz");
$benutzer_funktion_res = $this->BenutzerfunktionModel->loadWhere(array('uid' => $uid));
if (isError($benutzer_funktion_res)) {
show_error("was not able to query the table public.tbl_benutzerfunktion:" . getData($benutzer_funktion_res));
}
$benutzer_funktion_res = hasData($benutzer_funktion_res) ? getData($benutzer_funktion_res) : null;
return $benutzer_funktion_res;
}
/**
* gets all the Betriebsmittel of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Betriebsmittel
* @return array returns the Betriebsmittel corresponding to a userID
*/
private function getBetriebsmittelInfo($pid)
{
$this->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]);
//? betriebsmittel are not needed in a view
$betriebsmittelperson_res = $this->BetriebsmittelpersonModel->getBetriebsmittel($pid);
if (isError($betriebsmittelperson_res)) {
show_error("was not able to query the table public.tbl_betriebsmittelperson:" . getData($betriebsmittelperson_res));
}
$betriebsmittelperson_res = hasData($betriebsmittelperson_res) ? getData($betriebsmittelperson_res) : null;
return $betriebsmittelperson_res;
}
/**
* gets the alias of a corresponding user
* @access private
* @param integer $uid the userID used to get the alias
* @return string the alias of the userID
*/
private function getBenutzerAlias($uid)
{
$this->BenutzerModel->addSelect(["alias"]);
$benutzer_res = $this->BenutzerModel->load([$uid]);
if (isError($benutzer_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($benutzer_res));
} else {
$benutzer_res = hasData($benutzer_res) ? getData($benutzer_res)[0] : null;
}
return $benutzer_res;
}
/**
* gets the person information corresponding to a user
* @access private
* @param integer $uid the userID used to get the person information
* @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not
* @return array all the person informaion corresponding to a userID
*/
private function getPersonInfo($uid, $geburtsInfo = null)
{
$selectClause = ["foto", "foto_sperre", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"];
/** @param integer $geburtsInfo */
if ($geburtsInfo) {
array_push($selectClause, "gebort");
array_push($selectClause, "gebdatum");
}
$this->BenutzerModel->addSelect($selectClause);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$person_res = $this->BenutzerModel->load([$uid]);
if (isError($person_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($person_res));
} else {
$person_res = hasData($person_res) ? getData($person_res)[0] : null;
}
if( ($person_res->foto === null) || (($this->uid !== $uid) && ($person_res->foto_sperre !== false)) )
{
$dummy_foto = base64_encode(file_get_contents(DOC_ROOT.'skin/images/profilbild_dummy.jpg'));
$person_res->foto = $dummy_foto;
}
return $person_res;
}
/**
* gets the mitarbeiter information corresponding to a user
* @access private
* @param integer $uid the userID used to get the mitarbeiter information
* @return array all the mitarbeiter informaion corresponding to a userID
*/
private function getMitarbeiterInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]);
$this->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid");
$mitarbeiter_res = $this->MitarbeiterModel->load($uid);
if (isError($mitarbeiter_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($mitarbeiter_res));
} else {
$mitarbeiter_res = hasData($mitarbeiter_res) ? getData($mitarbeiter_res)[0] : null;
}
return $mitarbeiter_res;
}
/**
* gets the telefon information corresponding to a user
* @access private
* @param integer $uid the userID used to get the telefon information
* @return array all the telefon informaion corresponding to a userID
*/
private function getTelefonInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kontakt"]);
$this->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id");
$this->MitarbeiterModel->addLimit(1);
$telefon_res = $this->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]);
if (isError($telefon_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($telefon_res));
}
$telefon_res = hasData($telefon_res) ? getData($telefon_res)[0] : null;
return $telefon_res;
}
/**
* gets the student information corresponding to a user
* @access private
* @param integer $uid the userID used to get the student information
* @return array all the student informaion corresponding to a userID
*/
private function getStudentInfo($uid)
{
$this->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']);
$this->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz");
$student_res = $this->StudentModel->load([$uid]);
if (isError($student_res)) {
show_error("was not able to query the table public.tbl_student:" . getData($student_res));
}
$student_res = hasData($student_res) ? getData($student_res)[0] : null;
return $student_res;
}
/**
* gets the profil updates corresponding to a user
* @access private
* @param integer $uid the userID used to get the profil updates
* @return array all the profil updates corresponding to a userID
*/
private function getProfilUpdates($uid)
{
$profilUpdates = $this->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]);
if (isError($profilUpdates)) {
show_error("was not able to query the table public.tbl_profil_update:" . getData($profilUpdates));
}
$profilUpdates = hasData($profilUpdates) ? getData($profilUpdates) : null;
return $profilUpdates;
}
/**
* gets the Matrikelnummer corresponding to a user
* @access private
* @param integer $uid the userID used to get the Matrikelnummer
* @return integer the Matrikelnummer corresponding to a userID
*/
private function getMatrikelNummer($uid)
{
$this->BenutzerModel->addSelect(["matr_nr"]);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$matr_res = $this->BenutzerModel->load([$uid]);
if (isError($matr_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($matr_res));
}
$matr_res = hasData($matr_res) ? getData($matr_res)[0] : [];
return $matr_res;
}
/**
* gets the Zutrittsgruppen corresponding to a user
* @access private
* @param integer $uid the userID used to get the Zutrittsgruppen
* @return array all the Zutrittsgruppen corresponding to a userID
*/
private function getZutrittsgruppen($uid)
{
$this->BenutzergruppeModel->addSelect(['bezeichnung']);
$this->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$zutrittsgruppe_res = $this->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true));
if (isError($zutrittsgruppe_res)) {
show_error("was not able to query the table public.tbl_benutzergruppe:" . getData($zutrittsgruppe_res));
}
$zutrittsgruppe_res = hasData($zutrittsgruppe_res) ? getData($zutrittsgruppe_res) : null;
return $zutrittsgruppe_res;
}
/**
* gets the address information corresponding to a user
* @access private
* @param integer $uid the userID used to get the address information
* @return array all the address information corresponding to a userID
*/
private function getAdressenInfo($pid)
{
$adresse_res = $this->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]);
$adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC");
$adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz");
$adresse_res = $this->AdresseModel->loadWhere(["person_id" => $pid]);
if (isError($adresse_res)) {
show_error("was not able to query the table public.tbl_adresse:" . getData($adresse_res));
}
$adresse_res = hasData($adresse_res) ? getData($adresse_res) : null;
return $adresse_res;
}
/**
* gets the kontakt information corresponding to a user
* @access private
* @param integer $uid the userID used to get the kontakt information
* @return array all the kontakt information corresponding to a userID
*/
private function getKontaktInfo($pid)
{
$this->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']);
$this->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT');
$this->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT');
$this->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum');
$kontakte_res = $this->KontaktModel->loadWhere(['person_id' => $pid]);
if (isError($kontakte_res)) {
show_error("was not able to query the table public.tbl_kontakt:" . getData($kontakte_res));
}
$kontakte_res = hasData($kontakte_res) ? getData($kontakte_res) : null;
return $kontakte_res;
}
/**
* gets the date of issue of the FH access card corresponding to a user
* @access private
* @param integer $uid the userID used to get the date of issue of the FH access card
* @return string the date of issue of the FH access card corresponding to a userID
*/
private function getZutrittskarteDatum($uid)
{
$zutrittskarte_ausgegebenam = $this->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte");
if (isError($zutrittskarte_ausgegebenam)) {
show_error("was not able to query the table wavi.tbl_bentriebsmittelperson:" . getData($zutrittskarte_ausgegebenam));
}
$zutrittskarte_ausgegebenam = hasData($zutrittskarte_ausgegebenam) ? getData($zutrittskarte_ausgegebenam)[0]->ausgegebenam : null;
//? formats date from 01-01-2000 to 01.01.2000
$zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam);
return $zutrittskarte_ausgegebenam;
}
}
@@ -44,6 +44,7 @@ class ProfilUpdate extends FHCAPI_Controller
'updateProfilRequest' => self::PERM_LOGGED,
'deleteProfilRequest' => self::PERM_LOGGED,
'insertFile' => self::PERM_LOGGED,
'updateProfilbild' => self::PERM_LOGGED,
'show' => self::PERM_LOGGED,
]);
@@ -478,12 +479,101 @@ class ProfilUpdate extends FHCAPI_Controller
$this->terminateWithSuccess($res);
}
public function updateProfilbild()
{
$resize = function($filename, $width, $height){
// Hoehe und Breite neu berechnen
list($width_orig, $height_orig) = getimagesize($filename);
if ($width && ($width_orig < $height_orig))
{
$width = ($height / $height_orig) * $width_orig;
}
else
{
$height = ($width / $width_orig) * $height_orig;
}
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
//Bild nur verkleinern aber nicht vergroessern
if($width_orig>$width || $height_orig>$height)
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
else
$image_p = $image;
imagejpeg($image_p, $filename, 80);
@imagedestroy($image_p);
@imagedestroy($image);
};
if (!count($_FILES)) {
$this->terminateWithError("No file available for upload");
}
$files = $_FILES['files'];
$_FILES['files']['name'] = current($files['name']);
$_FILES['files']['type'] = current($files['type']);
$_FILES['files']['tmp_name'] = current($files['tmp_name']);
$_FILES['files']['error'] = current($files['error']);
$_FILES['files']['size'] = current($files['size']);
$_FILES['files']['tmp_name'] = current($files['tmp_name']);
$filename = $_FILES['files']['tmp_name'];
$ext = substr(current($files['name']), strrpos(current($files['name']), '.') + 1);
if($ext!='jpg' && $ext!='jpeg'){
$this->terminateWithError("Only jpg and jpeg files are allowed for profilbild upload");
}
// resize
$resize($filename, 827, 1063);
//akte
$fp = fopen($filename,'r');
//auslesen
$content = fread($fp, filesize($filename));
$base64_content = base64_encode($content);
$this->load->library('AkteLib');
$aktenInsertResult = $this->aktelib->add($this->pid,'Lichtbil',"Lichtbild_".$this->pid.".jpg","image/jpg",$fp,"Lichtbild gross");
fclose($fp);
if (isError($aktenInsertResult)) {
$this->terminateWithError(getError($aktenInsertResult));
}
// in person abspeichern
$resize($filename, 101, 130);
$fp = fopen($filename,'r');
$content = fread($fp, filesize($filename));
fclose($fp);
$base64_content = base64_encode($content);
$this->load->model('person/Person_model','PersonModel');
$personUpdate = $this->PersonModel->update($this->pid, ["foto"=>$base64_content]);
if(isError($personUpdate)){
$this->terminateWithError(getError($personUpdate));
}
// update foto status
$this->load->model('person/Fotostatusperson_model','FotostatusModel');
$fotoInsert = $this->FotostatusModel->insert(["person_id"=>$this->pid,"fotostatus_kurzbz"=>"hochgeladen","datum"=>date('Y-m-d'),"insertamum"=>date('Y-m-d H:i:s'),"insertvon"=>$this->uid,"updateamum"=>date('Y-m-d H:i:s'),"updatevon"=>$this->uid]);
if(isError($fotoInsert)){
$this->terminateWithError(getError($fotoInsert));
}
$this->terminateWithSuccess();
}
public function getProfilUpdateWithPermission($status = null)
{
// early return if no status has been passed as argument
if (!isset($status)) {
echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission());
return;
$this->terminateWithSuccess($this->ProfilUpdateModel->getProfilUpdateWithPermission());
}
// get the sprache of the user
@@ -496,7 +586,7 @@ class ProfilUpdate extends FHCAPI_Controller
$status = hasData($status) ? getData($status)[0]->status_kurzbz : null;
$res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null);
echo json_encode($res);
$this->terminateWithSuccess($res);
}
}
@@ -550,6 +640,7 @@ class ProfilUpdate extends FHCAPI_Controller
$this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id");
$this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id");
$this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz");
$this->StudentModel->addGroupBy(["public.tbl_studiengang.email"]);
//* check if the benutzer itself is active
//* check if the student status is Student or Diplomand (active students)
$this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']);
@@ -566,8 +657,10 @@ class ProfilUpdate extends FHCAPI_Controller
}
$mail_res = [];
//? sending email
foreach ($emails as $email) {
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid)));
foreach ($emails as $email)
{
$href = $this->config->item('cis_vilesci_base_url') . $this->config->item('cis_vilesci_index_page') . '/Cis/ProfilUpdate/id/' . $profil_update_id;
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => $href], $email, ("Profil Änderung von " . $uid)));
}
foreach ($mail_res as $m_res) {
if (!$m_res) {
@@ -590,21 +683,21 @@ class ProfilUpdate extends FHCAPI_Controller
function languageQuery($language)
{
return "select index from public.tbl_sprache where sprache = '" + $language + "'";
return "select index from public.tbl_sprache where sprache = '" . $language . "'";
}
$this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]);
$status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]);
if (isError($status_translation)) {
$this->terminateWithError($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError'));
}
$status_translation = hasData($status_translation) ? getData($status_translation)[0] : null;
if (isset($status_translation)) {
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending')));
if (isset($status_translation))
{
$href = $this->config->item('cis_base_url') . $this->config->item('cis_index_page') . '/Cis/Profil';
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => $href], $email, ("Profil Änderung " . $status_translation->status_de . ' / Profile Update ' . $status_translation->status_en));
if (!$mail_res) {
$this->addError($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
@@ -0,0 +1,72 @@
<?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');
use CI3_Events as Events;
class RendererLoader extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'GetRenderers' => self::PERM_LOGGED,
]);
$this->load->library('LogLib');
$this->loglib->setConfigs(array(
'classIndex' => 5,
'functionIndex' => 5,
'lineIndex' => 4,
'dbLogType' => 'API', // required
'dbExecuteUser' => 'RESTful API'
));
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* fetches Stundenplan and Moodle events together
* @access public
*
*/
public function GetRenderers(){
$renderer_paths = [];
Events::trigger(
'loadRenderers',
function & () use (&$renderer_paths)
{
return $renderer_paths;
}
);
$this->terminateWithSuccess($renderer_paths);
}
}
@@ -0,0 +1,60 @@
<?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');
class RouteInfo extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'info' => self::PERM_LOGGED,
]);
$this->load->model('system/Webservicelog_model', 'WebservicelogModel');
}
public function info()
{
$payload = json_decode($this->input->raw_input_stream);
if (isset($payload->app) && isset($payload->path) && $this->isValidApp($payload->app) && $this->isValidPath($payload->path))
{
$this->WebservicelogModel->insert(array(
'webservicetyp_kurzbz' => 'content',
'beschreibung' => $payload->app,
'request_data' => $payload->path,
'execute_user' => getAuthUID(),
'execute_time' => 'NOW()'
));
}
$this->terminateWithSuccess(true);
}
protected function isValidApp($app)
{
return preg_match("/^[A-Za-z0-9\-_]+$/", $app);
}
protected function isValidPath($path)
{
return preg_match("/^[\/A-Za-z0-9_.\-~?%=&;]+$/", $path);
}
}
@@ -35,11 +35,12 @@ class Searchbar extends FHCAPI_Controller
{
// NOTE(chris): additional permission checks will be done in SearchBarLib
parent::__construct([
'search' => self::PERM_LOGGED
'search' => self::PERM_LOGGED,
'searchCis' => self::PERM_LOGGED,
'searchStv' => self::PERM_LOGGED
]);
// Load the library SearchBarLib
$this->load->library('SearchBarLib');
$this->load->model('system/Webservicelog_model', 'WebservicelogModel');
}
//------------------------------------------------------------------------------------------------------------------
@@ -50,6 +51,7 @@ class Searchbar extends FHCAPI_Controller
*/
public function search()
{
$this->load->library('SearchBarLib');
$this->load->library('form_validation');
// Checks if the searchstr and the types parameters are in the POSTed JSON
@@ -63,7 +65,64 @@ class Searchbar extends FHCAPI_Controller
$result = $this->searchbarlib->search($this->input->post(self::SEARCHSTR_PARAM), $this->input->post(self::TYPES_PARAM));
if (property_exists($result, 'error'))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess($result);
$this->addMeta('mode', 'simple');
$this->terminateWithSuccess($result->data);
}
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
public function searchCis()
{
return $this->searchAdvanced([ 'config' => 'searchcis' ]);
}
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
public function searchStv()
{
return $this->searchAdvanced([ 'config' => 'searchstv' ]);
}
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
private function searchAdvanced($config)
{
$this->load->library('SearchLib', $config);
$this->load->library('form_validation');
// Checks if the searchstr and the types parameters are in the POSTed JSON
$this->form_validation->set_rules(self::SEARCHSTR_PARAM, null, 'required');
$this->form_validation->set_rules(self::TYPES_PARAM . '[]', null, 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// Convert to json the result from searchlib->search
$result = $this->searchlib->search($this->input->post(self::SEARCHSTR_PARAM), $this->input->post(self::TYPES_PARAM));
$this->WebservicelogModel->insert(array(
'webservicetyp_kurzbz' => 'content',
'beschreibung' => $config['config'],
'request_data' => json_encode(array(
self::SEARCHSTR_PARAM => $this->input->post(self::SEARCHSTR_PARAM),
self::TYPES_PARAM => $this->input->post(self::TYPES_PARAM)
)),
'execute_user' => getAuthUID(),
'execute_time' => 'NOW()'
));
$data = $this->getDataOrTerminateWithError($result);
$this->addMeta('time', $result->meta['time']);
$this->addMeta('searchstring', $result->meta['searchstring']);
$this->addMeta('mode', 'advanced');
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,65 @@
<?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');
class Studgang extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getStudiengangInfo'=> self::PERM_LOGGED,
]);
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
// Loads phrases system
$this->loadPhrases([
'global'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getStudiengangInfo(){
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID());
$isMitarbeiter = $this->getDataOrTerminateWithError($isMitarbeiter);
if($isMitarbeiter) {
$this->terminateWithSuccess(null);
}
// fetches the Studiengang Information which is used next to the news
$studiengangInfo = $this->StudiengangModel->getStudiengangInfoForNews();
$studiengangInfo= $this->getDataOrTerminateWithError($studiengangInfo);
$this->terminateWithSuccess($studiengangInfo);
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
}
@@ -0,0 +1,329 @@
<?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');
use CI3_Events as Events;
class Studium extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getStudienAllSemester'=> self::PERM_LOGGED,
'getStudiengaengeForStudienSemester'=> self::PERM_LOGGED,
'getStudienplaeneBySemester'=> self::PERM_LOGGED,
'getLvEvaluierungInfo'=> self::PERM_LOGGED,
]);
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->load->model('organisation/Studienordnung_model','StudienordnungModel');
$this->load->model('organisation/Studiensemester_model',"StudiensemesterModel");
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->load->model('codex/Orgform_model','OrgformModel');
$this->load->model('person/Person_model','PersonModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getStudienAllSemester(){
$parameter_studiensemester = $this->input->get('studiensemester',true);
$parameter_studiengang = $this->input->get('studiengang',true);
$parameter_semester = $this->input->get('semester',true);
$parameter_studienplan = $this->input->get('studienplan',true);
$aktuelles_studiensemester = current($this->getDataOrTerminateWithError($this->StudiensemesterModel->getAktOrNextSemester()));
if($this->getDataOrTerminateWithError($this->StudentModel->isStudent(getAuthUID()))){
$studentLehrverband =$this->StudentlehrverbandModel->loadWhere(["student_uid" => getAuthUID(), "studiensemester_kurzbz" => $aktuelles_studiensemester->studiensemester_kurzbz]);
$studentLehrverband = current($this->getDataOrTerminateWithError($studentLehrverband));
$student_studiensemester = $studentLehrverband->studiensemester_kurzbz;
$student_studiengang = $studentLehrverband->studiengang_kz;
$student_semester = $studentLehrverband->semester;
$student_studienplan = $this->getStudienPlanFromPrestudentStatus(getAuthPersonId())->studienplan_id;
if(!isset($parameter_studiensemester))
$parameter_studiensemester = $student_studiensemester;
if(!isset($parameter_studiengang))
$parameter_studiengang = $student_studiengang;
if(!isset($parameter_semester))
$parameter_semester = $student_semester;
if(!isset($parameter_studienplan))
$parameter_studienplan = $student_studienplan;
}
if(isset($parameter_studiensemester)){
$parameter_studiensemester = current($this->getDataOrTerminateWithError($this->StudiensemesterModel->loadWhere(["studiensemester_kurzbz" => $parameter_studiensemester])));
}
if(isset($parameter_studiengang)){
$parameter_studiengang = current($this->getDataOrTerminateWithError($this->StudiengangModel->loadWhere(["studiengang_kz" => $parameter_studiengang])));
}
if(isset($parameter_studienplan)){
$this->StudienplanModel->addJoin("lehre.tbl_studienordnung", "studienordnung_id");
$this->StudienplanModel->addJoin("lehre.tbl_studienplan_semester", "studienplan_id");
$parameter_studienplan = $this->StudienplanModel->loadWhere(["studienplan_id" => $parameter_studienplan, "aktiv" => TRUE]);
$parameter_studienplan = current($this->getDataOrTerminateWithError($parameter_studienplan));
}
// fetch studiensemester
$allStudienSemester = $this->getDataOrTerminateWithError($this->StudiensemesterModel->load());
if(isset($parameter_studiensemester) && !empty(array_filter($allStudienSemester, function($studiensemester) use($parameter_studiensemester){
return $studiensemester->studiensemester_kurzbz == $parameter_studiensemester->studiensemester_kurzbz;
}))){
$aktuelles_studiensemester = $parameter_studiensemester;
}
// fetch studiengaenge
$studiengaenge = $this->computeStudiengaenge($aktuelles_studiensemester->studiensemester_kurzbz);
$aktuelles_studiengang = current($studiengaenge);
if(!$aktuelles_studiengang){
$aktuelles_studiengang = null;
}
if(isset($parameter_studiengang) && !empty(array_filter( $studiengaenge,function($studiengang)use($parameter_studiengang){
return $studiengang->studiengang_kz == $parameter_studiengang->studiengang_kz;
}))){
$aktuelles_studiengang = $parameter_studiengang;
}
// compute semester and studienplaene
if($aktuelles_studiengang){
$studienplaene = $this->computeStudienplaene($aktuelles_studiengang->studiengang_kz, $aktuelles_studiensemester->studiensemester_kurzbz);
}else{
$studienplaene =[];
}
$semester = array_values(array_unique(array_map(function($item){
return $item->semester;
}, $studienplaene)));
$aktuelles_semester = current($semester);
if(!$aktuelles_semester){
$aktuelles_semester = null;
}
if(isset($parameter_semester) && in_array($parameter_semester, $semester)){
$aktuelles_semester = $parameter_semester;
}
$semester_studienplan = array_filter($studienplaene, function($item) use($aktuelles_semester){
return $item->semester == $aktuelles_semester;
});
// fetch current studienplan based on semester
$aktuelles_studienplan = current($semester_studienplan);
if(!$aktuelles_studienplan){
$aktuelles_studienplan = null;
}
if(isset($parameter_studienplan) && !empty(array_filter( $semester_studienplan, function($studienplan) use($parameter_studienplan){
return $studienplan->studienplan_id == $parameter_studienplan->studienplan_id;
}))){
$aktuelles_studienplan = $parameter_studienplan ;
}
// fetch studienplan lehrveranstaltungen
if($aktuelles_studienplan){
$lehrveranstaltungen = $this->computeStudienplanLehrveranstaltungen($aktuelles_studienplan->studienplan_id, $aktuelles_semester);
foreach($lehrveranstaltungen as $lehrv){
foreach($lehrv->lehrveranstaltungen as $lv){
$lvLektoren =$this->computeLektorenFromLehrveranstaltung($lv->lehrveranstaltung_id,$aktuelles_semester, $aktuelles_studiengang->studiengang_kz, $aktuelles_studiensemester->studiensemester_kurzbz);
$lv->lektoren = $lvLektoren;
}
}
$aktuelles_lehrveranstaltungen = $lehrveranstaltungen;
}else{
$aktuelles_lehrveranstaltungen = [];
}
// result object
$result = new stdClass();
$result->studienSemester = [];
$result->studienSemester["all"]= $allStudienSemester;
$result->studienSemester["preselected"]=$aktuelles_studiensemester;
$result->studiengang["all"]=$studiengaenge;
$result->studiengang["preselected"]=$aktuelles_studiengang;
$result->semester["all"] =$semester;
$result->semester["preselected"] =$aktuelles_semester;
$result->studienplan["all"]=$semester_studienplan;
$result->studienplan["preselected"]=$aktuelles_studienplan;
$result->lehrveranstaltungen=$aktuelles_lehrveranstaltungen;
$this->terminateWithSuccess($result);
}
public function getLvEvaluierungInfo($studiensemester_kurzbz, $lehrveranstaltung_id){
$result = [];
Events::trigger('lvEvaluierungsInfo', function & () use (&$result) {
return $result;
},$lehrveranstaltung_id, $studiensemester_kurzbz);
$this->terminateWithSuccess($result);
}
public function getStudiengaengeForStudienSemester($studiensemester){
$studiengaenge = $this->computeStudiengaenge($studiensemester);
$this->terminateWithSuccess($studiengaenge);
}
public function getStudienplaeneBySemester(){
$this->load->library('form_validation');
$this->form_validation->set_data($this->input->get());
$this->form_validation->set_rules('studiengang', 'studiengang', 'required');
$this->form_validation->set_rules('studiensemester', 'studiensemester', 'required');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$studiengang = $this->input->get('studiengang',true);
$studiensemester = $this->input->get('studiensemester',true);
$studienplaene = $this->computeStudienplaene($studiengang, $studiensemester);
$this->terminateWithSuccess($studienplaene);
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
private function computeStudienplaene($studiengang, $studiensemester){
$studienplaene = $this->StudienplanModel->getStudienplaeneBySemester($studiengang, $studiensemester);
$studienplaene = $this->getDataOrTerminateWithError($studienplaene);
$studienplaene = array_map(function($studienplan){
$orgform = current($this->getDataOrTerminateWithError($this->OrgformModel->loadWhere(["orgform_kurzbz" => $studienplan->orgform_kurzbz])));
$studienplan->orgform_bezeichnung = $orgform->bezeichnung;
return $studienplan;
},$studienplaene);
return $studienplaene;
}
private function computeStudienplanLehrveranstaltungen($studienplan_id, $semester){
/*
SELECT tbl_lehrveranstaltung.*,
tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id,
tbl_studienplan_lehrveranstaltung.semester as stpllv_semester,
tbl_studienplan_lehrveranstaltung.pflicht as stpllv_pflicht,
tbl_studienplan_lehrveranstaltung.koordinator as stpllv_koordinator,
tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent,
tbl_studienplan_lehrveranstaltung.sort stpllv_sort,
tbl_studienplan_lehrveranstaltung.curriculum,
tbl_studienplan_lehrveranstaltung.export,
tbl_studienplan_lehrveranstaltung.genehmigung
FROM lehre.tbl_lehrveranstaltung
JOIN lehre.tbl_studienplan_lehrveranstaltung
USING(lehrveranstaltung_id)
WHERE tbl_studienplan_lehrveranstaltung.studienplan_id=" . $this->db_add_param($studienplan_id, FHC_INTEGER);
if (defined("CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN") && CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN)
$qry .= " AND tbl_lehrveranstaltung.lehrtyp_kurzbz != 'modul'";
if (!is_null($semester))
{
$qry.=" AND tbl_studienplan_lehrveranstaltung.semester=" . $this->db_add_param($semester, FHC_INTEGER);
} */
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$query = "
SELECT tbl_lehrveranstaltung.*,
tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id,
tbl_studienplan_lehrveranstaltung.semester as stpllv_semester,
tbl_studienplan_lehrveranstaltung.pflicht as stpllv_pflicht,
tbl_studienplan_lehrveranstaltung.koordinator as stpllv_koordinator,
tbl_studienplan_lehrveranstaltung.studienplan_lehrveranstaltung_id_parent,
tbl_studienplan_lehrveranstaltung.sort stpllv_sort,
tbl_studienplan_lehrveranstaltung.curriculum,
tbl_studienplan_lehrveranstaltung.export,
tbl_studienplan_lehrveranstaltung.genehmigung
FROM lehre.tbl_lehrveranstaltung
JOIN lehre.tbl_studienplan_lehrveranstaltung
USING(lehrveranstaltung_id)
WHERE
tbl_lehrveranstaltung.lehre = true AND
tbl_studienplan_lehrveranstaltung.studienplan_id=? AND tbl_studienplan_lehrveranstaltung.semester=?";
if (defined("CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN") && CIS_PROFIL_STUDIENPLAN_MODULE_AUSBLENDEN)
$query .= " AND tbl_lehrveranstaltung.lehrtyp_kurzbz != 'modul'";
$lehrveranstaltungen = $this->LehrveranstaltungModel->execReadOnlyQuery($query,[$studienplan_id, $semester]);
$lehrveranstaltungen = $this->getDataOrTerminateWithError($lehrveranstaltungen);
usort($lehrveranstaltungen, function($a, $b){
if($a->lehrtyp_kurzbz == "modul"){
return -1;
}
else if($b->lehrtyp_kurzbz == "modul"){
return 1;
}
return 0;
});
$lehrveranstaltungen= array_reduce($lehrveranstaltungen,function($carry, $lehrv){
if($lehrv->lehrtyp_kurzbz == "modul"){
$lehrv->lehrveranstaltungen = [];
array_push($carry, $lehrv);
}
else{
$parent =array_filter($carry, function($item)use($lehrv){
return $item->studienplan_lehrveranstaltung_id == $lehrv->studienplan_lehrveranstaltung_id_parent;
});
$parent = current($parent);
if($parent){
$parent->lehrveranstaltungen[] = $lehrv;
}
}
return $carry;
}, []);
return $lehrveranstaltungen;
}
private function computeStudiengaenge($studiensemester){
$studiengang_studiensemester_result = $this->StudiengangModel->getStudiengaengeByStudiensemester($studiensemester);
$studiengang_studiensemester_result = $this->getDataOrTerminateWithError($studiengang_studiensemester_result);
return $studiengang_studiensemester_result;
}
private function getStudienPlanFromPrestudentStatus($person_id){
$studienplan_id = current($this->getDataOrTerminateWithError($this->PrestudentstatusModel->getLastStatusPerson($person_id)))->studienplan_id;
$studienplan =current($this->getDataOrTerminateWithError($this->StudienplanModel->loadWhere(["studienplan_id"=>$studienplan_id])));
return $studienplan;
}
private function computeLektorenFromLehrveranstaltung($lehreinheit_id, $semester, $studiengang, $studiensemester){
$this->load->library('StundenplanLib');
$lektoren = $this->stundenplanlib->getLektorenFromLehrveranstaltung($lehreinheit_id,$semester, $studiengang,$studiensemester);
$lektoren = $this->getDataOrTerminateWithError($lektoren) ?? [];
$lektoren = array_map(function($lektor){
return ["name"=>$this->getDataOrTerminateWithError($this->PersonModel->getFullName($lektor)), "email"=>$lektor."@".DOMAIN];
},$lektoren);
return $lektoren;
}
}
@@ -60,7 +60,11 @@ class BetriebsmittelP extends FHCAPI_Controller
public function getAllBetriebsmittel($type_id, $id)
{
$result = $this->BetriebsmittelpersonModel->getBetriebsmittelData($id, $type_id);
$betriebsmitteltypes = null;
if ($this->input->get('betriebsmitteltypes') !== null && !isEmptyArray($this->input->get('betriebsmitteltypes')))
$betriebsmitteltypes = $this->input->get('betriebsmitteltypes');
$result = $this->BetriebsmittelpersonModel->getBetriebsmittelData($id, $type_id, $betriebsmitteltypes);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
@@ -75,8 +79,9 @@ class BetriebsmittelP extends FHCAPI_Controller
'required' => $this->p->t('ui', 'error_fieldRequired')
]);
$this->form_validation->set_rules('kaution', 'Kaution', 'numeric|less_than_equal_to[9999.99]', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric')
$this->form_validation->set_rules('kaution', 'Kaution', 'callback_valid_number|callback_not_less_than_equal', [
'valid_number' => $this->p->t('ui', 'error_fieldNoValidNumber'),
'not_less_than_equal' => $this->p->t('ui', 'error_fieldLessThan1000'),
]);
$this->form_validation->set_rules('ausgegebenam', 'Ausgegeben am', 'required|is_valid_date', [
@@ -158,6 +163,7 @@ class BetriebsmittelP extends FHCAPI_Controller
], [
'uid_in_person' => $this->p->t('person', 'error_uidNotInPerson')
]);
$this->validateNewOrUpdate();
$betriebsmitteltyp = $this->input->post('betriebsmitteltyp');
@@ -167,6 +173,7 @@ class BetriebsmittelP extends FHCAPI_Controller
$betriebsmittel_id = $this->input->post('betriebsmittel_id');
$anmerkung = $this->input->post('anmerkung');
$kaution = $this->input->post('kaution');
if($kaution) $kaution = str_replace(',', '.', $kaution);
$ausgegebenam = $this->input->post('ausgegebenam');
$retouram = $this->input->post('retouram');
$uid = $this->input->post('uid');
@@ -250,6 +257,7 @@ class BetriebsmittelP extends FHCAPI_Controller
$betriebsmittel_id = $this->input->post('betriebsmittel_id');
$anmerkung = $this->input->post('anmerkung');
$kaution = $this->input->post('kaution');
if($kaution) $kaution = str_replace(',', '.', $kaution);
$ausgegebenam = $this->input->post('ausgegebenam');
$retouram = $this->input->post('retouram');
@@ -342,7 +350,7 @@ class BetriebsmittelP extends FHCAPI_Controller
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Betriebsmittelperson_id']), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(current(getData($result)));
return $this->terminateWithSuccess(current(getData($result)));
}
public function deleteBetriebsmittel($betriebsmittelperson_id)
@@ -358,7 +366,7 @@ class BetriebsmittelP extends FHCAPI_Controller
if (!hasData($result)) {
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Betriebsmittelperson_id']), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(current(getData($result)));
$this->terminateWithSuccess(current(getData($result)));
}
public function getTypenBetriebsmittel()
@@ -366,6 +374,12 @@ class BetriebsmittelP extends FHCAPI_Controller
$this->load->model('ressource/Betriebsmitteltyp_model', 'BetriebsmitteltypModel');
$this->BetriebsmitteltypModel->addOrder('beschreibung', 'ASC');
if ($this->input->get('betriebsmitteltypes') !== null && !isEmptyArray($this->input->get('betriebsmitteltypes')))
{
$this->BetriebsmitteltypModel->db->where_in('betriebsmitteltyp', $this->input->get('betriebsmitteltypes'));
}
$result = $this->BetriebsmitteltypModel->load(); // load All
if (isError($result)) {
@@ -382,6 +396,26 @@ class BetriebsmittelP extends FHCAPI_Controller
$this->terminateWithSuccess($data);
}
public function valid_number($number)
{
if(is_null($number)) return true;
$number = str_replace(',', '.', $number);
if (!is_numeric($number))
{
return false;
}
return true;
}
public function not_less_than_equal($number)
{
$number = str_replace(',', '.', $number);
if ($number < 1000)
return true;
return false;
}
}
@@ -0,0 +1,328 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Funktionen extends FHCAPI_Controller
{
public function __construct()
{
//TODO(Manu) check permissions
parent::__construct(array(
'getAllFunctions' => ['admin:r', 'assistenz:r'],
'getAllUserFunctions' => ['admin:r', 'assistenz:r'],
'getOrgHeads' => ['admin:r', 'assistenz:r'],
'getOrgetsForCompany' => ['admin:r', 'assistenz:r'],
'getAllOrgUnits' => ['admin:r', 'assistenz:r'],
'loadFunction' => ['admin:r', 'assistenz:r'],
'insertFunction' => ['admin:rw', 'assistenz:rw'],
'updateFunction' => ['admin:rw', 'assistenz:rw'],
'deleteFunction' => ['admin:rw', 'assistenz:rw'],
)
);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
]);
// Load models
$this->load->model('extensions/FHC-Core-Personalverwaltung/Api_model', 'ApiModel');
$this->load->model('ressource/Funktion_model', 'FunktionModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
}
public function getAllFunctions()
{
$this->FunktionModel->addSelect("funktion_kurzbz");
$this->FunktionModel->addSelect("beschreibung");
$this->FunktionModel->addSelect("aktiv");
$this->FunktionModel->addSelect("beschreibung AS label");
$this->FunktionModel->addOrder("beschreibung");
$result = $this->FunktionModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getOrgHeads()
{
$result = $this->OrganisationseinheitModel->getHeads();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAllUserFunctions($uid)
{
if(!$uid)
{
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'UID']), self::ERROR_TYPE_GENERAL);
}
$sql = "
SELECT
dv.dienstverhaeltnis_id,
un.bezeichnung || ' (' || TO_CHAR(dv.von, 'DD.MM.YYYY') || CASE WHEN dv.bis IS NOT NULL THEN ' - '
|| TO_CHAR(dv.bis, 'DD.MM.YYYY') ELSE '' END || ')' AS dienstverhaeltnis_unternehmen ,
'[' || oet.bezeichnung || '] ' || oe.bezeichnung AS funktion_oebezeichnung,
f.beschreibung AS funktion_beschreibung,
bf.*,
fb.bezeichnung AS fachbereich_bezeichnung,
CASE
WHEN
bf.datum_bis IS NOT NULL AND bf.datum_bis::date < now()::date
THEN
false
ELSE
true
END aktiv
FROM
public.tbl_benutzerfunktion bf
JOIN
public.tbl_organisationseinheit oe ON oe.oe_kurzbz = bf.oe_kurzbz
JOIN
public.tbl_organisationseinheittyp oet ON oe.organisationseinheittyp_kurzbz = oet.organisationseinheittyp_kurzbz
JOIN
public.tbl_funktion f ON f.funktion_kurzbz = bf.funktion_kurzbz
LEFT JOIN
hr.tbl_vertragsbestandteil_funktion vf ON vf.benutzerfunktion_id = bf.benutzerfunktion_id
LEFT JOIN
hr.tbl_vertragsbestandteil v ON vf.vertragsbestandteil_id = v.vertragsbestandteil_id
LEFT JOIN
hr.tbl_dienstverhaeltnis dv ON v.dienstverhaeltnis_id = dv.dienstverhaeltnis_id
LEFT JOIN
public.tbl_organisationseinheit un ON dv.oe_kurzbz = un.oe_kurzbz
LEFT JOIN
public.tbl_fachbereich fb ON fb.fachbereich_kurzbz = bf.fachbereich_kurzbz
WHERE
bf.uid = ?
ORDER BY
bf.datum_von, bf.datum_von ASC";
$benutzerfunktionen = $this->BenutzerfunktionModel->execReadOnlyQuery($sql, array($uid));
$data = $this->getDataOrTerminateWithError($benutzerfunktionen);
$this->terminateWithSuccess($data);
}
/*
* returns list of all organisation units
* as key value list to be used in select or autocomplete
*/
public function getAllOrgUnits()
{
$sql = "
SELECT
oe.oe_kurzbz, oe.aktiv,
'[' || COALESCE(oet.bezeichnung, oet.organisationseinheittyp_kurzbz) ||
'] ' || COALESCE(oe.bezeichnung, oe.oe_kurzbz) AS label
FROM public.tbl_organisationseinheit oe
JOIN public.tbl_organisationseinheittyp oet ON oe.organisationseinheittyp_kurzbz = oet.organisationseinheittyp_kurzbz
ORDER BY oet.bezeichnung ASC, oe.bezeichnung ASC";
$result = $this->OrganisationseinheitModel->execReadOnlyQuery($sql);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/*
* return list of child orgets for a given company orget_kurzbz
* as key value list to be used in select or autocomplete
*/
public function getOrgetsForCompany($companyOrgetkurzbz = null)
{
$sql = "
SELECT
oe.oe_kurzbz, oe.aktiv,
'[' || COALESCE(oet.bezeichnung, oet.organisationseinheittyp_kurzbz) ||
'] ' || COALESCE(oe.bezeichnung, oe.oe_kurzbz) AS label
FROM (
WITH RECURSIVE oes(oe_kurzbz, oe_parent_kurzbz) as
(
SELECT oe_kurzbz, oe_parent_kurzbz FROM public.tbl_organisationseinheit
WHERE oe_kurzbz=?
UNION ALL
SELECT o.oe_kurzbz, o.oe_parent_kurzbz FROM public.tbl_organisationseinheit o, oes
WHERE o.oe_parent_kurzbz=oes.oe_kurzbz
)
SELECT oe_kurzbz
FROM oes
GROUP BY oe_kurzbz
) c
JOIN public.tbl_organisationseinheit oe ON oe.oe_kurzbz = c.oe_kurzbz
JOIN public.tbl_organisationseinheittyp oet ON oe.organisationseinheittyp_kurzbz = oet.organisationseinheittyp_kurzbz
ORDER BY oet.bezeichnung ASC, oe.bezeichnung ASC";
$childorgets = $this->OrganisationseinheitModel->execReadOnlyQuery($sql, array($companyOrgetkurzbz));
$data = $this->getDataOrTerminateWithError($childorgets);
$this->terminateWithSuccess($data);
}
public function loadFunction($benutzerfunktion_id)
{
$this->BenutzerfunktionModel->addSelect("*");
$result = $this->BenutzerfunktionModel->loadWhere(
array('benutzerfunktion_id' => $benutzerfunktion_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function insertFunction()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$uid = $this->input->post('uid');
if(!$uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$datum_von = $formData['datum_von'] ?? null;
$datum_bis = $formData['datum_bis'] ?? null;
$formData['oe_kurzbz'] = is_array($formData['oe_kurzbz']) ? $formData['oe_kurzbz']['oe_kurzbz'] : $formData['oe_kurzbz'];
$formData['funktion_kurzbz'] = is_array($formData['funktion_kurzbz'])
? $formData['funktion_kurzbz']['funktion_kurzbz']
: $formData['funktion_kurzbz'];
$bezeichnung = $formData['bezeichnung'] ?? null;
$wochenstunden = $formData['wochenstunden'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('datum_von', 'VonDatum', 'required|is_valid_date', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'VonDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
]);
$this->form_validation->set_rules('datum_bis', 'BisDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'BisDatum'])
]);
$this->form_validation->set_rules('oe_kurzbz', 'Organisationseinheit', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Organisationseinheit'])
]);
$this->form_validation->set_rules('funktion_kurzbz', 'Funktion', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Funktion'])
]);
$this->form_validation->set_rules('wochenstunden', 'Wochenstunden', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Wochenstunden'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->BenutzerfunktionModel->insert([
'uid' => $uid,
'datum_von' => $datum_von,
'datum_bis' => $datum_bis ,
'oe_kurzbz' => $formData['oe_kurzbz'],
'funktion_kurzbz' => $formData['funktion_kurzbz'],
'bezeichnung' => $bezeichnung,
'wochenstunden' => $wochenstunden,
'insertamum' => date('c'),
'insertvon' => $authUID,
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function updateFunction()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$uid = $this->input->post('uid');
if(!$uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'UID']), self::ERROR_TYPE_GENERAL);
}
$benutzerfunktion_id = $this->input->post('benutzerfunktion_id');
if(!$benutzerfunktion_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Benutzerfunktion ID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$datum_von = $formData['datum_von'] ?? null;
$datum_bis = $formData['datum_bis'] ?? null;
$formData['oe_kurzbz'] = is_array($formData['oe_kurzbz']) ? $formData['oe_kurzbz']['oe_kurzbz'] : $formData['oe_kurzbz'];
$formData['funktion_kurzbz'] = is_array($formData['funktion_kurzbz'])
? $formData['funktion_kurzbz']['funktion_kurzbz']
: $formData['funktion_kurzbz'];
$bezeichnung = $formData['bezeichnung'] ?? null;
$wochenstunden = $formData['wochenstunden'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('datum_von', 'VonDatum', 'required|is_valid_date', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'VonDatum']),
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
]);
$this->form_validation->set_rules('datum_bis', 'BisDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'BisDatum'])
]);
$this->form_validation->set_rules('oe_kurzbz', 'Organisationseinheit', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Organisationseinheit'])
]);
$this->form_validation->set_rules('funktion_kurzbz', 'Funktion', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Funktion'])
]);
$this->form_validation->set_rules('wochenstunden', 'Wochenstunden', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Wochenstunden'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->BenutzerfunktionModel->update(
[
'benutzerfunktion_id' => $benutzerfunktion_id,
],
[
'uid' => $uid,
'datum_von' => $datum_von,
'datum_bis' => $datum_bis ,
'oe_kurzbz' => $formData['oe_kurzbz'],
'funktion_kurzbz' => $formData['funktion_kurzbz'],
'bezeichnung' => $bezeichnung,
'wochenstunden' => $wochenstunden,
'updateamum' => date('c'),
'updatevon' => $authUID,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteFunction($benutzerfunktion_id)
{
$result = $this->BenutzerfunktionModel->delete(
array('benutzerfunktion_id' => $benutzerfunktion_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,110 @@
<?php
/**
* Copyright (C) 2025 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');
class DirektGruppe extends FHCAPI_Controller
{
private $_ci;
public function __construct()
{
parent::__construct([
'add' => ['admin:rw', 'assistenz:rw'],
'delete' => ['admin:rw', 'assistenz:rw'],
'getByLehreinheit' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->loadPhrases([
'ui'
]);
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
$this->_ci->load->model('education/lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('person/Benutzer_model', 'BenutzerModel');
}
public function add()
{
$uid = $this->input->post('uid');
$lehreinheit_id = $this->input->post('lehreinheit_id');
$this->checkPermission($lehreinheit_id, $uid);
$result = $this->_ci->LehreinheitgruppeModel->direktUserAdd($uid, $lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function delete()
{
$uid = $this->input->post('uid');
$lehreinheit_id = $this->input->post('lehreinheit_id');
$this->checkPermission($lehreinheit_id, $uid);
$result = $this->_ci->LehreinheitgruppeModel->direktUserDelete($uid, $lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function getByLehreinheit($lehreinheit_id = null)
{
$this->checkPermission($lehreinheit_id);
$gruppen = $this->_ci->LehreinheitgruppeModel->getDirectGroup($lehreinheit_id);
$this->terminateWithSuccess(hasData($gruppen) ? getData($gruppen) : array());
}
private function checkPermission($lehreinheit_id, $uid = false)
{
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit_result) || isError($lehreinheit_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
if ($uid)
{
$benuzuer_result = $this->_ci->BenutzerModel->load(array($uid));
if (!hasData($benuzuer_result) || isError($benuzuer_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
}
$result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$oe_array = [];
if (hasData($result))
$oe_array = getData($result);
if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid'))
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
}
}
@@ -0,0 +1,47 @@
<?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);
}
}
@@ -0,0 +1,195 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Gruppe extends FHCAPI_Controller
{
private $_uid;
private $_ci;
public function __construct()
{
parent::__construct([
'add' => ['admin:rw', 'assistenz:rw'],
'delete' => ['admin:rw', 'assistenz:rw'],
'deleteFromLVPlan' => ['admin:rw', 'assistenz:rw'],
'getBenutzer' => ['admin:r', 'assistenz:r'],
'getAll' => ['admin:r', 'assistenz:r'],
'getByLehreinheit' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->library('PhrasesLib');
$this->loadPhrases(
array(
'ui'
)
);
$this->_ci->load->model('organisation/Gruppe_model', 'GruppeModel');
$this->_ci->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
$this->_ci->load->model('person/Person_model', 'PersonModel');
$this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
}
public function delete()
{
$lehreinheitgruppe_id = $this->input->post('lehreinheitgruppe_id');
$lehreinheit_id = $this->input->post('lehreinheit_id');
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($lehreinheitgruppe_id) || !ctype_digit((string)$lehreinheitgruppe_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheitgruppe_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheitgruppe_id' => $lehreinheitgruppe_id));
if (!hasData($lehreinheitgruppe_result) || isError($lehreinheitgruppe_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermission($lehreinheit_id);
$result = $this->_ci->LehreinheitgruppeModel->deleteGroup($lehreinheit_id, $lehreinheitgruppe_id);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function add()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$gid = $this->input->post('gid');
$lehrverband = $this->input->post('lehrverband');
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($gid) || !ctype_digit((string)$gid) || is_null($lehrverband))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermission($lehreinheit_id);
$result = $this->_ci->LehreinheitgruppeModel->addGroup($lehreinheit_id, $gid, !($lehrverband === 'false'));
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function getByLehreinheit($lehreinheit_id = null)
{
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermission($lehreinheit_id);
$gruppen = $this->_ci->LehreinheitgruppeModel->getByLehreinheit($lehreinheit_id);
$this->terminateWithSuccess(hasData($gruppen) ? getData($gruppen) : array());
}
public function deleteFromLVPlan()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$lehreinheitgruppe_id = $this->input->post('lehreinheitgruppe_id');
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id) || is_null($lehreinheitgruppe_id) || !ctype_digit((string)$lehreinheitgruppe_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheitgruppe_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheitgruppe_id' => $lehreinheitgruppe_id));
if (!hasData($lehreinheitgruppe_result) || isError($lehreinheitgruppe_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermission($lehreinheit_id);
$result = $this->_ci->StundenplandevModel->deleteGroupPlanning($lehreinheit_id, $lehreinheitgruppe_id);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function getAll()
{
$this->_ci->GruppeModel->addSelect('gruppe_kurzbz,
studiengang_kz,
semester,
bezeichnung,
gid,
\'false\' as lehrverband');
$gruppen_result = $this->_ci->GruppeModel->loadWhere(array('sichtbar' => true, 'aktiv' => true, 'lehre' => true, 'direktinskription' => false, 'semester IS NOT NULL' => null));
$gruppen_array = array();
if (isError($gruppen_result))
$this->terminateWithError(getError($gruppen_result), self::ERROR_TYPE_GENERAL);
if (hasData($gruppen_result))
$gruppen_array = getData($gruppen_result);
$this->_ci->LehrverbandModel->addSelect('CONCAT(UPPER(CONCAT(typ, kurzbz)), \'\', semester, verband, COALESCE(gruppe,\'\')) as gruppe_kurzbz,
studiengang_kz,
semester,
tbl_lehrverband.bezeichnung,
gid,
\'true\' as lehrverband');
$this->_ci->LehrverbandModel->addJoin('public.tbl_studiengang', 'studiengang_kz');
$this->_ci->LehrverbandModel->addOrder('verband');
$this->_ci->LehrverbandModel->addOrder('gruppe');
$lehrverband_result = $this->_ci->LehrverbandModel->loadWhere(array('tbl_lehrverband.aktiv' => true));
$lehrverband_array = array();
if (isError($lehrverband_result))
$this->terminateWithError(getError($lehrverband_result), self::ERROR_TYPE_GENERAL);
if (hasData($lehrverband_result))
$lehrverband_array = getData($lehrverband_result);
$all_gruppen = array_merge($gruppen_array, $lehrverband_array);
$this->terminateWithSuccess($all_gruppen);
}
public function getBenutzer()
{
$this->_ci->PersonModel->addSelect('vorname, nachname, uid, semester, UPPER(CONCAT(tbl_studiengang.typ, tbl_studiengang.kurzbz)) as studiengang');
$this->_ci->PersonModel->addJoin('public.tbl_benutzer', 'person_id');
$this->_ci->PersonModel->addJoin('public.tbl_mitarbeiter', 'uid = mitarbeiter_uid', 'LEFT');
$this->_ci->PersonModel->addJoin('public.tbl_student', 'uid = student_uid', 'LEFT');
$this->_ci->PersonModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT');
$personen = $this->_ci->PersonModel->loadWhere(array('tbl_benutzer.aktiv' => true));
$this->terminateWithSuccess(hasData($personen) ? getData($personen) : array());
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
private function checkPermission($lehreinheit_id)
{
$lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit_result) || isError($lehreinheit_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$oe_array = [];
if (hasData($result))
$oe_array = getData($result);
if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('lv-plan', $oe_array, 'suid'))
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
}
}
@@ -0,0 +1,446 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Lehreinheit extends FHCAPI_Controller
{
private $_uid;
private $_ci;
public function __construct()
{
parent::__construct([
'add' => ['admin:rw', 'assistenz:rw'],
'copy' => ['admin:rw', 'assistenz:rw'],
'delete' => ['admin:rw', 'assistenz:rw'],
'update' => ['admin:rw', 'assistenz:rw'],
'get' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r'],
'getLehrfach' => ['admin:r', 'assistenz:r'],
'getSprache' => ['admin:r', 'assistenz:r'],
'getRaumtyp' => ['admin:r', 'assistenz:r'],
'getLehrform' => ['admin:r', 'assistenz:r']
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
$this->_ci->load->library('PhrasesLib');
$this->loadPhrases(
array(
'global',
'ui'
)
);
$this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehreinheitgruppe_model', 'LehreinheitgruppeModel');
$this->_ci->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
}
public function get($lehreinheit_id)
{
$lehreinheit = $this->checkLehreinheit($lehreinheit_id);
$lehreinheit->lehrfaecher = $this->getLehrfaecher($lehreinheit);
$this->terminateWithSuccess($lehreinheit);
}
private function getLehrfaecher($lehreinheit)
{
$lehrfacher_array = array($lehreinheit->lehrfach_id);
$this->_ci->LehreinheitModel->addSelect('lehrveranstaltung_id_kompatibel');
$this->_ci->LehreinheitModel->addJoin('lehre.tbl_lehrveranstaltung_kompatibel', 'lehrveranstaltung_id');
$lehrfaecher = $this->_ci->LehreinheitModel->loadWhere(array('lehrveranstaltung_id' => $lehreinheit->lehrveranstaltung_id));
if (hasData($lehrfaecher))
$lehrfaecher_array = array_merge($lehrfacher_array, array_column(getData($lehrfaecher), 'lehrveranstaltung_id_kompatibel'));
$lehrfaecher_array[] = $lehreinheit->lehrveranstaltung_id;
$this->_ci->LehrveranstaltungModel->addDistinct('lehrfach_id');
$this->_ci->LehrveranstaltungModel->addSelect("tbl_lehrveranstaltung.lehrveranstaltung_id, CONCAT(tbl_lehrveranstaltung.bezeichnung || '(' || tbl_lehrveranstaltung.oe_kurzbz || ')') as lehrfach");
$this->_ci->LehrveranstaltungModel->db->where_in('tbl_lehrveranstaltung.lehrveranstaltung_id', $lehrfaecher_array);
$lehrfaecher_result = $this->_ci->LehrveranstaltungModel->load();
return hasData($lehrfaecher_result) ? getData($lehrfaecher_result) : array();
}
public function add()
{
$lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
if (is_null($lehrveranstaltung_id) || !ctype_digit((string)$lehrveranstaltung_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehrveranstaltung_result = $this->_ci->LehrveranstaltungModel->loadWhere(array('lehrveranstaltung_id' => $lehrveranstaltung_id));
if (!hasData($lehrveranstaltung_result) || isError($lehrveranstaltung_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehrveranstaltung = getData($lehrveranstaltung_result)[0];
$oe_result = $this->_ci->LehrveranstaltungModel->getAllOe($lehrveranstaltung->lehrveranstaltung_id);
$oe_array = hasData($oe_result) ? array_column(getData($oe_result), 'oe_kurzbz') : array();
if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('lv-plan', $oe_array, 'suid'))
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
$this->_ci->load->library('form_validation');
$updatableFields = array(
'lehrveranstaltung_id',
'studiensemester_kurzbz',
'lehrfach_id',
'lehrform_kurzbz',
'stundenblockung',
'wochenrythmus',
'gewicht',
'start_kw',
'raumtyp',
'raumtypalternativ',
'sprache',
'lehre',
'anmerkung',
'lvnr',
'unr',
);
foreach ($updatableFields as $field)
{
switch ($field) {
case 'lehrveranstaltung_id':
$this->form_validation->set_rules($field, 'Lehrveranstaltung ID', 'required|integer');
break;
case 'studiensemester_kurzbz':
$this->form_validation->set_rules($field, 'Studiensemester', 'required|max_length[16]');
break;
case 'lehrfach_id':
$this->form_validation->set_rules($field, 'Lehrfach ID', 'required|integer');
break;
case 'lehrform_kurzbz':
$this->form_validation->set_rules($field, 'Lehrform', 'required|max_length[8]');
break;
case 'stundenblockung':
$this->form_validation->set_rules($field, 'Stundenblockung', 'required|integer|greater_than_equal_to[0]');
break;
case 'wochenrythmus':
$this->form_validation->set_rules($field, 'Wochenrhytmus', 'required|integer|greater_than_equal_to[0]');
break;
case 'start_kw':
$this->form_validation->set_rules($field, 'Start KW', 'integer|greater_than[0]|less_than_equal_to[53]');
break;
case 'gewicht':
$this->form_validation->set_rules($field, 'Gewicht', 'numeric');
break;
case 'raumtyp':
$this->form_validation->set_rules($field, 'Raumtyp', 'required|max_length[16]');
break;
case 'raumtypalternativ':
$this->form_validation->set_rules($field, 'Raumtyp Alternativ', 'required|max_length[16]');
break;
case 'sprache':
$this->form_validation->set_rules($field, 'Sprache', 'required|max_length[16]');
break;
case 'lvnr':
$this->form_validation->set_rules($field, 'LVNR', 'integer');
break;
case 'unr':
$this->form_validation->set_rules($field, 'UNR', 'integer');
break;
case 'lehre':
$this->form_validation->set_rules($field, 'Lehre', 'trim');
break;
case 'anmerkung':
$this->form_validation->set_rules($field, 'Anmerkung', 'trim');
break;
}
}
if ($this->form_validation->run() === false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$updateData = array();
foreach ($updatableFields as $field)
{
$value = $this->input->post($field);
if ($value !== null)
{
$updateData[$field] = $value;
}
}
$updateData['insertvon'] = $this->_uid;
$updateData['insertamum'] = date('Y-m-d H:i:s');
$result = $this->_ci->LehreinheitModel->insert(
$updateData
);
if (!isset($updateData['unr']))
{
$unr = getData($result);
$this->_ci->LehreinheitModel->update($unr, array('unr' => $unr));
}
$this->terminateWithSuccess($result);
}
public function copy()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$art = $this->input->post('art');
$lehreinheit_old = $this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit_old->lehreinheit_id);
$lehreinheit_new = $lehreinheit_old;
$lehreinheit_new->unr = null;
unset($lehreinheit_new->lehreinheit_id);
$lehreinheit_new->updateamum = date('Y-m-d H:i:s');
$lehreinheit_new->updatevon = $this->_uid;
$lehreinheit_new->insertamum = date('Y-m-d H:i:s');
$lehreinheit_new->insertvon = $this->_uid;
$insert_result = $this->_ci->LehreinheitModel->insert($lehreinheit_new);
if (isError($insert_result))
$this->terminateWithError(getError($insert_result), self::ERROR_TYPE_GENERAL);
$lehreinheit_id_new = getData($insert_result);
$this->_ci->LehreinheitModel->update(array('lehreinheit_id' => $lehreinheit_id_new), array('unr' => $lehreinheit_id_new));
if (in_array($art, array('gruppen', 'alle')))
{
$gruppen_result = $this->_ci->LehreinheitgruppeModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (isError($gruppen_result))
$this->terminateWithError(getError($gruppen_result), self::ERROR_TYPE_GENERAL);
if (hasData($gruppen_result))
{
$gruppen = getData($gruppen_result);
foreach ($gruppen as $gruppe)
{
$gruppe_new = $gruppe;
unset($gruppe_new->lehreinheitgruppe_id);
$gruppe_new->lehreinheit_id = $lehreinheit_id_new;
$gruppe_new->insertamum = date('Y-m-d H:i:s');
$gruppe_new->insertvon = $this->_uid;
$gruppe_new->updateamum = date('Y-m-d H:i:s');
$gruppe_new->updatevon = $this->_uid;
$gruppe_new_result = $this->_ci->LehreinheitgruppeModel->insert($gruppe_new);
if (isError($gruppe_new_result))
$this->terminateWithError(getError($gruppe_new_result), self::ERROR_TYPE_GENERAL);
}
}
}
if (in_array($art, array('lektoren', 'alle')))
{
$lektoren_result = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id));
if (isError($lektoren_result))
$this->terminateWithError(getError($lektoren_result), self::ERROR_TYPE_GENERAL);
if (hasData($lektoren_result))
{
$lektoren = getData($lektoren_result);
foreach ($lektoren as $lektor)
{
$lektor_new = $lektor;
$lektor_new->lehreinheit_id = $lehreinheit_id_new;
$lektor_new->insertamum = date('Y-m-d H:i:s');
$lektor_new->insertvon = $this->_uid;
$lektor_new->updateamum = date('Y-m-d H:i:s');
$lektor_new->updatevon = $this->_uid;
unset($lektor_new->vertrag_id);
$lektor_new_result = $this->_ci->LehreinheitmitarbeiterModel->insert((array)$lektor_new);
if (isError($lektor_new_result))
$this->terminateWithError(getError($lektor_new_result), self::ERROR_TYPE_GENERAL);
}
}
}
$this->terminateWithSuccess("Erfolgeich gespeichert");
}
public function delete()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$lehreinheit = $this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit->lehreinheit_id);
$result = $this->_ci->LehreinheitModel->deleteLehreinheit($lehreinheit->lehreinheit_id);
if (isError($result))
$this->terminateWithValidationErrors(getError($result));
$this->terminateWithSuccess('Erfolgreich geloescht');
}
public function update()
{
$lehreinheit = $this->checkLehreinheit($this->input->post('lehreinheit_id'));
$this->checkPermission($lehreinheit->lehreinheit_id);
$this->_ci->load->library('form_validation');
$formData = $this->input->post('formData');
$updatableFields = array(
'lehrveranstaltung_id',
'studiensemester_kurzbz',
'lehrfach_id',
'lehrform_kurzbz',
'stundenblockung',
'wochenrythmus',
'gewicht',
'start_kw',
'raumtyp',
'raumtypalternativ',
'sprache',
'lehre',
'anmerkung',
'lvnr',
'unr',
);
$this->form_validation->set_data($formData);
foreach ($updatableFields as $field)
{
if (array_key_exists($field, $formData))
{
switch ($field)
{
case 'lehrveranstaltung_id':
$this->form_validation->set_rules($field, 'Lehrveranstaltung ID', 'required|integer');
break;
case 'studiensemester_kurzbz':
$this->form_validation->set_rules($field, 'Studiensemester', 'required|max_length[16]');
break;
case 'lehrfach_id':
$this->form_validation->set_rules($field, 'Lehrfach ID', 'required|integer');
break;
case 'lehrform_kurzbz':
$this->form_validation->set_rules($field, 'Lehrform', 'required|max_length[8]');
break;
case 'stundenblockung':
$this->form_validation->set_rules($field, 'Stundenblockung', 'required|integer|greater_than_equal_to[0]');
break;
case 'wochenrythmus':
$this->form_validation->set_rules($field, 'Wochenrhytmus', 'required|integer|greater_than_equal_to[0]');
break;
case 'start_kw':
$this->form_validation->set_rules($field, 'Start KW', 'integer|greater_than[0]|less_than_equal_to[53]');
break;
case 'gewicht':
$this->form_validation->set_rules($field, 'Gewicht', 'numeric|greater_than_equal_to[0]');
break;
case 'raumtyp':
$this->form_validation->set_rules($field, 'Raumtyp', 'required|max_length[16]');
break;
case 'raumtypalternativ':
$this->form_validation->set_rules($field, 'Raumtyp Alternativ', 'required|max_length[16]');
break;
case 'sprache':
$this->form_validation->set_rules($field, 'Sprache', 'required|max_length[16]');
break;
case 'lvnr':
$this->form_validation->set_rules($field, 'LVNR', 'integer');
break;
case 'unr':
$this->form_validation->set_rules($field, 'UNR', 'integer|greater_than_equal_to[0]');
break;
case 'lehre':
$this->form_validation->set_rules($field, 'Lehre', 'trim');
break;
case 'anmerkung':
$this->form_validation->set_rules($field, 'Anmerkung', 'trim');
break;
}
}
}
if ($this->form_validation->run() === false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$updateData = [];
foreach ($updatableFields as $field)
{
if (array_key_exists($field, $formData))
{
$updateData[$field] = $formData[$field];
}
}
$updateData['updatevon'] = $this->_uid;
$updateData['updateamum'] = date('Y-m-d H:i:s');
$result = $this->_ci->LehreinheitModel->update(
[
'lehreinheit_id' => $this->input->post('lehreinheit_id'),
],
$updateData
);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess($this->p->t('global', 'gespeichert'));
}
private function checkPermission($lehreinheit_id)
{
$result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$oe_array = [];
if (hasData($result))
$oe_array = getData($result);
if (!$this->_ci->permissionlib->isBerechtigtMultipleOe('admin', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('assistenz', $oe_array, 'suid') &&
!$this->_ci->permissionlib->isBerechtigtMultipleOe('lv-plan', $oe_array, 'suid'))
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
}
private function checkLehreinheit($lehreinheit_id)
{
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit_result) || isError($lehreinheit_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
return getData($lehreinheit_result)[0];
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
}
@@ -0,0 +1,409 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Lektor extends FHCAPI_Controller
{
private $_uid;
private $_ci;
public function __construct()
{
parent::__construct([
'add' => ['admin:rw', 'assistenz:rw'],
'update' => ['admin:rw', 'assistenz:rw'],
'cancelVertrag' => ['admin:rw', 'assistenz:rw'],
'deleteLVPlan' => ['admin:rw', 'assistenz:rw'],
'deletePerson' => ['admin:rw', 'assistenz:rw'],
'getLehrfunktionen' => ['admin:r', 'assistenz:r'],
'getLektoren' => ['admin:r', 'assistenz:r'],
'getLektorenByLE' => ['admin:r', 'assistenz:r'],
'getLektorDaten' => ['admin:r', 'assistenz:r'],
'getLektorVertrag' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
$this->_ci->load->library('PermissionLib');
$this->_ci->load->library('LektorLib');
$this->_ci->load->library('form_validation');
$this->loadPhrases([
'ui'
]);
$this->_ci->load->model('accounting/Vertrag_model', 'VertragModel');
$this->_ci->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->_ci->load->model('education/lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$this->_ci->load->model('ressource/stundenplandev_model', 'StundenplandevModel');
$this->_ci->load->model('ressource/Stundensatz_model', 'StundensatzModel');
}
private function checkMitarbeiter($mitarbeiter_uid)
{
if (is_null($mitarbeiter_uid))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
}
public function add()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkMitarbeiter($mitarbeiter_uid);
$lehrfach_permission = $this->checkLehrfachPermission($lehreinheit_id, array('assistenz', 'admin'));
$lehreinheit_permission = $this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan'));
if (!$lehrfach_permission && !$lehreinheit_permission)
$this->terminateWithError($this->p->t('ui', 'error_fieldWriteAccess'));
$result = $this->_ci->lektorlib->addLektorToLehreinheit($lehreinheit_id, $mitarbeiter_uid);
if (isError($result)) $this->terminateWithError(getError($result));
$this->terminateWithSuccess("Erfolgreich gespeichert");
}
public function update()
{
$formData = $this->input->post('formData');
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkMitarbeiter($mitarbeiter_uid);
$updatableFields = array(
'lehrfunktion_kurzbz',
'planstunden',
'stundensatz',
'faktor',
'anmerkung',
'bismelden',
'semesterstunden',
'mitarbeiter_uid'
);
$this->form_validation->set_data($formData);
foreach ($updatableFields as $field)
{
if (array_key_exists($field, $formData))
{
switch ($field)
{
case 'lehrfunktion_kurzbz':
$this->form_validation->set_rules($field, 'Lehrfunktion', 'required|max_length[16]');
break;
case 'planstunden':
$this->form_validation->set_rules($field, 'Planstunden', 'integer|greater_than_equal_to[0]');
break;
case 'stundensatz':
$formData['stundensatz'] = str_replace(',', '.', $formData['stundensatz']);
$this->form_validation->set_rules($field, 'Stundensatz', 'callback__check_stundensatz');
break;
case 'faktor':
$this->form_validation->set_rules($field, 'Faktor', 'numeric|greater_than_equal_to[0]');
break;
case 'anmerkung':
$this->form_validation->set_rules($field, 'Anmerkung', 'max_length[256]');
break;
case 'bismelden':
$this->form_validation->set_rules($field, 'Bis Melden', 'trim');
break;
case 'semesterstunden':
$formData['semesterstunden'] = str_replace(',', '.', $formData['semesterstunden']);
$this->form_validation->set_rules($field, 'Semesterstunden', 'callback__check_semesterstunden');
break;
case 'mitarbeiter_uid':
$this->form_validation->set_rules($field, 'Semesterstunden', 'required|max_length[32]');
break;
}
}
}
if (!$this->form_validation->run())
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
if (isset($formData['semesterstunden']) && (!is_numeric($formData['semesterstunden']) || $formData['semesterstunden'] === ''))
{
$formData['semesterstunden'] = null;
}
$lehreinheit_permission = $this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan'));
if (!$lehreinheit_permission)
$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));
$this->terminateWithSuccess($result);
}
public function _check_stundensatz($value)
{
$value = str_replace(',', '.', $value);
if (!is_numeric($value))
{
$this->form_validation->set_message('_check_decimal', 'Das Feld {field} muss eine Zahl sein.');
return false;
}
if ($value < 0 || $value >= 10000) {
$this->form_validation->set_message('_check_decimal', 'Das Feld {field} muss zwischen 0 und 10000 liegen.');
return false;
}
return true;
}
public function _check_semesterstunden($value)
{
if ($value === null || $value === '') {
return true;
}
if (!is_numeric($value))
{
$this->form_validation->set_message(
'_check_semesterstunden',
'Das Feld {field} muss eine Zahl sein.'
);
return false;
}
if ($value < 0)
{
$this->form_validation->set_message(
'_check_semesterstunden',
'Das Feld {field} muss eine Zahl größer oder gleich 0 sein.'
);
return false;
}
if ($value > 999.99)
{
$this->form_validation->set_message(
'_check_semesterstunden',
'Das Feld {field} darf maximal 999,99 betragen.'
);
return false;
}
return true;
}
public function getLehrfunktionen()
{
$this->_ci->load->model('education/Lehrfunktion_model', 'LehrfunktionModel');
$this->_ci->LehrfunktionModel->addOrder('lehrfunktion_kurzbz');
$this->terminateWithSuccess(getData($this->_ci->LehrfunktionModel->load()));
}
public function getLektoren()
{
$this->_ci->MitarbeiterModel->addSelect('uid, person_id, vorname, nachname');
$this->_ci->MitarbeiterModel->addJoin('public.tbl_benutzer', 'uid = mitarbeiter_uid');
$this->_ci->MitarbeiterModel->addJoin('public.tbl_person', 'person_id');
$this->terminateWithSuccess(getData($this->_ci->MitarbeiterModel->loadWhere(array('public.tbl_benutzer.aktiv' => true))));
}
private function checkLehreinheit($lehreinheit_id)
{
if (is_null($lehreinheit_id) || !ctype_digit((string)$lehreinheit_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$lehreinheit_result = $this->_ci->LehreinheitModel->load($lehreinheit_id);
if (!hasData($lehreinheit_result) || isError($lehreinheit_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
return getData($lehreinheit_result)[0];
}
public function getLektorenByLE($lehreinheit_id = null)
{
$this->checkLehreinheit($lehreinheit_id);
$le_mitarbeiter_data = $this->_ci->LehreinheitmitarbeiterModel->getLektorenByLe($lehreinheit_id);
$this->terminateWithSuccess(hasData($le_mitarbeiter_data) ? getData($le_mitarbeiter_data) : array());
}
public function getLektorDaten($lehreinheit_id = null, $mitarbeiter_uid = null)
{
$lehreinheit = $this->checkLehreinheit($lehreinheit_id);
if (is_null($mitarbeiter_uid))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$studiensemester_result = $this->_ci->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz' => $lehreinheit->studiensemester_kurzbz));
$studiensemester = getData($studiensemester_result)[0];
$defaultStundensatz = $this->_ci->StundensatzModel->getDefaultStundensatz($mitarbeiter_uid, $studiensemester->start, $studiensemester->ende, 'lehre');
$le_mitarbeiter_result = $this->_ci->LehreinheitmitarbeiterModel->getByLeLektor($lehreinheit_id, $mitarbeiter_uid);
$le_mitarbeiter_data = array();
if (hasData($le_mitarbeiter_result))
{
$le_mitarbeiter_data = getData($le_mitarbeiter_result)[0];
$le_mitarbeiter_data->default_stundensatz = $defaultStundensatz;
}
$vertrag = $this->getLektorVertrag($lehreinheit_id, $mitarbeiter_uid);
$le_mitarbeiter_data->vertrag = $vertrag;
$this->terminateWithSuccess($le_mitarbeiter_data);
}
private function getLektorVertrag($lehreinheit_id = null, $mitarbeiter_uid = null)
{
$this->_ci->load->model('accounting/Vertrag_model', 'VertragModel');
$vertrag = $this->_ci->VertragModel->getVertrag($mitarbeiter_uid, $lehreinheit_id);
return hasData($vertrag) ? getData($vertrag)[0] : null;
}
private function checkLehrfachPermission($lehreinheit_id, $permissions)
{
$lehrfach_oe_kurzbz = $this->_ci->LehreinheitModel->getLehrfachOe($lehreinheit_id);
if (isError($lehrfach_oe_kurzbz))
$this->terminateWithError(getError($lehrfach_oe_kurzbz), self::ERROR_TYPE_GENERAL);
$lehrfach_oe_kurzbz = array('');
if (hasData($lehrfach_oe_kurzbz))
$lehrfach_oe_kurzbz = array_column(getData($lehrfach_oe_kurzbz), 'oe_kurzbz');
return $this->checkPermissionGenerel($permissions, $lehrfach_oe_kurzbz);
}
private function checkPermissionGenerel($permissions, $oe_array)
{
$hasPermission = false;
foreach ($permissions as $permission)
{
if ($this->_ci->permissionlib->isBerechtigtMultipleOe($permission, $oe_array, 'suid'))
{
$hasPermission = true;
break;
}
}
return $hasPermission;
}
private function checkPermission($lehreinheit_id, $permissions)
{
$result = $this->_ci->LehreinheitModel->getOes($lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$oe_array = [];
if (hasData($result))
$oe_array = getData($result);
return $this->checkPermissionGenerel($permissions, $oe_array);
}
public function cancelVertrag()
{
$vertrag_id = $this->input->post('vertrag_id');
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit_id, array('admin', 'lehre/lehrauftrag_bestellen'));
if (is_null($vertrag_id) || !ctype_digit((string)$vertrag_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$vertrag_result = $this->_ci->VertragModel->load($vertrag_id);
if (!hasData($vertrag_result) || isError($vertrag_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
if (is_null($mitarbeiter_uid))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$result = $this->_ci->VertragModel->cancelVertrag($vertrag_id, $mitarbeiter_uid);
if (isError($result))
$this->terminateWithError(getError($result));
$this->terminateWithSuccess($result);
}
public function deletePerson()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit_id, array('admin', 'assistenz', 'lv-plan'));
if (is_null($mitarbeiter_uid))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$delete_result =$this->_ci->LehreinheitmitarbeiterModel->deleteLektorFromLe($lehreinheit_id, $mitarbeiter_uid);
if (isError($delete_result))
$this->terminateWithError(getError($delete_result));
$this->terminateWithSuccess($delete_result);
}
public function deleteLVPlan()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit_id, array('lv-plan/lektorentfernen'));
if (is_null($mitarbeiter_uid))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$mitarbeiter_result = $this->_ci->MitarbeiterModel->load($mitarbeiter_uid);
if (!hasData($mitarbeiter_result) || isError($mitarbeiter_result))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$delete_result = $this->_ci->StundenplandevModel->deleteLektorPlanning($lehreinheit_id, $mitarbeiter_uid);
if (isError($delete_result))
$this->terminateWithError(getError($delete_result));
$this->terminateWithSuccess($delete_result);
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
}
@@ -0,0 +1,121 @@
<?php
/**
* Copyright (C) 2025 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');
class Setup extends FHCAPI_Controller
{
private $_ci;
private $_uid;
public function __construct()
{
parent::__construct([
'getTabs' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r'],
'getSprache' => ['admin:r', 'assistenz:r'],
'getRaumtyp' => ['admin:r', 'assistenz:r'],
'getLehrform' => ['admin:r', 'assistenz:r'],
]);
$this->_ci = &get_instance();
$this->_setAuthUID();
$this->_ci->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->_ci->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->_ci->load->library('VariableLib', ['uid' => $this->_uid]);
}
public function getTabs()
{
$tabs['details'] = array (
'title' => 'Details',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Details.js',
'config' => []
);
$tabs['gruppen'] = array (
'title' => 'Gruppen',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Gruppen.js',
'config' => []
);
$tabs['lektor'] = array (
'title' => 'LektorInnenzuteilung',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Lektor.js',
'config' => []
);
$tabs['notiz'] = array (
'title' => 'Notizen',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Notiz.js',
'config' => []
);
$this->terminateWithSuccess($tabs);
}
public function getStudiensemester()
{
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->_ci->StudiensemesterModel->addOrder('start', 'DESC');
$this->terminateWithSuccess(getData($this->_ci->StudiensemesterModel->load()));
}
public function getSprache()
{
$this->_ci->load->model('system/Sprache_model', 'SpracheModel');
$this->terminateWithSuccess(getData($this->_ci->SpracheModel->load()));
}
public function getRaumtyp()
{
$this->_ci->load->model('ressource/Raumtyp_model', 'RaumtypModel');
$this->_ci->RaumtypModel->addOrder('raumtyp_kurzbz');
$this->terminateWithSuccess(getData($this->_ci->RaumtypModel->loadWhere(array('aktiv' => true))));
}
public function getLehrform()
{
$language = $this->_getLanguageIndex();
$this->_ci->load->model('codex/lehrform_model', 'LehrformModel');
$this->_ci->LehrformModel->addSelect(
'*,
bezeichnung_kurz[('.$language.')] as bez_kurz,
bezeichnung_lang[('.$language.')] as bez
'
);
$this->terminateWithSuccess(getData($this->_ci->LehrformModel->load()));
}
private function _getLanguageIndex()
{
$this->_ci->load->model('system/Sprache_model', 'SpracheModel');
$this->_ci->SpracheModel->addSelect('index');
$result = $this->_ci->SpracheModel->loadWhere(array('sprache' => getUserLanguage()));
return hasData($result) ? getData($result)[0]->index : 1;
}
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid)
show_error('User authentification failed');
}
}
@@ -0,0 +1,117 @@
<?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);
}
}
@@ -0,0 +1,50 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Tags extends Tag_Controller
{
const BERECHTIGUNG_KURZBZ = ['admin:rw', 'assistenz:rw'];
public function __construct()
{
parent::__construct([
'getTag' => self::BERECHTIGUNG_KURZBZ,
'getTags' => self::BERECHTIGUNG_KURZBZ,
'addTag' => self::BERECHTIGUNG_KURZBZ,
'updateTag' => self::BERECHTIGUNG_KURZBZ,
'doneTag' => self::BERECHTIGUNG_KURZBZ,
'deleteTag' => self::BERECHTIGUNG_KURZBZ,
'updateLehre' => self::BERECHTIGUNG_KURZBZ,
'doneLehre' => self::BERECHTIGUNG_KURZBZ,
'deleteLehre' => self::BERECHTIGUNG_KURZBZ,
]);
$this->config->load('lvverwaltung');
}
public function getTag($readonly_tags = null)
{
parent::getTag($this->config->item('lvverwaltung_tags'));
}
public function getTags($tags = null)
{
parent::getTags($this->config->item('lvverwaltung_tags'));
}
public function addTag($withZuordnung = true, $updatable_tags = null)
{
parent::addTag(true, $this->config->item('lvverwaltung_tags'));
}
public function updateTag($updatable_tags = null)
{
parent::updateTag($this->config->item('lvverwaltung_tags'));
}
public function deleteTag($withZuordnung = true, $updatable_tags = null)
{
parent::deleteTag(true, $this->config->item('lvverwaltung_tags'));
}
public function doneTag($updatable_tags = null)
{
parent::doneTag($this->config->item('lvverwaltung_tags'));
}
}
@@ -0,0 +1,466 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Messages extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getMessages' => ['admin:r', 'assistenz:r'],
'getVorlagen' => ['admin:r', 'assistenz:r'],
'getMessageVarsPerson' => ['admin:r', 'assistenz:r'],
'getMsgVarsPrestudent' => ['admin:r', 'assistenz:r'],
'getMsgVarsLoggedInUser' => ['admin:r', 'assistenz:r'],
'getNameOfDefaultRecipient' => ['admin:r', 'assistenz:r'],
'sendMessage' => ['admin:r', 'assistenz:r'],
'deleteMessage' => ['admin:r', 'assistenz:r'],
'getVorlagentext' => ['admin:r', 'assistenz:r'],
'getPreviewText' => ['admin:r', 'assistenz:r'],
'getReplyData' => ['admin:r', 'assistenz:r'],
'getPersonId' => ['admin:r', 'assistenz:r'],
'getUid' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('system/Message_model', 'MessageModel');
$this->load->model('CL/Messages_model', 'MessagesModel');
// Additional Permission Checks
//TODO(manu) check permissions
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
$this->load->library('MessageLib');
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function getMessages($id, $type_id, $size, $page)
{
if($type_id != 'person_id'){
$id = $this->_getPersonId($id, $type_id);
}
$offset = $size * ($page - 1);
$limit = $size;
$result = $this->MessageModel->getMessagesForTable($id, $offset, $limit);
$data = $this->getDataOrTerminateWithError($result);
$this->addMeta('count', $data['count']);
$this->terminateWithSuccess($data['data']);
}
public function getVorlagen()
{
//get oe of user
$uid = getAuthUID();
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung');
$data = $this->getDataOrTerminateWithError($result);
$oe_kurzbz = current($data);
$this->load->model('system/Vorlage_model', 'VorlageModel');
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
//If admin
$this->VorlageModel->addOrder('vorlage_kurzbz', 'ASC');
$result = $this->VorlageModel->loadWhere(
array(
'mimetype' => 'text/html'
));
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getVorlagentext($vorlage_kurzbz)
{
//$this->terminateWithError("vor " . $vorlage_kurzbz, self::ERROR_TYPE_GENERAL);
//$studiengang_kz = 227; //TODO(Manu) dynamisieren NULL
$studiengang_kz = 0;
$this->load->model('system/Vorlagestudiengang_model', 'VorlagestudiengangModel');
$this->VorlagestudiengangModel->addOrder('version', 'DESC');
$result = $this->VorlagestudiengangModel->loadWhere(
[
'vorlage_kurzbz' =>$vorlage_kurzbz,
'studiengang_kz' => $studiengang_kz
]);
$data = $this->getDataOrTerminateWithError($result);
//not correct with Vorlage
$vorlage = current($data);
//$this->terminateWithSuccess($data);
$this->terminateWithSuccess($vorlage->text);
}
public function getMessageVarsPerson($id, $typeId)
{
$person_id = ($typeId == 'mitarbeiter_uid') ? $this->_getPersonId($id, $typeId) : $id;
$result = $this->MessageModel->getMsgVarsDataByPersonId($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getMsgVarsPrestudent($id, $typeId)
{
$prestudent_id = ($typeId == 'uid') ? $this->_getPrestudentIdFromUid($id) : $id;
$result = $this->MessageModel->getMsgVarsDataByPrestudentId($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getMsgVarsLoggedInUser()
{
$result = $this->MessageModel->getMsgVarsLoggedInUser();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getNameOfDefaultRecipient($id, $type_id)
{
$id = ($type_id != 'person_id') ? $this->_getPersonId($id, $type_id) : $id;
$this->load->model('person/Person_model', 'PersonModel');
$result = $this->PersonModel->load($id);
$data = $this->getDataOrTerminateWithError($result);
$name = current($data);
$this->terminateWithSuccess($name->vorname . " " . $name->nachname );
}
public function sendMessage($recipient_id)
{
//has to be uid
// $this->terminateWithError("uid", $recipient_id, self::ERROR_TYPE_GENERAL);
//default setting
$receiversPersonId = $this->_getPersonId($recipient_id, 'uid');
$uid = getAuthUID();
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['uid' => $uid]
);
$data = $this->getDataOrTerminateWithError($result);
$benutzer = current($data);
if (isset($_POST['data']))
{
$data = json_decode($_POST['data']);
unset($_POST['data']);
foreach ($data as $k => $v) {
$_POST[$k] = $v;
}
}
$this->load->library('form_validation');
$this->form_validation->set_rules('subject', 'Betreff', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Betreff'])
]);
$this->form_validation->set_rules('body', 'Text', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Text'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$subject = $this->input->post('subject');
$body = $this->input->post('body');
$relationmessage_id = $this->input->post('relationmessage_id');
$typeId = $this->input->post('type_id');
$id = $this->input->post('id');
if($typeId == 'uid')
{
$prestudent_id = $this-> _getPrestudentIdFromUid($id);
//parseMessagetext for variables Prestudent
$result = $this->MessagesModel->parseMessageTextPrestudent($prestudent_id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
}
if($typeId == 'mitarbeiter_uid')
{
$person_id = $this->_getPersonId($id, $typeId);
$result = $this->MessagesModel->parseMessageTextPerson($person_id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
$this->terminateWithError($bodyParsed, self::ERROR_TYPE_GENERAL);
}
elseif($typeId == 'person_id')
{
$result = $this->MessagesModel->parseMessageTextPerson($id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
}
elseif($typeId == 'prestudent_id')
{
// $this->terminateWithError("prestudent_id ", self::ERROR_TYPE_GENERAL);
$result = $this->MessagesModel->parseMessageTextPrestudent($id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
}
else
{
$this->terminateWithError("type_id " . $typeId . " not valid", self::ERROR_TYPE_GENERAL);
}
$result = $this->messagelib->sendMessageUser($receiversPersonId, $subject, $bodyParsed, $benutzer->person_id, null, $relationmessage_id);
$this->terminateWithSuccess($result);
}
public function getPreviewText($id, $type_id)
{
if (isset($_POST['data']))
{
$data = json_decode($_POST['data']);
unset($_POST['data']);
}
else
$this->terminateWithError("Textbody missing ", self::ERROR_TYPE_GENERAL);
switch($type_id)
{
case 'uid':
$prestudent_id = $this->_getPrestudentIdFromUid($id);
$result = $this->MessagesModel->parseMessageTextPrestudent($prestudent_id, $data);
break;
case 'prestudent_id':
$result = $this->MessagesModel->parseMessageTextPrestudent($id, $data);
break;
case 'person_id':
$result = $this->MessagesModel->parseMessageTextPerson($id, $data);
break;
case 'mitarbeiter_uid':
{
$person_id = $this->_getPersonId($id, $type_id);
$result = $this->MessagesModel->parseMessageTextPerson($person_id, $data);
}
break;
default:
$this->terminateWithError("MESSAGES::getPreviewText logic for type_id " . $type_id . " not defined yet", self::ERROR_TYPE_GENERAL);
break;
}
$bodyParsed = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($bodyParsed);
}
public function getReplyData($messageId)
{
//TODO(Manu) validation of messageId: if number
$this->MessageModel->addSelect('public.tbl_msg_message.*');
$this->MessageModel->addSelect('r.*');
$this->MessageModel->addSelect('p.nachname');
$this->MessageModel->addSelect('p.vorname');
$this->MessageModel->addJoin('public.tbl_msg_recipient r', 'ON (r.message_id = public.tbl_msg_message.message_id)');
$this->MessageModel->addJoin('public.tbl_person p', 'ON (p.person_id = public.tbl_msg_message.person_id)');
$result = $this->MessageModel->loadWhere(
array('r.message_id' => $messageId)
);
$dataMessage = $this->getDataOrTerminateWithError($result);
$prefix = "Re: "; // reply subject prefix
$subject = $dataMessage[0]->subject;
$body = $dataMessage[0]->body;
$replyBody = $this->_getReplyBody($body, $dataMessage[0]->nachname, $dataMessage[0]->vorname, $dataMessage[0]->insertamum);
$dataMessage[0]->replyBody = $replyBody;
$dataMessage[0]->rest = "Help Manu";
$dataMessage[0]->replySubject = $prefix . $subject;
$this->terminateWithSuccess($dataMessage);
}
public function deleteMessage($messageId)
{
// Start DB transaction
$this->db->trans_begin();
$result = $this->MessageModel->deleteMessageRecipient($messageId);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$result = $this->MessageModel->deleteMessageStatus($messageId);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$result = $this->MessageModel->deleteMessage($messageId);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->db->trans_commit();
$this->terminateWithSuccess($result);
}
public function getPersonId($id, $typeId)
{
if ($typeId == 'uid' || $typeId == 'mitarbeiter_uid')
{
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['uid' => $id]
);
}
elseif($typeId == 'prestudent_id')
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $id]
);
}
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
$this->terminateWithSuccess($person->person_id);
}
public function getUid($id, $typeId)
{
if (!$typeId)
{
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Type ID']), self::ERROR_TYPE_GENERAL);
}
elseif ($typeId == 'person_id')
{
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['person_id' => $id]
);
}
elseif($typeId == 'prestudent_id')
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $id]
);
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
$person_id = $person->person_id;
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['person_id' => $person_id]
);
}
elseif($typeId == 'uid' || $typeId == 'mitarbeiter_uid')
{
$this->terminateWithSuccess($id);
}
else
{
$this->terminateWithError("MESSAGES::getUID logic for type_id " . $typeId . " not defined yet", self::ERROR_TYPE_GENERAL);
}
$data = $this->getDataOrTerminateWithError($result);
$benutzer = current($data);
$this->terminateWithSuccess($benutzer->uid);
}
private function _getPersonId($id, $typeId)
{
if ($typeId == 'uid' || $typeId == 'mitarbeiter_uid')
{
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['uid' => $id]
);
}
elseif($typeId == 'prestudent_id')
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $id]
);
}
$data = $this->getDataOrTerminateWithError($result);
if (count($data) < 1)
{
$this->terminateWithError('Error: Messages API no person_id found.');
}
$person = current($data);
return $person->person_id;
}
private function _getPrestudentIdFromUid($uid)
{
// $this->terminateWithError($uid, self::ERROR_TYPE_GENERAL);
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->loadWhere(
['student_uid' => $uid]
);
$data = $this->getDataOrTerminateWithError($result);
if (count($data) < 1)
{
$this->terminateWithError('Error: Messages API no prestudent_id found.');
}
$student = current($data);
return $student->prestudent_id;
}
private function _getReplyBody($body, $receiverName, $receiverSurname, $sentDate)
{
// To quote a reply body message
$bodyFormat = "<br>
<br>
<blockquote>
<i>
On %s %s %s wrote:
</i>
</blockquote>
<blockquote style='border-left:2px solid; padding-left: 8px'>
%s
</blockquote>";
return sprintf(
$bodyFormat,
date_format(date_create($sentDate), 'd.m.Y H:i'), $receiverName, $receiverSurname, $body
);
}
}
@@ -0,0 +1,21 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class NotizLehreinheit extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'getUid' => ['admin:r', 'assistenz:r'],
'getNotizen' => ['admin:r', 'assistenz:r'],
'loadNotiz' => ['admin:r', 'assistenz:r'],
'addNewNotiz' => ['admin:rw', 'assistenz:rw'],
'updateNotiz' => ['admin:rw', 'assistenz:rw'],
'deleteNotiz' => ['admin:rw', 'assistenz:rw'],
'loadDokumente' => ['admin:r', 'assistenz:r'],
'getMitarbeiter' => ['admin:r', 'assistenz:r'],
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
}
}
@@ -18,6 +18,7 @@ class NotizPerson extends Notiz_Controller
'loadDokumente' => ['admin:r', 'assistenz:r'],
'getMitarbeiter' => ['admin:r', 'assistenz:r'],
'isBerechtigt' => ['admin:r', 'assistenz:r'],
'getCountNotes' => ['admin:r', 'assistenz:r'],
]);
}
@@ -0,0 +1,57 @@
<?php
/**
* FH-Complete
*
* @package FHC-API
* @author FHC-Team
* @copyright Copyright (c) 2016, fhcomplete.org
* @license GPLv3
* @link http://fhcomplete.org
* @since Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
if (!defined('BASEPATH')) exit('No direct script access allowed');
class StudiengangEP extends FHCAPI_Controller
{
/**
* StudiengangEP API constructor.
*/
public function __construct()
{
parent::__construct(
array(
'getStudiengangByKz' => self::PERM_LOGGED
)
);
// Load model StudiengangModel
$this->load->model('organisation/studiengang_model', 'StudiengangModel');
}
/**
* @return void
*/
public function getStudiengangByKz()
{
$studiengang_kz = intval($this->input->get('studiengang_kz'));
$this->StudiengangModel->addSelect('studiengang_kz, kurzbz, kurzbzlang, '
. 'typ, bezeichnung, english, aktiv, orgform_kurzbz, sprache, '
. 'oe_kurzbz');
$result = $this->StudiengangModel->load($studiengang_kz);
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
$stg = null;
if(hasData($result))
{
$stg = (getData($result))[0];
}
$this->terminateWithSuccess($stg);
}
}
@@ -0,0 +1,80 @@
<?php
/**
* FH-Complete
*
* @package FHC-API
* @author FHC-Team
* @copyright Copyright (c) 2016, fhcomplete.org
* @license GPLv3
* @link http://fhcomplete.org
* @since Version 1.0
* @filesource
*/
// ------------------------------------------------------------------------
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Studienjahr extends FHCAPI_Controller
{
/**
* Studienjahr API constructor.
*/
public function __construct()
{
parent::__construct(
array(
'getAll' => self::PERM_LOGGED,
'getNext' => self::PERM_LOGGED
)
);
// Load model StudiensemesterModel
$this->load->model('organisation/studienjahr_model', 'StudienjahrModel');
}
/**
* Get all Studienjahre.
*
* @param null|string $order Sorting order for the Studienjahr, 'asc' or 'desc'. Defaults to 'asc'.
* @param null|string $start Starting Studienjahre with given studienjahr_kurzbz
*/
public function getAll()
{
$order = $this->input->get('order');
$start = $this->input->get('studienjahr_kurzbz');
if (strcasecmp($order, 'DESC') == 0) {
$this->StudienjahrModel->addOrder('studienjahr_kurzbz', 'DESC');
} else {
$this->StudienjahrModel->addOrder('studienjahr_kurzbz', 'ASC');
}
if ($start) {
$result = $this->StudienjahrModel->loadWhere([
'studienjahr_kurzbz >= ' => $start
]);
} else {
$result = $this->StudienjahrModel->load();
}
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getNext()
{
$this->StudienjahrModel->addJoin('public.tbl_studiensemester', 'studienjahr_kurzbz');
$this->StudienjahrModel->addOrder('start');
$this->StudienjahrModel->addLimit(1);
$result = $this->StudienjahrModel->loadWhere(['start >' => 'NOW()']);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
$this->terminateWithSuccess(current(getData($result)));
}
}
@@ -24,7 +24,8 @@ class Studiensemester extends FHCAPI_Controller
parent::__construct(
array(
'getAll' => self::PERM_LOGGED,
'getAktNext' => self::PERM_LOGGED
'getAktNext' => self::PERM_LOGGED,
'getStudienjahrByStudiensemester' => self::PERM_LOGGED
)
);
// Load model StudiensemesterModel
@@ -115,4 +116,40 @@ class Studiensemester extends FHCAPI_Controller
$this->terminateWithSuccess((getData($result) ?: ''));
}
/**
* Get Studienjahr by Studiensemester.
* input param semester: studiensemester_kurzbz
*/
public function getStudienjahrByStudiensemester()
{
$semester = $this->input->get('semester');
$studienjahrObj = null;
if (!is_numeric($semester))
{
$this->StudiensemesterModel->addSelect('studienjahr_kurzbz');
$result = $this->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz =' => $semester));
}
if (hasData($result))
{
$studienjahr = getData($result)[0]->studienjahr_kurzbz;
$startstudienjahr = substr($studienjahr, 0, 4);
$endstudienjahr = substr($studienjahr, 0, 2) . substr($studienjahr, -2);
$studienjahrObj = new StdClass();
$studienjahrObj->studienjahr_kurzbz = $studienjahr;
$studienjahrObj->startstudienjahr = $startstudienjahr;
$studienjahrObj->endstudienjahr= $endstudienjahr;
}
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
$this->terminateWithSuccess((getData(success($studienjahrObj))));
}
}
@@ -0,0 +1,501 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Abschlusspruefung extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAbschlusspruefung' => ['admin:r', 'assistenz:r'],
'loadAbschlusspruefung' => ['admin:r', 'assistenz:r'],
'insertAbschlusspruefung' => ['admin:rw', 'assistenz:rw'],
'updateAbschlusspruefung' => ['admin:rw', 'assistenz:rw'],
'deleteAbschlusspruefung' => ['admin:rw', 'assistenz:rw'],
'getTypenAbschlusspruefung' => ['admin:rw', 'assistenz:rw'],
'getNoten' => ['admin:rw', 'assistenz:rw'],
'getTypenAntritte' => ['admin:rw', 'assistenz:rw'],
'getBeurteilungen' => ['admin:rw', 'assistenz:rw'],
'getAkadGrade' => ['admin:rw', 'assistenz:rw'],
'getMitarbeiter' => ['admin:rw', 'assistenz:rw'],
'getAllMitarbeiter' => ['admin:rw', 'assistenz:rw'],
'getAllPersons' => ['admin:rw', 'assistenz:rw'],
'getPruefer' => ['admin:rw', 'assistenz:rw'],
'getTypStudiengang' => ['admin:rw', 'assistenz:rw'],
'checkForExistingExams' => ['admin:rw', 'assistenz:rw'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'person',
'abschlusspruefung'
]);
// Load models
$this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel');
//Permission checks for Studiengangsarray
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
if ($this->router->method == 'insertAbschlusspruefung' || $this->router->method == 'updateAbschlusspruefung')
{
$student_uid = $this->input->post('uid') ?: ($this->input->post('formData')['student_uid'] ?? null);
if(!$student_uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedStgsFromUid($student_uid, $allowedStgs);
}
if ($this->router->method == 'deleteAbschlusspruefung')
{
$abschlusspruefung_id = $this->input->post('id');
if(!$abschlusspruefung_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Abschlusspruefung ID']), self::ERROR_TYPE_GENERAL);
}
$result = $this->AbschlusspruefungModel->load(
array('abschlusspruefung_id' => $abschlusspruefung_id)
);
$data = $this->getDataOrTerminateWithError($result);
$student_uid = current($data)->student_uid;
$this->_checkAllowedStgsFromUid($student_uid, $allowedStgs);
}
}
private function _checkAllowedStgsFromUid($student_uid, $allowedStgs)
{
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]);
$data = $this->getDataOrTerminateWithError($result);
$studiengang_kz = current($data)->studiengang_kz;
if (!in_array($studiengang_kz, $allowedStgs))
{
return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL);
}
}
public function getAbschlusspruefung($student_uid)
{
$result = $this->AbschlusspruefungModel->getAbschlusspruefungForPrestudent($student_uid);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function loadAbschlusspruefung()
{
$abschlusspruefung_id = $this->input->post('id');
$this->AbschlusspruefungModel->addSelect('lehre.tbl_abschlusspruefung.*');
$this->AbschlusspruefungModel->addSelect("
CASE
WHEN pruefer1 IS NOT NULL
THEN CONCAT(p1.nachname, ' ', p1.vorname, COALESCE(' ' || p1.titelpre, ''))
ELSE NULL
END AS p1
");
$this->AbschlusspruefungModel->addSelect("
CASE
WHEN pruefer2 IS NOT NULL
THEN CONCAT(p2.nachname, ' ', p2.vorname, COALESCE(' ' || p2.titelpre, ''))
ELSE NULL
END AS p2
");
$this->AbschlusspruefungModel->addSelect("
CASE
WHEN pruefer3 IS NOT NULL
THEN CONCAT(p3.nachname, ' ', p3.vorname, COALESCE(' ' || p3.titelpre, ''))
ELSE NULL
END AS p3
");
$this->AbschlusspruefungModel->addSelect("
CASE
WHEN vorsitz IS NOT NULL
THEN CONCAT(pv.nachname, ' ', pv.vorname, COALESCE(' ' || pv.titelpre, ''), ' (', ben.uid , ')' )
ELSE NULL
END AS pv
");
$this->AbschlusspruefungModel->addJoin('public.tbl_benutzer ben', 'ON (ben.uid = lehre.tbl_abschlusspruefung.vorsitz)', 'LEFT');
$this->AbschlusspruefungModel->addJoin('public.tbl_person pv', 'ON (pv.person_id = ben.person_id)', 'LEFT');
$this->AbschlusspruefungModel->addJoin('public.tbl_person p1', 'ON (p1.person_id = lehre.tbl_abschlusspruefung.pruefer1)', 'LEFT');
$this->AbschlusspruefungModel->addJoin('public.tbl_person p2', 'ON (p2.person_id = lehre.tbl_abschlusspruefung.pruefer2)', 'LEFT');
$this->AbschlusspruefungModel->addJoin('public.tbl_person p3', 'ON (p3.person_id = lehre.tbl_abschlusspruefung.pruefer3)', 'LEFT');
$result = $this->AbschlusspruefungModel->loadWhere(
array('abschlusspruefung_id' => $abschlusspruefung_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function getTypenAbschlusspruefung()
{
$this->load->model('education/Pruefungstyp_model', 'PruefungstypModel');
$result = $this->PruefungstypModel->loadWhere(
array('abschluss' => true)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getTypenAntritte()
{
$this->load->model('education/Pruefungsantritt_model', 'PruefungsantrittModel');
$result = $this->PruefungsantrittModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getBeurteilungen()
{
$this->load->model('education/Abschlussbeurteilung_model', 'AbschlussbeurteilungModel');
$result = $this->AbschlussbeurteilungModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAkadGrade()
{
$studiengang_kz= $this->input->post('studiengang_kz');
$this->load->model('education/Akadgrad_model', 'AkadgradModel');
$result = $this->AkadgradModel->loadWhere(
array('studiengang_kz' => $studiengang_kz)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getTypStudiengang()
{
$studiengang_kz= $this->input->post('studiengang_kz');
/* if (!$studiengang_kzs || !is_array($studiengang_kzs)) {
$this->load->library('form_validation');
$this->form_validation->set_rules('studiengang_kzs', '', 'required|is_null', [
'is_null' => $this->p->t('ui', 'error_fieldMustBeArray')
]);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}*/
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$result = $this->StudiengangModel->loadWhere(
array('studiengang_kz' => $studiengang_kz)
);
$data = $this->getDataOrTerminateWithError($result);
$typStudiengang = current($data)->typ;
$this->terminateWithSuccess($typStudiengang);
}
public function getMitarbeiter($searchString)
{
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'mitAkadGrad');
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess($result ?: []);
}
public function getPruefer($searchString)
{
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'ohneMaUid');
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess($result ?: []);
}
public function getNoten()
{
$this->load->model('education/Note_model', 'NoteModel');
$this->NoteModel->addOrder('note', 'ASC');
$result = $this->NoteModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function insertAbschlusspruefung()
{
$this->load->library('form_validation');
$student_uid = $this->input->post('uid');
if(!$student_uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('pruefungstyp_kurzbz', 'Typ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ'])
]);
$this->form_validation->set_rules('akadgrad_id', 'AkadGrad', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'AkadGrad'])
]);
$this->form_validation->set_rules('datum', 'Datum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Datum'])
]);
$this->form_validation->set_rules('sponsion', 'Sponsion', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Sponsion'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->AbschlusspruefungModel->insert([
'student_uid' => $student_uid,
'pruefungstyp_kurzbz' => $formData['pruefungstyp_kurzbz'],
'akadgrad_id' => $formData['akadgrad_id'],
'vorsitz' => $formData['vorsitz'],
'pruefungsantritt_kurzbz' => $formData['pruefungsantritt_kurzbz'],
'abschlussbeurteilung_kurzbz' => $formData['abschlussbeurteilung_kurzbz'],
'datum' => $formData['datum'], //TODO(Manu) check if minute format like FAS
'sponsion' => $formData['sponsion'],
'pruefer1' => $formData['pruefer1'],
'pruefer2' => $formData['pruefer2'],
'pruefer3' => $formData['pruefer3'],
'protokoll' => $formData['protokoll'],
'note' => $formData['note'],
'anmerkung' => $formData['anmerkung'],
'insertamum' => date('c'),
'insertvon' => getAuthUID()
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function updateAbschlusspruefung()
{
$this->load->library('form_validation');
$abschlusspruefung_id = $this->input->post('id');
if(!$abschlusspruefung_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Abschlussprüfung ID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$vorsitz = isset($formData['vorsitz']['mitarbeiter_uid']) ? $formData['vorsitz']['mitarbeiter_uid'] : $formData['vorsitz'];
$pruefer1 = isset($formData['pruefer1']['person_id']) ? $formData['pruefer1']['person_id'] : $formData['pruefer1'];
$pruefer2 = isset($formData['pruefer2']['person_id']) ? $formData['pruefer2']['person_id'] : $formData['pruefer2'];
$pruefer3 = isset($formData['pruefer3']['person_id']) ? $formData['pruefer3']['person_id'] : $formData['pruefer3'];
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('pruefungstyp_kurzbz', 'Typ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ'])
]);
$this->form_validation->set_rules('akadgrad_id', 'AkadGrad', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'AkadGrad'])
]);
$this->form_validation->set_rules('datum', 'Datum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Datum'])
]);
$this->form_validation->set_rules('sponsion', 'Sponsion', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Sponsion'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->AbschlusspruefungModel->update(
[
'abschlusspruefung_id' => $abschlusspruefung_id
],
[
'student_uid' => $formData['student_uid'],
'pruefungstyp_kurzbz' => $formData['pruefungstyp_kurzbz'],
'akadgrad_id' => $formData['akadgrad_id'],
'vorsitz' => $vorsitz,
'pruefungsantritt_kurzbz' => $formData['pruefungsantritt_kurzbz'],
'abschlussbeurteilung_kurzbz' => $formData['abschlussbeurteilung_kurzbz'],
'datum' => $formData['datum'],
'sponsion' => $formData['sponsion'],
'pruefer1' => $pruefer1,
'pruefer2' => $pruefer2,
'pruefer3' => $pruefer3,
'protokoll' => $formData['protokoll'],
'note' => $formData['note'],
'anmerkung' => $formData['anmerkung'],
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteAbschlusspruefung()
{
$abschlusspruefung_id = $this->input->post('id');
$result = $this->AbschlusspruefungModel->delete(
array('abschlusspruefung_id' => $abschlusspruefung_id)
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
$this->outputJson($result);
}
return $this->terminateWithSuccess(current(getData($result)) ? : null);
}
public function checkForExistingExams()
{
$warning = false;
$output = [];
$student_uids = $this->input->post('uids');
if (empty($student_uids)) {
throw new InvalidArgumentException("Keine UID(s) übergeben.");
}
if( !is_array($student_uids) )
{
$student_uids = array($student_uids);
}
foreach ($student_uids as $uid)
{
$result = $this->AbschlusspruefungModel->loadWhere(
array('student_uid' => $uid)
);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
$warning = true;
$output[] = $uid;
}
}
if($warning)
{
$uids = is_array($output) ? implode(", ", $output) : $output;
return $this->terminateWithError($this->p->t('abschlusspruefung', 'error_studentOhneFinalExam', ['id'=> $uids]), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess('step3');
}
/*
* returns list of all Mitarbeiter
* as key value list to be used in select or autocomplete
*/
public function getAllMitarbeiter()
{
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$sql = "
SELECT
ma.mitarbeiter_uid as mitarbeiter_uid,
CONCAT(p.nachname, ' ', p.vorname, ' (', ma.mitarbeiter_uid, ')') as label
FROM
public.tbl_mitarbeiter ma
JOIN public.tbl_benutzer bn ON (bn.uid = ma.mitarbeiter_uid)
JOIN public.tbl_person p ON (p.person_id = bn.person_id)
ORDER BY
p.nachname ASC
";
$result = $this->MitarbeiterModel->execReadOnlyQuery($sql);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/*
* returns list of all Persons
* as key value list to be used in select or autocomplete
*/
public function getAllPersons()
{
$this->load->model('person/Person_model', 'PersonModel');
$sql = "
SELECT
p.vorname, p.nachname, p.person_id,
CONCAT(p.nachname, ' ', p.vorname) as label
FROM
public.tbl_person p
-- JOIN public.tbl_benutzer bn ON (p.person_id = bn.person_id)
-- and bn.aktiv = 'true'
ORDER BY
p.nachname ASC
";
//TODO(manu) check if filter active benutzer
$result = $this->PersonModel->execReadOnlyQuery($sql);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -31,6 +31,11 @@ class Address extends FHCAPI_Controller
'getNations' => self::PERM_LOGGED,
'getPlaces' => self::PERM_LOGGED
]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function getNations()
@@ -45,7 +50,7 @@ class Address extends FHCAPI_Controller
$this->terminateWithSuccess($data);
}
public function getPlaces($plz)
public function getPlaces($plz = null)
{
$this->load->model('codex/Gemeinde_model', 'GemeindeModel');
@@ -53,7 +58,11 @@ class Address extends FHCAPI_Controller
$this->form_validation->set_data(['address.plz' => $plz]);
$this->form_validation->set_rules('address.plz', 'PLZ', 'numeric|less_than[10000]');
$this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric|less_than[10000]', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ']),
'less_than' => $this->p->t('ui', 'error_fieldLessThan10000', ['field' => 'PLZ'])
]);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
@@ -0,0 +1,70 @@
<?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');
/**
* Controller for downloading Akte
*/
class Akte extends Auth_Controller
{
/**
* Calls the parent's constructor and prepares libraries and phrases
*/
public function __construct()
{
parent::__construct([
'download' => ['admin:w', 'assistenz:w'],
]);
// Load models
$this->load->model('crm/Akte_model', 'AkteModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
*
* Downloads an Akte
*/
public function download()
{
$akte_id = $this->input->get('akte_id');
if (!is_numeric($akte_id)) $this->terminateWithError('akte Id missing');
$result = $this->AkteModel->load($akte_id);
if (!hasData($result)) $this->terminateWithError('Akte not found');
$data = getData($result)[0];
if (isset($data->inhalt) && $data->inhalt != '')
{
header('Content-Description: File Transfer');
header('Content-Type: '. $data->mimetype);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Disposition: attachment; filename="'.$data->titel.'"');
echo base64_decode($data->inhalt);
die();
}
}
}
@@ -0,0 +1,256 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Anrechnungen extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAnrechnungen' => ['admin:r', 'assistenz:r'],
'deleteAnrechnung' => ['admin:rw', 'assistenz:rw'],
'getLehrveranstaltungen' => ['admin:r', 'assistenz:r'],
'getBegruendungen' => ['admin:r', 'assistenz:r'],
'getLektoren' => ['admin:r', 'assistenz:r'],
'getLvsKompatibel' => ['admin:r', 'assistenz:r'],
'insertAnrechnung' => ['admin:rw', 'assistenz:rw'],
'loadAnrechnung' => ['admin:rw', 'assistenz:rw'],
'updateAnrechnung' => ['admin:rw', 'assistenz:rw'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui', 'lehre'
]);
// Load models
$this->load->model('education/Anrechnung_model', 'AnrechnungsModel');
}
public function getAnrechnungen($prestudent_id)
{
$result = $this->AnrechnungsModel->getAnrechnungsData($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getBegruendungen()
{
$this->load->model('education/Anrechnungbegruendung_model', 'AnrechnungbegrueundungsModel');
$result = $this->AnrechnungbegrueundungsModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(getData($result) ?: []);
}
public function getLehrveranstaltungen($prestudent_id)
{
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$result = $this->PrestudentstatusModel->getLastStatus($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$studienplan_id = current($data)->studienplan_id;
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudienplanId($studienplan_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLvsKompatibel($lehrveranstaltung_id)
{
$this->AnrechnungsModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'ON (lv.lehrveranstaltung_id = lehre.tbl_anrechnung.lehrveranstaltung_id)');
$result = $this->AnrechnungsModel->loadWhere(
['lehrveranstaltung_id_kompatibel' => $lehrveranstaltung_id]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLektoren($studiengang_kz)
{
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->MitarbeiterModel->getLektoren($studiengang_kz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function insertAnrechnung()
{
$this->load->library('form_validation');
$prestudent_id = $this->input->post('prestudent_id');
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$_POST['lehrveranstaltung_id'] =
(isset($formData['lehrveranstaltung_id']) && !empty($formData['lehrveranstaltung_id']))
? $formData['lehrveranstaltung_id']
: null;
$_POST['lehrveranstaltung_id_kompatibel'] =
(isset($formData['lehrveranstaltung_id_kompatibel']) && !empty($formData['lehrveranstaltung_id_kompatibel']))
? $formData['lehrveranstaltung_id_kompatibel']
: null;
$_POST['begruendung'] =
(isset($formData['begruendung_id']) && !empty($formData['begruendung_id']))
? $formData['begruendung_id']
: null;
$_POST['genehmigtVon'] = (isset($formData['genehmigt_von']) && !empty($formData['genehmigt_von']))
? $formData['genehmigt_von']
: null;
$this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrveranstaltung_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung'])
]);
$this->form_validation->set_rules('begruendung', 'Begruendung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Begruendung'])
]);
if($_POST['begruendung'] == 2)
{
$this->form_validation->set_rules('lehrveranstaltung_id_kompatibel', 'Lehrveranstaltung_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung Kompatibel'])
]);
}
$this->form_validation->set_rules('genehmigtVon', 'GenehmigtVon', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'GenehmigtVon'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->AnrechnungsModel->insert(
[
'prestudent_id' => $prestudent_id,
'lehrveranstaltung_id' => $_POST['lehrveranstaltung_id'],
'lehrveranstaltung_id_kompatibel' => $_POST['lehrveranstaltung_id_kompatibel'],
'begruendung_id' => $_POST['begruendung'],
'genehmigt_von' => $_POST['genehmigtVon']
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadAnrechnung($anrechnung_id)
{
$this->AnrechnungsModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'ON (lv.lehrveranstaltung_id = lehre.tbl_anrechnung.lehrveranstaltung_id)');
$result = $this->AnrechnungsModel->loadWhere(
array('anrechnung_id' => $anrechnung_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function updateAnrechnung()
{
$this->load->library('form_validation');
$anrechnung_id = $this->input->post('anrechnung_id');
if(!$anrechnung_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Anrechnung UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$_POST['lehrveranstaltung_id'] =
(isset($formData['lehrveranstaltung_id']) && !empty($formData['lehrveranstaltung_id']))
? $formData['lehrveranstaltung_id']
: null;
$_POST['lehrveranstaltung_id_kompatibel'] =
(isset($formData['lehrveranstaltung_id_kompatibel']) && !empty($formData['lehrveranstaltung_id_kompatibel']))
? $formData['lehrveranstaltung_id_kompatibel']
: null;
$_POST['begruendung'] = (isset($formData['begruendung_id']) && !empty($formData['begruendung_id'])) ? $formData['begruendung_id'] : null;
$_POST['genehmigtVon'] = (isset($formData['genehmigt_von']) && !empty($formData['genehmigt_von'])) ? $formData['genehmigt_von'] : null;
$this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrveranstaltung_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung'])
]);
$this->form_validation->set_rules('begruendung', 'Begruendung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Begruendung'])
]);
if($_POST['begruendung'] == 2)
{
$this->form_validation->set_rules('lehrveranstaltung_id_kompatibel', 'Lehrveranstaltung_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehrveranstaltung Kompatibel'])
]);
}
$this->form_validation->set_rules('genehmigtVon', 'GenehmigtVon', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'GenehmigtVon'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->AnrechnungsModel->update(
[
'anrechnung_id' => $anrechnung_id,
],
[
'lehrveranstaltung_id' => $_POST['lehrveranstaltung_id'],
'lehrveranstaltung_id_kompatibel' => $_POST['lehrveranstaltung_id_kompatibel'],
'begruendung_id' => $_POST['begruendung'],
'genehmigt_von' => $_POST['genehmigtVon']
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteAnrechnung($anrechnung_id)
{
// Start DB transaction
$this->db->trans_begin();
//delete anrechnung_id of table tbl_anrechnung_anrechnungstatus
$this->load->model('education/Anrechnunganrechnungstatus_model','AnrechnungAnrechnungstatusModel');
$result = $this->AnrechnungAnrechnungstatusModel->delete(
array('anrechnung_id' => $anrechnung_id)
);
$this->getDataOrTerminateWithError($result);
//delete anrechnung_id of table tbl_anrechnung
$result = $this->AnrechnungsModel->delete(
array('anrechnung_id' => $anrechnung_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->db->trans_commit();
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,272 @@
<?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');
use CI3_Events as Events;
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about archive documents
* Listens to ajax post calls to change the archive documents
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Archiv extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and prepares libraries and phrases
*/
public function __construct()
{
parent::__construct([
'getArchiv' => ['admin:r', 'assistenz:r'],
'getArchivVorlagen' => ['admin:r', 'assistenz:r'],
'archive' => ['admin:w', 'assistenz:w'],
'download' => ['admin:w', 'assistenz:w'],
'update' => ['admin:w'],
'delete' => ['admin:w', 'assistenz:w']
]);
// Load models
$this->load->model('crm/Akte_model', 'AkteModel');
$this->load->model('system/Vorlage_model', 'VorlageModel');
// Load language phrases
$this->loadPhrases([
'archiv'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Get archive documents for a person
* @return void
*/
public function getArchiv()
{
$person_id = $this->input->get('person_id');
$this->load->library('form_validation');
if (!$person_id || !is_array($person_id))
{
$this->form_validation->set_rules('person_id', 'Person ID', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->AkteModel->getArchiv($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* Get Vorlagen for archiving documents
* @return void
*/
public function getArchivVorlagen()
{
$result = $this->VorlageModel->getArchivVorlagen();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
*
* @param
* @return object success or error
*/
public function download()
{
$akte_id = $this->input->get('akte_id');
if (!is_numeric($akte_id)) $this->terminateWithError('akte Id missing');
$result = $this->AkteModel->load($akte_id);
if (!hasData($result)) $this->terminateWithError('Akte not found');
$data = $this->getDataOrTerminateWithError($result);
$data = getData($result)[0];
//$this->addMeta("daa", $data->inhalt);
$fileObj = new stdClass();
if (isset($data->inhalt) && $data->inhalt != '')
{
// Define handle to output stream
$tmpFilePointer = fopen("php://output", 'w');
$meta_data = stream_get_meta_data($tmpFilePointer);
$filename = $meta_data["uri"];
fwrite($tmpFilePointer, $data->inhalt);
header('Content-Description: File Transfer');
header('Content-Type: '. $data->mimetype);
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
//header('Content-Length: ' . filesize($fileObj->file));
//header("Content-type: $data->mimetype");
header('Content-Disposition: attachment; filename="'.$data->titel.'"');
readfile($filename);
//echo base64_decode($data->inhalt);
die();
//~ $fileObj->file = $data->inhalt;
//~ $fileObj->name = $data->titel;
//~ $fileObj->mimetype = $data->mimetype;
//~ $fileObj->disposition = 'attachment';
}
else
{
$this->load->library('AkteLib');
$result = $this->aktelib->get($akte_id);
}
/* $fileObj->filename
* $fileObj->file
* $fileObj->name
* $fileObj->mimetype
* $fileObj->disposition*/
}
/**
* Updating an Akte
* @return void
*/
public function update()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('akte_id', 'Akte Id', 'required');
$this->form_validation->set_rules('signiert', 'Signiert', 'is_bool');
$this->form_validation->set_rules('stud_selfservice', 'Self-Service', 'is_bool');
//Events::trigger('konto_update_validation', $this->form_validation);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$id = $this->input->post('akte_id');
// get the akte
$result = $this->AkteModel->load($id);
if (!hasData($result)) $this->terminateWithError("Akte not found!");
$akte = getData($result)[0];
$allowed = [
'signiert',
'stud_selfservice'
];
$data = [
'updateamum' => date('c'),
'updatevon' => getAuthUID()
];
// if Akte has Inhalt directly in Akte table
if (isset($_FILES['datei']['tmp_name']))
{
$this->addMeta('read', "read");
// update inhalt directly
// get tmp file
$filename = $_FILES['datei']['tmp_name'];
// open it
$fp = fopen($filename,'r');
// read it
$content = fread($fp, filesize($filename));
fclose($fp);
// encode it
$data['inhalt'] = base64_encode($content);
$this->addMeta('content', base64_encode($content));
}
foreach ($allowed as $field)
if ($this->input->post($field) !== null)
$data[$field] = $this->input->post($field);
$this->addMeta("data", $data);
$result = $this->AkteModel->update($id, $data);
$this->getDataOrTerminateWithError($result);
$result = null;
$this->terminateWithSuccess($result);
}
/**
* Delete archived Akte
*
* @return void
*/
public function delete()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('akte_id', 'Akte ID', 'required');
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'has_permissions_for_stg[admin:rw,assistenz:rw]');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$akte_id = $this->input->post('akte_id');
$result = $this->AkteModel->load($akte_id);
if (!hasData($result))
{
$this->terminateWithError($this->p->t('archiv', 'error_missing', [
'akte_id' => $akte_id
]));
}
$result = getData($result)[0];
if ($result->dokument_kurzbz == 'Ausbvert'
&& isset($result->akzeptiertamum)
&& !isEmptyString($result->akzeptiertamum)
&& !has_permissions_for_stg($this->input->post('studiengang_kz'), 'admin:rw')
)
{
$this->terminateWithError($this->p->t('archiv', 'nur_admins_loschen_ausbildungsvertraege', [
'akte_id' => $akte_id
]));
}
$result = $this->AkteModel->delete($akte_id);
if (isError($result)) $this->terminateWithError(getError($result));
$this->terminateWithSuccess();
}
}
@@ -0,0 +1,413 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Aufnahmetermine extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAufnahmetermine' => ['admin:r', 'assistenz:r'],
'loadAufnahmetermin' => ['admin:r', 'assistenz:r'],
'insertAufnahmetermin' => ['admin:rw', 'assistenz:rw'],
'updateAufnahmetermin' => ['admin:rw', 'assistenz:rw'],
'deleteAufnahmetermin' => ['admin:rw', 'assistenz:rw'],
'getListPlacementTests' => ['admin:r', 'assistenz:r'],
'getListStudyPlans' => ['admin:r', 'assistenz:r'],
'loadDataRtPrestudent' => ['admin:r', 'assistenz:r'],
'insertOrUpdateDataRtPrestudent' => ['admin:r', 'assistenz:r'],
'loadAufnahmegruppen' => ['admin:r', 'assistenz:r'],
'getResultReihungstest' => ['admin:r', 'assistenz:r'],
'getZukuenftigeReihungstestStg' => ['admin:r', 'assistenz:r'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'admission'
]);
// Load models
$this->load->model('crm/Reihungstest_model', 'ReihungstestModel');
$this->load->model('crm/RtPerson_model', 'RtPersonModel');
}
public function getAufnahmetermine($person_id)
{
$result = $this->ReihungstestModel->getReihungstestPerson($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function insertAufnahmetermin()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$formData = $this->input->post('formData');
$person_id = $this->input->post('person_id');
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
}
$rt_id = (isset($formData['rt_id']) && !empty($formData['rt_id'])) ? $formData['rt_id'] : null;
$anmeldedatum = (isset($formData['anmeldedatum']) && !empty($formData['anmeldedatum'])) ? $formData['anmeldedatum'] : null;
$teilgenommen = (isset($formData['teilgenommen']) && !empty($formData['teilgenommen'])) ? $formData['teilgenommen'] : false;
$studienplan_id = (isset($formData['studienplan_id']) && !empty($formData['studienplan_id'])) ? $formData['studienplan_id'] : null;
$punkte = (isset($formData['punkte']) && !empty($formData['punkte'])) ? $formData['punkte'] : null;
//validation if there is already an RT with chosen data existing
$result = $this->RtPersonModel->loadWhere(
array(
'rt_id' => $rt_id,
'person_id' => $person_id,
'studienplan_id' => $studienplan_id,
)
);
$data = getData($result);
if($data)
return $this->terminateWithError("Error", self::ERROR_TYPE_GENERAL);
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('punkte', 'Punkte', 'numeric', [
'required' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Punkte'])
]);
$this->form_validation->set_rules('studienplan_id', 'studienplan_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studienplan'])
]);
$this->form_validation->set_rules('rt_id', 'Reihungstest_id', 'required', [
'is_valid_date' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Reihungstest'])
]);
$this->form_validation->set_rules('anmeldedatum', 'AnmeldeDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Anmeldedatum'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->RtPersonModel->insert([
'person_id' => $person_id,
'rt_id' => $rt_id,
'anmeldedatum' => $anmeldedatum,
'teilgenommen' => $teilgenommen,
'studienplan_id' => $studienplan_id,
'punkte' => $punkte,
'insertamum' => date('c'),
'insertvon' => $authUID,
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadAufnahmetermin($rt_person_id)
{
$result = $this->RtPersonModel->loadWhere(
array('rt_person_id' => $rt_person_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function updateAufnahmetermin()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$formData = $this->input->post('formData');
$rt_person_id = $this->input->post('rt_person_id');
$person_id = (isset($formData['person_id']) && !empty($formData['person_id'])) ? $formData['person_id'] : null;
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
}
if(!$rt_person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'RT_Person ID']), self::ERROR_TYPE_GENERAL);
}
$rt_id = (isset($formData['rt_id']) && !empty($formData['rt_id'])) ? $formData['rt_id'] : null;
$anmeldedatum = (isset($formData['anmeldedatum']) && !empty($formData['anmeldedatum'])) ? $formData['anmeldedatum'] : null;
$teilgenommen = (isset($formData['teilgenommen']) && !empty($formData['teilgenommen'])) ? $formData['teilgenommen'] : false;
$studienplan_id = (isset($formData['studienplan_id']) && !empty($formData['studienplan_id'])) ? $formData['studienplan_id'] : null;
$punkte = (isset($formData['punkte']) && !empty($formData['punkte'])) ? $formData['punkte'] : null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('punkte', 'Punkte', 'numeric', [
'required' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Punkte'])
]);
$this->form_validation->set_rules('studienplan_id', 'studienplan_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studienplan'])
]);
$this->form_validation->set_rules('rt_id', 'Reihungstest_id', 'required', [
'is_valid_date' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Reihungstest'])
]);
$this->form_validation->set_rules('anmeldedatum', 'AnmeldeDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Anmeldedatum'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->RtPersonModel->update(
[
'rt_person_id' => $rt_person_id,
],
[
'rt_id' => $rt_id,
'anmeldedatum' => $anmeldedatum,
'teilgenommen' => $teilgenommen,
'studienplan_id' => $studienplan_id,
'punkte' => $punkte,
'insertamum' => date('c'),
'insertvon' => $authUID,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteAufnahmetermin($rt_person_id)
{
$result = $this->RtPersonModel->delete(
array('rt_person_id' => $rt_person_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getListPlacementTests($prestudent_id)
{
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
//get studienplan array
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->PrestudentstatusModel->addSelect('*');
$this->PrestudentstatusModel->addSelect('sp.studienplan_id');
$this->PrestudentstatusModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
$result = $this->PrestudentstatusModel->loadWhere(
array(
'prestudent_id' => $prestudent_id,
'status_kurzbz' => 'Interessent'
)
);
$data = $this->getDataOrTerminateWithError($result);
$studienplan_arr = [];
$include_ids = [];
foreach ($data as $item)
{
if($item->studienplan_id != null)
$studienplan_arr[] = $item->studienplan_id;
}
//get Placementtests Person
$person_id = $this->_getPersonId($prestudent_id);
$resultRt = $this->ReihungstestModel->getReihungstestPerson($person_id);
$dataRt = $this->getDataOrTerminateWithError($resultRt);
foreach ($dataRt as $item)
{
if(!in_array($item->studienplan_id, $studienplan_arr))
$studienplan_arr[] = $item->studienplan_id;
if(!in_array($item->rt_id, $include_ids) && ($item->rt_id != null))
$include_ids[] = $item->rt_id;
}
$result = $this->ReihungstestModel->getReihungstestByStudyPlanAndIds($studienplan_arr, $include_ids);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getListStudyPlans($person_id)
{
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$result = $this->StudienplanModel->getStudienplaeneForPerson($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadDataRtPrestudent($prestudent_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addSelect(["reihungstestangetreten"]);
$this->PrestudentModel->addSelect(["rt_gesamtpunkte"]);
$this->PrestudentModel->addSelect(["aufnahmegruppe_kurzbz"]);
$result = $this->PrestudentModel->loadWhere(
array('prestudent_id' => $prestudent_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function insertOrUpdateDataRtPrestudent()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$formData = $this->input->post('formData');
$prestudent_id = $this->input->post('prestudent_id');
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$rt_gesamtpunkte =
(isset($formData['rt_gesamtpunkte']) && !empty($formData['rt_gesamtpunkte']))
? $formData['rt_gesamtpunkte']
: null;
$reihungstestangetreten =
(isset($formData['reihungstestangetreten']) && !empty($formData['reihungstestangetreten']))
? $formData['reihungstestangetreten']
: null;
$aufnahmegruppe_kurzbz =
(isset($formData['aufnahmegruppe_kurzbz']) && !empty($formData['aufnahmegruppe_kurzbz']))
? $formData['aufnahmegruppe_kurzbz']
: null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('rt_gesamtpunkte', 'Rt_gesamtpunkte', 'numeric', [
'required' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Rt_gesamtpunkte'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->update(
[
'prestudent_id' => $prestudent_id,
],
[
'reihungstestangetreten' => $reihungstestangetreten,
'rt_gesamtpunkte' => $rt_gesamtpunkte,
'aufnahmegruppe_kurzbz' => $aufnahmegruppe_kurzbz,
'updateamum' => date('c'),
'updatevon' => $authUID,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadAufnahmegruppen()
{
$uid = $this->input->get('uid');
$studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz');
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$result = $this->BenutzergruppeModel->loadAufnahmegruppen($uid, $studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(($data));
}
public function getResultReihungstest()
{
$person_id = $this->input->get('person_id');
$punkte = $this->input->get('punkte');
$reihungstest_id = $this->input->get('reihungstest_id');
if(!$reihungstest_id)
{
$this->terminateWithSuccess(null);
}
//for gewichtung
$studiengang_kz = $this->input->get('studiengang_kz');
$this->load->model('testtool/Ablauf_model', 'AblaufModel');
$result = $this->AblaufModel->getAblaufGebieteAndGewichte($studiengang_kz);
$data = $this->getDataOrTerminateWithError($result);
$weightedArray = [];
foreach ($data as $abl)
{
$weightedArray[$abl->gebiet_id] = $abl->gewicht;
}
$result = $this->ReihungstestModel->getReihungstestErgebnisPerson($person_id, $punkte, $reihungstest_id, $weightedArray);
/* if (isError($result))
{
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}*/
$this->terminateWithSuccess($result);
}
public function getZukuenftigeReihungstestStg()
{
$studiengang_kz = $this->input->get('studiengang_kz');
if(!$studiengang_kz)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
}
$result = $this->ReihungstestModel->getZukuenftigeReihungstestStg($studiengang_kz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
private function _getPersonId($prestudent_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $prestudent_id]
);
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
return $person->person_id;
}
}
@@ -44,21 +44,33 @@ class Config extends FHCAPI_Controller
'person',
'lehre',
'stv',
'konto'
'konto',
'abschlusspruefung'
]);
// Load Config
$this->load->config('stv');
}
public function student()
{
$result = [];
$config = $this->config->item('tabs');
$result['details'] = [
'title' => $this->p->t('stv', 'tab_details'),
'component' => './Stv/Studentenverwaltung/Details/Details.js'
'component' => './Stv/Studentenverwaltung/Details/Details.js',
'config' => $config['details']
];
$result['notes'] = [
'title' => $this->p->t('stv', 'tab_notes'),
'component' => './Stv/Studentenverwaltung/Details/Notizen.js'
'component' => './Stv/Studentenverwaltung/Details/Notizen.js',
'config' => $config['notes'],
'showSuffix' => ($config['notes']['showCountNotes'] ?? false),
'suffixhelper' => APP_ROOT . 'public/js/helpers/Stv/Studentenverwaltung/Details/Notizen/NotizenSuffixHelper.js'
];
$result['contact'] = [
'title' => $this->p->t('stv', 'tab_contact'),
'component' => './Stv/Studentenverwaltung/Details/Kontakt.js',
@@ -69,12 +81,17 @@ class Config extends FHCAPI_Controller
];
$result['prestudent'] = [
'title' => $this->p->t('stv', 'tab_prestudent'),
'component' => './Stv/Studentenverwaltung/Details/Prestudent.js'
'component' => './Stv/Studentenverwaltung/Details/Prestudent.js',
'config' => $config['prestudent']
];
$result['status'] = [
'title' => 'Status',
'component' => './Stv/Studentenverwaltung/Details/MultiStatus.js'
];
$result['documents'] = [
'title' => $this->p->t('stv', 'tab_documents'),
'component' => './Stv/Studentenverwaltung/Details/Dokumente.js'
];
$result['banking'] = [
'title' => $this->p->t('stv', 'tab_banking'),
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
@@ -91,23 +108,91 @@ class Config extends FHCAPI_Controller
'title' => $this->p->t('stv', 'tab_resources'),
'component' => './Stv/Studentenverwaltung/Details/Betriebsmittel.js'
];
/* TODO(chris): Ausgeblendet für Testing
$result['groups'] = [
'title' => $this->p->t('stv', 'tab_groups'),
'component' => './Stv/Studentenverwaltung/Details/Gruppen.js'
];
$result['messages'] = [
'title' => $this->p->t('stv', 'tab_messages'),
'component' => './Stv/Studentenverwaltung/Details/Messages.js'
];
$result['grades'] = [
'title' => $this->p->t('stv', 'tab_grades'),
'component' => './Stv/Studentenverwaltung/Details/Noten.js'
'component' => './Stv/Studentenverwaltung/Details/Noten.js',
'showOnlyWithUid' => true,
'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()
]
];
$result['exam'] = [
'title' => $this->p->t('stv', 'tab_exam'),
'component' => './Stv/Studentenverwaltung/Details/Pruefung.js'
];
$result['exemptions'] = [
'title' => $this->p->t('lehre', 'anrechnungen'),
'component' => './Stv/Studentenverwaltung/Details/Anrechnungen.js',
'config' => $config['exemptions']
];
$result['finalexam'] = [
'title' => $this->p->t('stv', 'tab_finalexam'),
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
'config' => $config['finalexam']
];
$result['mobility'] = [
'title' => $this->p->t('stv', 'tab_mobility'),
'component' => './Stv/Studentenverwaltung/Details/Mobility.js'
];
$result['archive'] = [
'title' => $this->p->t('stv', 'tab_archive'),
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
'config' => [
'showEdit' => $this->permissionlib->isBerechtigt('admin')
]
];
$result['jointstudies'] = [
'title' => $this->p->t('stv', 'tab_jointstudies'),
'component' => './Stv/Studentenverwaltung/Details/JointStudies.js'
];
$result['coursedates'] = [
'title' => $this->p->t('stv', 'tab_courseDates'),
'component' => './Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine.js'
];
$result['admissionDates'] = [
'title' => $this->p->t('stv', 'tab_admissionDates'),
'component' => './Stv/Studentenverwaltung/Details/Aufnahmetermine.js'
];
$result['functions'] = [
'title' => $this->p->t('stv', 'tab_functions'),
'component' => './Stv/Studentenverwaltung/Details/Funktionen.js'
];
*/
Events::trigger('stv_conf_student', function & () use (&$result) {
return $result;
});
$this->terminateWithSuccess($result);
$sortConfig = $this->config->item('student_tab_order');
$this->terminateWithSuccess($this->sortTabList($result, $sortConfig));
}
public function students()
{
$result = [];
$config = $this->config->item('tabs');
$result['banking'] = [
'title' => $this->p->t('stv', 'tab_banking'),
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
@@ -131,12 +216,26 @@ class Config extends FHCAPI_Controller
'changeStatusToAbsolvent' => $this->permissionlib->isBerechtigt('admin')
]
];
$result['finalexam'] = [
'title' => $this->p->t('stv', 'tab_finalexam'),
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
'config' => $config['finalexam']
];
$result['archive'] = [
'title' => $this->p->t('stv', 'tab_archive'),
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
'config' => [
'showEdit' => $this->permissionlib->isBerechtigt('admin')
]
];
Events::trigger('stv_conf_students', function & () use (&$result) {
return $result;
});
$this->terminateWithSuccess($result);
$sortConfig = $this->config->item('students_tab_order');
$this->terminateWithSuccess($this->sortTabList($result, $sortConfig));
}
protected function kontoColumns()
@@ -230,4 +329,216 @@ 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
*
* @param array $input
* @param array $config
*
* @return array
*/
protected function sortTabList($input, $config)
{
// prepare config
if (!$config || !is_array($config))
$config = [];
else
$config = array_flip($config);
// fill missing items in config
foreach (array_keys($input) as $key) {
if (!isset($config[$key]))
$config[$key] = count($config);
}
// do the sorting
uksort($input, function ($a, $b) use ($config) {
return $config[$a] - $config[$b];
});
return $input;
}
}
@@ -0,0 +1,569 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Dokumente extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getDocumentsUnaccepted' => ['admin:r', 'assistenz:r'],
'getDocumentsAccepted' => ['admin:r', 'assistenz:r'],
'deleteZuordnung' => ['admin:rw', 'assistenz:rw'],
'createZuordnung' => ['admin:rw', 'assistenz:rw'],
'loadAkte' => ['admin:rw', 'assistenz:rw'],
'deleteAkte' => ['admin:rw', 'assistenz:rw'],
'updateAkte' => ['admin:rw', 'assistenz:rw'],
'getDoktypen' => ['admin:r', 'assistenz:r'],
'uploadDokument' => ['admin:rw', 'assistenz:rw'],
'download' => ['admin:rw', 'assistenz:rw'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
$this->load->library('DmsLib', array('who' => getAuthUID()));
// Load language phrases
$this->loadPhrases([
'ui',
'dokumente'
]);
// Load models
$this->load->model('crm/Akte_model', 'AkteModel');
$this->load->model('crm/Dokument_model', 'DokumentModel');
$this->load->model('crm/Dokumentprestudent_model', 'DokumentprestudentModel');
//TODO(Manu) check additional Berechtigungen
//TODO(Manu) check if using dokument lib instead of dokument model?
}
public function getDocumentsUnaccepted($prestudent_id, $studiengang_kz)
{
if(!$prestudent_id)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if (!is_numeric($prestudent_id))
$this->terminateWithError($this->p->t('ui', 'error_valueNotNumeric', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if(!$studiengang_kz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
$person_id = $this->_getPersonId($prestudent_id);
$result = $this->DokumentModel->getUnacceptedDocuments($prestudent_id, $person_id);
$dataAkteUnaccepted = $this->getDataOrTerminateWithError($result);
$resultMd = $this->_getMissingDocuments($studiengang_kz, $prestudent_id);
$data = $this->_mergeDocuments($dataAkteUnaccepted, $resultMd);
$this->terminateWithSuccess($data);
}
public function getDocumentsAccepted($prestudent_id, $studiengang_kz)
{
if(!$prestudent_id)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if (!is_numeric($prestudent_id))
$this->terminateWithError($this->p->t('ui', 'error_valueNotNumeric', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if(!$studiengang_kz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
$resultPreDoc = $this->_getPrestudentDokumente($prestudent_id);
$arrayAccepted = [];
$person_id = $this->_getPersonId($prestudent_id);
$docNames = array_map(function ($item) {
return $item->dokument_kurzbz;
}, $resultPreDoc);
foreach($docNames as $doc)
{
$result = $this->AkteModel->getAktenFAS($person_id, $doc, $studiengang_kz, $prestudent_id, true);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (hasData($result))
{
$data = getData($result);
foreach ($data as $value)
{
array_push($arrayAccepted, $value);
}
}
}
//Mapping with document_kurzbz
$preDocMap = [];
foreach ($resultPreDoc as $pre) {
$preDocMap[$pre->dokument_kurzbz] = $pre;
}
$mergedArray = [];
foreach ($arrayAccepted as $doc) {
$merged = clone $doc;
if (isset($preDocMap[$doc->dokument_kurzbz])) {
$merged->docdatum = $preDocMap[$doc->dokument_kurzbz]->docdatum;
$merged->insertvonma = $preDocMap[$doc->dokument_kurzbz]->insertvonma;
$merged->bezeichnung = $preDocMap[$doc->dokument_kurzbz]->bezeichnung;
} else {
$merged->akzeptiertdatum = null;
$merged->akzeptiertvon = null;
}
$mergedArray[] = $merged;
}
$this->terminateWithSuccess($mergedArray);
}
public function deleteZuordnung($prestudent_id, $dokument_kurzbz)
{
if(!$prestudent_id)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if (!is_numeric($prestudent_id))
$this->terminateWithError($this->p->t('ui', 'error_valueNotNumeric', ['value' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if(!$dokument_kurzbz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Dokument_kurzbz']), self::ERROR_TYPE_GENERAL);
$result = $this->DokumentprestudentModel->delete(
[
'prestudent_id' => $prestudent_id,
'dokument_kurzbz' => $dokument_kurzbz
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadAkte($akte_id)
{
if (!$akte_id)
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Akte ID']), self::ERROR_TYPE_GENERAL);
$this->AkteModel->addSelect('public.tbl_akte.*');
$this->AkteModel->addSelect("CONCAT(public.tbl_person.vorname, ' ' , public.tbl_person.nachname) AS namePerson");
$this->AkteModel->addJoin('public.tbl_person', 'person_id');
$result = $this->AkteModel->loadWhere(
[
'akte_id' => $akte_id,
]
);
$data = $this->getDataOrTerminateWithError($result);
$data = current($data);
$this->terminateWithSuccess($data);
}
public function updateAkte()
{
$this->form_validation->set_rules('akte_id', 'Akte ID', 'required', [
'required' => $this->p->t('dokumente', 'err_updateNotAllowed')
]);
$this->form_validation->set_rules('dokument_kurzbz', 'Dokumenttyp', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Dokumenttyp'])
]);
$this->form_validation->set_rules('nachreichung_am', 'Nachreichung am', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Nachreichung am'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$uid = getAuthUID();
$result = $this->AkteModel->update(
[
'akte_id' => $this->input->post('akte_id'),
],
[
'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'),
'updateamum' => date('c'),
'updatevon' => $uid,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function createZuordnung($prestudent_id, $dokument_kurzbz)
{
if (!$prestudent_id)
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
if(!$dokument_kurzbz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Dokument_kurzbz']), self::ERROR_TYPE_GENERAL);
$uid = getAuthUid();
//check if more than 1 dokumentkurzbz
//if()
$result = $this->DokumentprestudentModel->insert(
[
'prestudent_id' => $prestudent_id,
'dokument_kurzbz' => $dokument_kurzbz,
'mitarbeiter_uid' => $uid,
'datum' => date('c'),
'insertamum' => date('c'),
'insertvon' => $uid,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteAkte($akte_id)
{
if (!$akte_id)
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Akte ID']), self::ERROR_TYPE_GENERAL);
$result = $this->AkteModel->load($akte_id);
$dataAkte = $this->getDataOrTerminateWithError($result);
$logdata_akte = var_export($dataAkte, true);
$dms_id = current($dataAkte)->dms_id;
$nachgereicht = current($dataAkte)->nachgereicht;
$inhalt = current($dataAkte)->inhalt;
$inhaltVorhanden = $inhalt != '';
$uid = getAuthUid();
$this->db->trans_start();
if($dms_id)
{
$this->load->model('content/Dms_model', 'DmsModel');
$result = $this->DmsModel->load($dms_id);
$data = $this->getDataOrTerminateWithError($result);
$logdata_dms = (array)$data;
$logdata_dms = "Logdata: " . var_export($logdata_dms, true);
//delete from dmsLib
$this->load->library('DmsLib');
$person_id = current($dataAkte)->person_id;
$result = $this->dmslib->delete($person_id, $dms_id);
$this->getDataOrTerminateWithError($result);
//LOGGING Dms ID
$this->load->model('system/Log_model', 'LogModel');
$result = $this->LogModel->insert([
'executetime' => date('c'),
'mitarbeiter_uid' => $uid,
'beschreibung' => "Löschen der DMS_ID ". $dms_id,
'sql' => $logdata_dms
]);
$this->getDataOrTerminateWithError($result);
//delete akte
$result = $this->AkteModel->delete(
[
'akte_id' => $akte_id
]
);
$data = $this->getDataOrTerminateWithError($result);
//Logging Deletion Akte
$result = $this->LogModel->insert([
'executetime' => date('c'),
'mitarbeiter_uid' => $uid,
'beschreibung' => "Löschen der Akte ". $akte_id,
'sql' => "DELETE FROM public.tbl_akte WHERE akte_id=" .$akte_id. " LogData: ". $logdata_akte
]);
$this->getDataOrTerminateWithError($result);
$this->db->trans_complete();
$this->terminateWithSuccess($data);
}
elseif (!!$dms_id || ($nachgereicht && !$inhaltVorhanden))
{
$result = $this->AkteModel->delete(
[
'akte_id' => $akte_id
]
);
$data = $this->getDataOrTerminateWithError($result);
$result = $this->LogModel->insert([
'executetime' => date('c'),
'mitarbeiter_uid' => $uid,
'beschreibung' => "Löschen der Akte ". $akte_id,
'sql' => "DELETE FROM public.tbl_akte WHERE akte_id=" .$akte_id. " LogData: ". $logdata_akte
]);
$this->getDataOrTerminateWithError($result);
$this->db->trans_complete();
$this->terminateWithSuccess($data);
}
else
$this->terminateWithError($this->p->t('dokumente', 'err_deleteDokHere'), self::ERROR_TYPE_GENERAL);
}
public function uploadDokument()
{
$this->load->library('DmsLib');
$prestudent_id = $this->input->post('prestudent_id');
$anmerkung_intern = $this->input->post('anmerkung_intern');
$titel_intern = $this->input->post('titel_intern');
$dokument_kurzbz = $this->input->post('dokument_kurzbz');
$this->form_validation->set_rules('prestudent_id', 'Prestudent_id', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Prestudent ID'])
]);
$this->form_validation->set_rules('dokument_kurzbz', 'Dokumenttyp', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Dokumenttyp'])
]);
//validation if attachment was added
$this->form_validation->set_rules('anhang', 'Attachment', 'callback_file_check');
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->db->trans_start();
$uid = getAuthUID();
$dms = array(
'kategorie_kurzbz' => 'Akte',
'version' => 0,
'name' => $_FILES['anhang']['name'],
'mimetype' => $_FILES['anhang']['type'],
'insertamum' => date('c'),
'insertvon' => $uid
);
$result = $this->dmslib->upload($dms, 'anhang', array("jpg", "png", "pdf"));
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$dms_id = $result->retval['dms_id'];
$person_id = $this->_getPersonId($prestudent_id);
$result = $this->DokumentModel->load($dokument_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$bezeichnung = current($data)->bezeichnung;
//save entry in akte
if($dms_id)
{
$result = $this->AkteModel->insert([
'person_id' => $person_id,
'dms_id' => $dms_id,
'dokument_kurzbz' => $dokument_kurzbz,
'mimetype' => $_FILES['anhang']['type'],
'insertamum' => date('c'),
'erstelltam' => date('c'),
'insertvon' => $uid,
'anmerkung_intern' => $anmerkung_intern,
'titel_intern' => $titel_intern,
'bezeichnung' => $bezeichnung,
'titel' => $_FILES['anhang']['name']
]);
$data = $this->getDataOrTerminateWithError($result);
$this->db->trans_complete();
$this->terminateWithSuccess($data);
}
$this->db->trans_complete();
$this->terminateWithSuccess($data);
}
public function getDoktypen()
{
$this->DokumentModel->addSelect('dokument_kurzbz');
$this->DokumentModel->addSelect('bezeichnung');
$this->DokumentModel->addOrder('dokument_kurzbz', 'ASC');
$result = $this->DokumentModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function download()
{
//TODO(Manu) check filetype, Decoding
$akte_id = $this->input->get('akte_id');
if(!$akte_id)
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Akte ID']), self::ERROR_TYPE_GENERAL);
if (!is_numeric($akte_id))
$this->terminateWithError($this->p->t('ui', 'error_valueNotNumeric', ['value' => 'Akte ID']), self::ERROR_TYPE_GENERAL);
$result = $this->AkteModel->load($akte_id);
if (!hasData($result)) $this->terminateWithError('Akte not found');
$data = getData($result)[0];
$mimetype = $data->mimetype;
$filecontentbase64 = $data->inhalt;
$filename = $data->titel;
if(intval($data->dms_id) > 0)
{
$dmsdokres = $this->dmslib->read($data->dms_id);
if (!hasData($dmsdokres)) $this->terminateWithError('DMS File not found');
$dmsdok = getData($dmsdokres)[0];
$mimetype = $dmsdok->mimetype;
$filecontentbase64 = $dmsdok->file_content;
$filename = $dmsdok->name;
}
$filecontent = '';
if (!empty($filecontentbase64)) {
$filecontent = base64_decode($filecontentbase64, true);
if ($filecontent === false) {
$this->terminateWithError('Base64-Dekodierung failed.');
}
}
$this->terminateWithFileOutput($mimetype, $filecontent, $filename);
}
private function _getMissingDocuments($studiengang_kz, $prestudent_id)
{
$result = $this->DokumentModel->getMissingDocuments($studiengang_kz, $prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
return $data;
}
private function _getUnacceptedDocuments($prestudent_id)
{
$person_id = $this->_getPersonId($prestudent_id);
$result = $this->DokumentModel->getUnacceptedDocuments($prestudent_id, $person_id);
$data = $this->getDataOrTerminateWithError($result);
return $data;
}
/**
* helper function for merging objects
* sorts object after merging according to dokument_kurzbz
* @param $original object of documents of akte
* @param object $toMerge documents to merge (of dokumentprestudent, dokumentstudiengang)
* @return Array mergedObject
*/
private function _mergeDocuments($original, $toMerge)
{
$existingKurzbez = [];
foreach ($original as $doc) {
$existingKurzbez[$doc->dokument_kurzbz] = true;
}
foreach ($toMerge as $doc) {
if (!isset($existingKurzbez[$doc->dokument_kurzbz])) {
$original[] = $doc;
$existingKurzbez[$doc->dokument_kurzbz] = true;
}
else
{
foreach($original as $docOriginal)
{
if ($docOriginal->dokument_kurzbz == $doc->dokument_kurzbz)
{
$docOriginal->pflicht = $doc->pflicht;
$docOriginal->onlinebewerbung = $doc->onlinebewerbung;
}
}
}
}
usort($original, function ($a, $b) {
return strcmp($a->dokument_kurzbz, $b->dokument_kurzbz);
});
return $original;
}
private function _getDocumentsOfAkte($person_id)
{
$result = $this->AkteModel->getAktenFAS($person_id);
$data = $this->getDataOrTerminateWithError($result);
return $data;
}
private function _getPrestudentDokumente($prestudent_id)
{
$result = $this->DokumentprestudentModel->getPrestudentDokumente($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
return $data;
}
private function _getPersonId($prestudent_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $prestudent_id]
);
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
return $person->person_id;
}
public function file_check($str)
{
if (isset($_FILES['anhang']) && $_FILES['anhang']['size'] > 0)
{
$allowed_mime_types = ['image/jpeg', 'image/png', 'application/pdf'];
$mime = mime_content_type($_FILES['anhang']['tmp_name']);
if (in_array($mime, $allowed_mime_types))
{
return true;
} else
{
$this->form_validation->set_message('file_check', $this->p->t('dokumente', 'error_fileType'));
return false;
}
}
else
{
$this->form_validation->set_message('file_check', $this->p->t('dokumente', 'error_fileMissing'));
return false;
}
}
}
@@ -35,8 +35,6 @@ class Favorites extends FHCAPI_Controller
// Load models
$this->load->model('system/Variable_model', 'VariableModel');
// TODO(chris): variable table might be to small to store favorites!
}
public function index()
@@ -48,7 +46,7 @@ class Favorites extends FHCAPI_Controller
if (!$data)
$this->terminateWithSuccess(null);
else
$this->terminateWithSuccess($data['stv_favorites']);
$this->terminateWithSuccess($data['stv_favorites'] ?? null);
}
public function set()
@@ -62,6 +60,17 @@ class Favorites extends FHCAPI_Controller
$favorites = $this->input->post('favorites');
$removed = [];
while (strlen($favorites) > 64) {
$favObj = json_decode($favorites);
if (!$favObj->list)
break;
$removed[] = array_shift($favObj->list);
$favorites = json_encode($favObj);
}
if ($removed)
$this->addMeta('removed', $removed);
$result = $this->VariableModel->setVariable(getAuthUID(), 'stv_favorites', $favorites);
$this->getDataOrTerminateWithError($result);
@@ -0,0 +1,287 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class GemeinsameStudien extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getStudien' => ['admin:r', 'assistenz:r'],
'loadStudie' => ['admin:r', 'assistenz:r'],
'insertStudie' => ['admin:rw', 'assistenz:rw'],
'updateStudie' => ['admin:rw', 'assistenz:rw'],
'deleteStudie' => ['admin:rw', 'assistenz:rw'],
'getProgramsStudien' => ['admin:r', 'assistenz:r'],
'getTypenMobility' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r'],
'getStudienprogramme' => ['admin:r', 'assistenz:r'],
'getPartnerfirmen' => ['admin:r', 'assistenz:r'],
'getStatiPrestudent' => ['admin:r', 'assistenz:r'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'jointstudies'
]);
// Load models
$this->load->model('codex/Mobilitaet_model', 'MobilitaetModel');
//TODO(check if additional Permissions necessary): 'student/stammdaten'
}
public function getStudien($prestudent_id)
{
$this->MobilitaetModel->addSelect('mobilitaet_id');
$this->MobilitaetModel->addSelect('mobilitaetstyp_kurzbz');
$this->MobilitaetModel->addSelect('prestudent_id');
$this->MobilitaetModel->addSelect('studiensemester_kurzbz');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.mobilitaetsprogramm_code');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.gsprogramm_id');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.firma_id');
$this->MobilitaetModel->addSelect('status_kurzbz');
$this->MobilitaetModel->addSelect('ausbildungssemester');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.insertvon');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.insertamum');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.updatevon');
$this->MobilitaetModel->addSelect('bis.tbl_mobilitaet.updateamum');
$this->MobilitaetModel->addSelect('mp.kurzbz');
$this->MobilitaetModel->addSelect('gp.gsprogrammtyp_kurzbz');
$this->MobilitaetModel->addSelect('gp.bezeichnung as studienprogramm');
$this->MobilitaetModel->addSelect('f.name as partner');
$this->MobilitaetModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_mobilitaet.mobilitaetsprogramm_code)', 'LEFT');
$this->MobilitaetModel->addJoin('bis.tbl_gsprogramm gp', 'ON (gp.gsprogramm_id = bis.tbl_mobilitaet.gsprogramm_id)', 'LEFT');
$this->MobilitaetModel->addJoin('public.tbl_firma f', 'ON (f.firma_id = bis.tbl_mobilitaet.firma_id)', 'LEFT');
$result = $this->MobilitaetModel->loadWhere([
'prestudent_id' => $prestudent_id,
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getTypenMobility()
{
$this->load->model('codex/Mobilitaetstyp_model', 'MobilitaetstypModel');
$result = $this->MobilitaetstypModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStudiensemester()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addOrder('studienjahr_kurzbz', 'DESC');
$result = $this->StudiensemesterModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStudienprogramme()
{
$this->load->model('codex/Gsprogramm_model', 'GsprogrammModel');
$result = $this->GsprogrammModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getPartnerfirmen()
{
$this->load->model('ressource/Firma_model', 'FirmaModel');
$result = $this->FirmaModel->loadWhere(
['partner_code !=' => null]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStatiPrestudent()
{
$this->load->model('crm/Status_model', 'StatusModel');
$result = $this->StatusModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadStudie($mobilitaet_id)
{
$result = $this->MobilitaetModel->load($mobilitaet_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function insertStudie()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$prestudent_id = $this->input->post('prestudent_id');
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$ausbildungssemester = (isset($formData['ausbildungssemester']) && !empty($formData['ausbildungssemester']))
? $formData['ausbildungssemester']
: null;
$mobilitaetstyp_kurzbz = (isset($formData['mobilitaetstyp_kurzbz']) && !empty($formData['mobilitaetstyp_kurzbz']))
? $formData['mobilitaetstyp_kurzbz']
: null;
$studiensemester_kurzbz = (isset($formData['studiensemester_kurzbz']) && !empty($formData['studiensemester_kurzbz']))
? $formData['studiensemester_kurzbz'] : null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('mobilitaetstyp_kurzbz', 'Typ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ'])
]);
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studiensemester'])
]);
$this->form_validation->set_rules('ausbildungssemester', 'Ausbildungssemester', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Ausbildungssemester']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ausbildungssemester']),
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$status_kurzbz = (isset($formData['status_kurzbz']) && !empty($formData['status_kurzbz']))
? $formData['status_kurzbz']
: null;
$mobilitaetsprogramm_code = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code']))
? $formData['mobilitaetsprogramm_code']
: null;
$gsprogramm_id = (isset($formData['gsprogramm_id']) && !empty($formData['gsprogramm_id']))
? $formData['gsprogramm_id']
: null;
$firma_id= (isset($formData['firma_id']) && !empty($formData['firma_id'])) ? $formData['firma_id'] : null;
$result = $this->MobilitaetModel->insert([
'prestudent_id' => $prestudent_id,
'mobilitaetstyp_kurzbz' =>$mobilitaetstyp_kurzbz,
'status_kurzbz' => $status_kurzbz,
'studiensemester_kurzbz' =>$studiensemester_kurzbz,
'mobilitaetsprogramm_code' => $mobilitaetsprogramm_code,
'gsprogramm_id' => $gsprogramm_id,
'firma_id' => $firma_id,
'ausbildungssemester' =>$ausbildungssemester,
'insertvon' => $authUID,
'insertamum' => date('c'),
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function updateStudie()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$prestudent_id = $this->input->post('prestudent_id');
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$mobilitaet_id = (isset($formData['mobilitaet_id']) && !empty($formData['mobilitaet_id']))
? $formData['mobilitaet_id'] :
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Mobilitaet ID']), self::ERROR_TYPE_GENERAL);
$ausbildungssemester = (isset($formData['ausbildungssemester']) && !empty($formData['ausbildungssemester']))
? $formData['ausbildungssemester']
: null;
$mobilitaetstyp_kurzbz = (isset($formData['mobilitaetstyp_kurzbz']) && !empty($formData['mobilitaetstyp_kurzbz']))
? $formData['mobilitaetstyp_kurzbz']
: null;
$studiensemester_kurzbz = (isset($formData['studiensemester_kurzbz']) && !empty($formData['studiensemester_kurzbz']))
? $formData['studiensemester_kurzbz']
: null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('mobilitaetstyp_kurzbz', 'Typ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Typ'])
]);
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Studiensemester'])
]);
$this->form_validation->set_rules('ausbildungssemester', 'Ausbildungssemester', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Ausbildungssemester']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ausbildungssemester']),
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$status_kurzbz = (isset($formData['status_kurzbz']) && !empty($formData['status_kurzbz'])) ? $formData['status_kurzbz'] : null;
$mobilitaetsprogramm_code = (isset($formData['mobilitaetsprogramm_code']) && !empty($formData['mobilitaetsprogramm_code']))
? $formData['mobilitaetsprogramm_code']
: null;
$gsprogramm_id = (isset($formData['gsprogramm_id']) && !empty($formData['gsprogramm_id']))
? $formData['gsprogramm_id']
: null;
$firma_id= (isset($formData['firma_id']) && !empty($formData['firma_id'])) ? $formData['firma_id'] : null;
$result = $this->MobilitaetModel->update(
[
'mobilitaet_id' => $mobilitaet_id,
],
[
'prestudent_id' => $prestudent_id,
'mobilitaetstyp_kurzbz' => $mobilitaetstyp_kurzbz,
'status_kurzbz' => $status_kurzbz,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'mobilitaetsprogramm_code' => $mobilitaetsprogramm_code,
'gsprogramm_id' => $gsprogramm_id,
'firma_id' => $firma_id,
'ausbildungssemester' => $ausbildungssemester,
'updatevon' => $authUID,
'updateamum' => date('c'),
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteStudie($mobilitaet_id)
{
if(!$mobilitaet_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Mobilität ID']), self::ERROR_TYPE_GENERAL);
}
$result = $this->MobilitaetModel->delete(
array('mobilitaet_id' => $mobilitaet_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,699 @@
<?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 grades
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Grades extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'list' => 'student/noten:r',
'getCertificate' => 'student/noten:r',
'getTeacherProposal' => 'student/noten:r',
'getRepeaterGrades' => 'student/noten:r',
'updateCertificate' => ['admin:w', 'assistenz:w'],
'deleteCertificate' => ['admin:w', 'assistenz:w'],
'copyTeacherProposalToCertificate' => 'student/noten:w',
'copyRepeaterGradeToCertificate' => 'student/noten:w',
'getGradeFromPoints' => 'student/noten:r'
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load Phrases
$this->loadPhrases([
'stv',
'person',
'lehre'
]);
}
/**
* List all possible grades
* (Entries in lehre.tbl_note)
*
* @return void
*/
public function list()
{
$this->load->model('codex/Note_model', 'NoteModel');
$this->NoteModel->addOrder('note');
$result = $this->NoteModel->load();
$grades = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($grades);
}
/**
* List grades for the certificate of a prestudent.
* (Entries in lehre.tbl_zeugnisnote)
*
* @param string $prestudent_id
* @param string|null $studiensemester_kurzbz If studiensemester_kurzbz only this semesters grades will be loaded, otherwise all semesters grades will be loaded.
*
* @return void
*/
public function getCertificate($prestudent_id, $studiensemester_kurzbz = null)
{
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudentModel->loadWhere([
'prestudent_id' => $prestudent_id
]);
$student = $this->getDataOrTerminateWithError($result);
if (!$student)
$this->terminateWithSuccess([]);
$student_uid = current($student)->student_uid;
if ($studiensemester_kurzbz !== null && !$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$result = $this->ZeugnisnoteModel->getZeugnisnoten($student_uid, $studiensemester_kurzbz);
$grades = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($grades);
}
/**
* List grades of a prestudent that teachers gave.
* (Entries in campus.tbl_lvgesamtnote)
*
* @param string $prestudent_id
* @param string|null $studiensemester_kurzbz If studiensemester_kurzbz only this semesters grades will be loaded, otherwise all semesters grades will be loaded.
*
* @return void
*/
public function getTeacherProposal($prestudent_id, $studiensemester_kurzbz = null)
{
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudentModel->loadWhere([
'prestudent_id' => $prestudent_id
]);
$student = $this->getDataOrTerminateWithError($result);
if (!$student)
$this->terminateWithSuccess([]);
$student_uid = current($student)->student_uid;
if ($studiensemester_kurzbz !== null && !$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$result = $this->LvgesamtnoteModel->getLvGesamtNoten(null, $student_uid, $studiensemester_kurzbz);
$grades = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($grades);
}
/**
* List grades of a prestudent that an assistant marked as already done
* or as not allowed because of the repeating of a semester.
*
* @param string $prestudent_id
* @param string|false $studiensemester_kurzbz If studiensemester_kurzbz only this semesters grades will be loaded, otherwise all semesters grades will be loaded.
*
* @return void
*/
public function getRepeaterGrades($prestudent_id, $studiensemester_kurzbz = false)
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->library('AntragLib');
if ($studiensemester_kurzbz !== false && !$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$result = $this->antraglib->getLvsForPrestudent($prestudent_id, $studiensemester_kurzbz);
$grades = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($grades);
}
/**
* Update or Insert a grade for the certificate of a prestudent.
* (Entry in lehre.tbl_zeugnisnote)
*
* @return void
*/
public function updateCertificate()
{
$this->load->library('form_validation');
$this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer");
$this->form_validation->set_rules("student_uid", $this->p->t('person', 'student'), "required");
$this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t('lehre', 'studiensemester'), "required");
$this->form_validation->set_rules('note', $this->p->t('lehre', 'note'), 'required|numeric');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$student_uid = $this->input->post('student_uid');
$lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
$note = $this->input->post('note');
$authUID = getAuthUID();
$now = date('c');
// NOTE(chris): Stg Permissions
if (!$this->hasPermissionUpdate($lehrveranstaltung_id, $student_uid))
return $this->_outputAuthError([$this->router->method => ['admin', 'assistenz']]);
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$result = $this->ZeugnisnoteModel->load([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $student_uid,
'lehrveranstaltung_id' => $lehrveranstaltung_id
]);
$current = $this->getDataOrTerminateWithError($result);
if ($current) {
$result = $this->ZeugnisnoteModel->update([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $student_uid,
'lehrveranstaltung_id' => $lehrveranstaltung_id
], [
'note' => $note,
'benotungsdatum' => $now,
'updateamum' => $now,
'updatevon' => $authUID
]);
} else {
$result = $this->ZeugnisnoteModel->insert([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $student_uid,
'lehrveranstaltung_id' => $lehrveranstaltung_id,
'note' => $note,
'benotungsdatum' => $now,
'insertamum' => $now,
'insertvon' => $authUID
]);
}
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
}
/**
* Delete a grade from the certificate of a prestudent.
* (Entry in lehre.tbl_zeugnisnote)
*
* @return void
*/
public function deleteCertificate()
{
$this->load->library('form_validation');
$this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer");
$this->form_validation->set_rules("student_uid", $this->p->t('person', 'student'), "required");
$this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t('lehre', 'studiensemester'), "required");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$student_uid = $this->input->post('student_uid');
$lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
// NOTE(chris): Stg Permissions
if (!$this->hasPermissionDelete($lehrveranstaltung_id, $student_uid))
return $this->_outputAuthError([$this->router->method => ['admin', 'assistenz']]);
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$result = $this->ZeugnisnoteModel->delete([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $student_uid,
'lehrveranstaltung_id' => $lehrveranstaltung_id
]);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
}
/**
* Copy a grade that teachers gave to the certificate of a prestudent.
* (Entry in campus.tbl_lvgesamtnote to an entry in lehre.tbl_zeugnisnote)
*
* @return void
*/
public function copyTeacherProposalToCertificate()
{
$this->load->library('form_validation');
$this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer");
$this->form_validation->set_rules("student_uid", $this->p->t('person', 'student'), "required");
$this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t('lehre', 'studiensemester'), "required");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
$student_uid = $this->input->post('student_uid');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$authUID = getAuthUID();
// NOTE(chris): Stg Permissions
if (!$this->hasPermissionCopy($lehrveranstaltung_id, $student_uid))
return $this->_outputAuthError([$this->router->method => 'student/noten']);
$this->load->model('education/Lvgesamtnote_model', 'LvgesamtnoteModel');
$result = $this->LvgesamtnoteModel->load([
'student_uid' => $student_uid,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'lehrveranstaltung_id' => $lehrveranstaltung_id
]);
$teacherGrade = $this->getDataOrTerminateWithError($result);
if (!$teacherGrade)
show_404();
$teacherGrade = current($teacherGrade);
$data = [
'note' => $teacherGrade->note,
'punkte' => $teacherGrade->punkte,
'uebernahmedatum' => date('c'),
'benotungsdatum' => $teacherGrade->benotungsdatum,
'bemerkung' => $teacherGrade->bemerkung
];
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$this->ZeugnisnoteModel->addJoin('lehre.tbl_note n', 'note');
$result = $this->ZeugnisnoteModel->load([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $student_uid,
'lehrveranstaltung_id' => $lehrveranstaltung_id
]);
$certificateGrade = $this->getDataOrTerminateWithError($result);
if ($certificateGrade) {
$certificateGrade = current($certificateGrade);
if (!$certificateGrade->lkt_ueberschreibbar)
$this->terminateWithError($this->p->t("stv", "grades_error_overwrite"));
// NOTE(chris): update
$data['updateamum'] = $data['uebernahmedatum'];
$data['updatevon'] = $authUID;
$this->ZeugnisnoteModel->update([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $student_uid,
'lehrveranstaltung_id' => $lehrveranstaltung_id
], $data);
} else {
// NOTE(chris): insert
$data['insertamum'] = $data['uebernahmedatum'];
$data['insertvon'] = $authUID;
$data['lehrveranstaltung_id'] = $lehrveranstaltung_id;
$data['student_uid'] = $student_uid;
$data['studiensemester_kurzbz'] = $studiensemester_kurzbz;
$this->ZeugnisnoteModel->insert($data);
if (defined('FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN')
&& FAS_PRUEFUNG_BEI_NOTENEINGABE_ANLEGEN) {
$result = $this->addTestsForGrade(
$studiensemester_kurzbz,
$student_uid,
$lehrveranstaltung_id,
$teacherGrade->note,
$teacherGrade->punkte
);
$this->getDataOrTerminateWithError($result);
}
}
$this->terminateWithSuccess(true);
}
/**
* Copy a grade that was marked by an assistant as already done or not
* allowed because of the repeating of a semester to the certificate of a
* prestudent.
*
* @return void
*/
public function copyRepeaterGradeToCertificate()
{
$this->load->library('form_validation');
$this->form_validation->set_rules("studierendenantrag_lehrveranstaltung_id", "studierendenantrag_lehrveranstaltung_id", "required|integer");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$id = $this->input->post('studierendenantrag_lehrveranstaltung_id');
$authUID = getAuthUID();
$this->load->model('education/Studierendenantraglehrveranstaltung_model', 'StudierendenantraglehrveranstaltungModel');
$this->StudierendenantraglehrveranstaltungModel->addSelect("tbl_studierendenantrag_lehrveranstaltung.*");
$this->StudierendenantraglehrveranstaltungModel->addSelect("student_uid");
$this->StudierendenantraglehrveranstaltungModel->addJoin("campus.tbl_studierendenantrag", "studierendenantrag_id");
$this->StudierendenantraglehrveranstaltungModel->addJoin("public.tbl_student", "prestudent_id", "LEFT");
$result = $this->StudierendenantraglehrveranstaltungModel->load($id);
$repeaterGrade = $this->getDataOrTerminateWithError($result);
if (!$repeaterGrade)
show_404();
$repeaterGrade = current($repeaterGrade);
// NOTE(chris): Stg Permissions
if (!$this->hasPermissionCopy($repeaterGrade->lehrveranstaltung_id, $repeaterGrade->student_uid))
return $this->_outputAuthError([$this->router->method => 'student/noten']);
$data = [
'note' => $repeaterGrade->note,
'uebernahmedatum' => date('c'),
'benotungsdatum' => $repeaterGrade->insertamum,
'bemerkung' => $repeaterGrade->anmerkung
];
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$result = $this->ZeugnisnoteModel->load([
$repeaterGrade->studiensemester_kurzbz,
$repeaterGrade->student_uid,
$repeaterGrade->lehrveranstaltung_id
]);
$certificateGrade = $this->getDataOrTerminateWithError($result);
if ($certificateGrade) {
// NOTE(chris): update
$data['updateamum'] = $data['uebernahmedatum'];
$data['updatevon'] = $authUID;
$this->ZeugnisnoteModel->update([
$repeaterGrade->studiensemester_kurzbz,
$repeaterGrade->student_uid,
$repeaterGrade->lehrveranstaltung_id
], $data);
} else {
// NOTE(chris): insert
$data['insertamum'] = $data['uebernahmedatum'];
$data['insertvon'] = $authUID;
$data['lehrveranstaltung_id'] = $repeaterGrade->lehrveranstaltung_id;
$data['student_uid'] = $repeaterGrade->student_uid;
$data['studiensemester_kurzbz'] = $repeaterGrade->studiensemester_kurzbz;
$this->ZeugnisnoteModel->insert($data);
}
$this->terminateWithSuccess(true);
}
/**
* Loads the grade from the points using the gradingkey
*
* @return void
*/
public function getGradeFromPoints()
{
$this->load->library('form_validation');
$this->form_validation->set_rules("lehrveranstaltung_id", $this->p->t('lehre', 'lehrveranstaltung'), "required|integer");
$this->form_validation->set_rules("points", $this->p->t("stv", "grades_points"), "required|numeric");
$this->form_validation->set_rules("studiensemester_kurzbz", $this->p->t("lehre", "studiensemester"), "required|regex_match[/^[WS]S[0-9]{4}$/]");
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$this->load->model('education/Notenschluesselaufteilung_model', 'NotenschluesselaufteilungModel');
$result = $this->NotenschluesselaufteilungModel->getNote(
$this->input->post('points'),
$this->input->post('lehrveranstaltung_id'),
$studiensemester_kurzbz
);
$note = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($note);
}
/**
* Helper function that adds tests for a student
* (Entries in lehre.tbl_pruefung)
*
* @param string $studiensemester_kurzbz
* @param string $student_uid
* @param integer $lehrveranstaltung_id
* @param integer $note
* @param numeric $punkte
*
* @return stdClass
*/
protected function addTestsForGrade($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id, $note, $punkte)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
// Get Lehreinheit
$result = $this->LehrveranstaltungModel->getLeByStudent($student_uid, $studiensemester_kurzbz, $lehrveranstaltung_id);
if (isError($result))
return $result;
if (!hasData($result))
return error($this->p->t("stv", "grades_error_lehreinheit_id"));
$le = current(getData($result));
// Prepare
$this->load->model('education/LePruefung_model', 'LePruefungModel');
$data = [
"student_uid" => $student_uid,
"lehreinheit_id" => $le->lehreinheit_id,
"datum" => date('Y-m-d'),
"pruefungstyp_kurzbz" => "Termin1",
"note" => $note
];
if (defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE)
$data["punkte"] = $punkte;
// Get Anwesenheit
$this->load->model('education/Anwesenheit_model', 'AnwesenheitModel');
$result = $this->AnwesenheitModel->loadAnwesenheitStudiensemester($studiensemester_kurzbz, $student_uid, $lehrveranstaltung_id);
if (isError($result))
return $result;
$anwesenheit = getData($result);
if ($anwesenheit && (float)current($anwesenheit)->prozent < FAS_ANWESENHEIT_ROT) {
// Get Anwesenheitsbefreiung
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerFunktionByUidInStdsem($student_uid, $studiensemester_kurzbz, 'awbefreit');
if (isError($result))
return $result;
$anwesenheitsbefreit = hasData($result);
// Wenn nicht Anwesenheitsbefreit und Anwesenheit unter einem bestimmten Prozentsatz fällt dann wird ein Pruefungsantritt abgezogen
if (!$anwesenheitsbefreit) {
$data2 = $data;
$data2["note"] = 7;
if (isset($data2["punkte"]))
unset($data2["punkte"]);
$result = $this->LePruefungModel->insert($data2);
if (isError($result))
return $result;
$data["pruefungstyp_kurzbz"] = "Termin2";
}
}
return $this->LePruefungModel->insert($data);
}
/**
* Helper function to check permissions for updateCertificate()
*
* @param integer $lehrveranstaltung_id
* @param string $student_uid
*
* @return boolean
*/
protected function hasPermissionUpdate($lehrveranstaltung_id, $student_uid)
{
if ($lehrveranstaltung_id === null || $student_uid === null)
return true;
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$student_uid]);
if (isError($result) || !hasData($result))
return false;
$student = current(getData($result));
if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz))
return true;
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz))
return true;
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$result = $this->StudienplanModel->getAllOesForLv($lehrveranstaltung_id);
if (isError($result))
return false;
$oes = getData($result) ?: [];
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getStg($lehrveranstaltung_id);
if (isError($result))
return false;
if (hasData($result))
$oes[] = current(getData($result));
foreach ($oes as $oe) {
if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz))
return true;
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz))
return true;
}
return false;
}
/**
* Helper function to check permissions for deleteCertificate()
*
* @param integer $lehrveranstaltung_id
* @param string $student_uid
*
* @return boolean
*/
protected function hasPermissionDelete($lehrveranstaltung_id, $student_uid)
{
if ($lehrveranstaltung_id === null || $student_uid === null)
return true;
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$student_uid]);
if (isError($result) || !hasData($result))
return false;
$student = current(getData($result));
if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz))
return true;
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz))
return true;
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
if (isError($result) || !hasData($result))
return false;
$oe = current(getData($result));
if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz))
return true;
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz))
return true;
return false;
}
/**
* Helper function to check permissions for
* copyTeacherProposalToCertificate() and copyRepeaterGradeToCertificate()
*
* @param integer $lehrveranstaltung_id
* @param string $student_uid
*
* @return boolean
*/
protected function hasPermissionCopy($lehrveranstaltung_id, $student_uid)
{
if ($lehrveranstaltung_id === null || $student_uid === null)
return true;
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$student_uid]);
if (isError($result) || !hasData($result))
return false;
$student = current(getData($result));
if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $student->studiengang_kz))
return true;
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
if (isError($result) || !hasData($result))
return false;
$oe = current(getData($result));
if ($this->permissionlib->isBerechtigt('student/noten', 'suid', $oe->oe_kurzbz))
return true;
return false;
}
}
@@ -0,0 +1,80 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Gruppen extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getGruppen' => ['admin:r', 'assistenz:r'],
'deleteGruppe' => ['admin:rw', 'assistenz:rw'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui', 'gruppenmanagement'
]);
// Load models
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('organisation/Gruppe_model', 'GruppeModel');
}
public function getGruppen($student_uid)
{
$this->BenutzergruppeModel ->addSelect('gruppe_kurzbz');
$this->BenutzergruppeModel ->addSelect('bezeichnung');
$this->BenutzergruppeModel ->addSelect('generiert');
$this->BenutzergruppeModel ->addSelect('uid');
$this->BenutzergruppeModel ->addSelect('studiensemester_kurzbz');
$this->BenutzergruppeModel ->addJoin('public.tbl_gruppe', 'gruppe_kurzbz');
$this->BenutzergruppeModel-> addOrder('bezeichnung', 'ASC');
$result = $this->BenutzergruppeModel->loadWhere(
array(
'uid' => $student_uid
)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteGruppe()
{
$student_uid = $this->input->post('id');
$gruppe_kurzbz = $this->input->post('gruppe_kurzbz');
//Validate if automatic group generation
$result = $this->GruppeModel-> loadWhere(
array(
'gruppe_kurzbz' => $gruppe_kurzbz
)
);
$data = $this->getDataOrTerminateWithError($result);
$generation = current($data);
if($generation->generiert)
{
$this->terminateWithError($this->p->t('gruppenmanagement', 'error_deleteGeneratedGroups'), self::ERROR_TYPE_GENERAL);
}
$result = $this->BenutzergruppeModel->delete(
array(
'gruppe_kurzbz' => $gruppe_kurzbz,
'uid' => $student_uid
)
);
$data = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($data);
}
}
@@ -28,7 +28,8 @@ class Kontakt extends FHCAPI_Controller
'getStandorte' => ['admin:r', 'assistenz:r'],
'getStandorteByFirma' => ['admin:r', 'assistenz:r'],
'getKontakte' => ['admin:r', 'assistenz:r'],
'getBankverbindung' => ['mitarbeiter/bankdaten:r', 'student/bankdaten:r']
'getBankverbindung' => ['mitarbeiter/bankdaten:r', 'student/bankdaten:r'],
'getAllFirmen' => ['admin:r', 'assistenz:r']
]);
// Load Libraries
@@ -46,6 +47,7 @@ class Kontakt extends FHCAPI_Controller
$this->load->model('organisation/standort_model', 'StandortModel');
$this->load->model('ressource/firma_model', 'FirmaModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Kontakttyp_model', 'KontakttypModel');
// Extra Permissionchecks
$permsMa = [];
@@ -85,7 +87,10 @@ class Kontakt extends FHCAPI_Controller
|| $this->router->method == 'addNewBankverbindung'
) {
$person_id = current(array_slice($this->uri->rsegments, 2));
if (is_null($person_id) || !ctype_digit((string)$person_id))
$this->terminateWithError( $this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud);
} elseif ($this->router->method == 'loadAddress'
|| $this->router->method == 'loadContact'
@@ -97,7 +102,14 @@ class Kontakt extends FHCAPI_Controller
|| $this->router->method == 'deleteContact'
|| $this->router->method == 'deleteBankverbindung'
) {
$id = current(array_slice($this->uri->rsegments, 2));
if($this->input->post('address_id'))
$id = $this->input->post('address_id');
if($this->input->post('adresse_id'))
$id = $this->input->post('adresse_id');
if($this->input->post('bankverbindung_id'))
$id = $this->input->post('bankverbindung_id');
if($this->input->post('kontakt_id'))
$id = $this->input->post('kontakt_id');
$model = 'person/Adresse_model';
if ($this->router->method == 'loadContact'
@@ -112,6 +124,9 @@ class Kontakt extends FHCAPI_Controller
$model = 'person/Bankverbindung_model';
}
if (!isset($id) || !ctype_digit((string)$id))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model($model, 'TempModel');
$result = $this->TempModel->load($id);
$data = $this->getDataOrTerminateWithError($result);
@@ -125,7 +140,12 @@ class Kontakt extends FHCAPI_Controller
}
public function getAdressen($person_id)
{
$this->AdresseModel->addSelect('public.tbl_adresse.*');
$this->AdresseModel->addSelect("public.tbl_adresse.*,
(CASE
WHEN public.tbl_adresse.updateamum >= public.tbl_adresse.insertamum
THEN public.tbl_adresse.updateamum
ELSE public.tbl_adresse.insertamum
END) AS lastUpdate");
$this->AdresseModel->addSelect('t.*');
$this->AdresseModel->addSelect('f.firma_id');
$this->AdresseModel->addSelect('f.name as firmenname');
@@ -143,15 +163,26 @@ class Kontakt extends FHCAPI_Controller
public function addNewAddress($person_id)
{
$this->form_validation->set_rules('plz', 'PLZ', 'required|numeric', [
$this->form_validation->set_data(['address.plz' => $_POST['plz']]);
$this->form_validation->set_rules('address.plz', 'PLZ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ'])
]);
if(isset($_POST['gemeinde']) && isset($_POST['ort']))
$this->form_validation->set_rules('plz', 'Postleitzahl', 'callback_validateLocationCombination', [
'validateLocationCombination' => $this->p->t('ui', 'error_location_combination')
]);
if(isset($_POST['nation']) && $_POST['nation'] == 'A')
{
$this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ'])
]);
}
if(isset($_POST['gemeinde']) && isset($_POST['ort']) && isset($_POST['nation']) && $_POST['nation'] == 'A')
{
$this->form_validation->set_rules('address.plz', 'Postleitzahl', 'callback_validateLocationCombination', [
'validateLocationCombination' => $this->p->t('ui', 'error_location_combination')
]);
}
if ($this->form_validation->run() == false)
{
@@ -167,13 +198,7 @@ class Kontakt extends FHCAPI_Controller
$name = isset($_POST['name']) ? $_POST['name'] : null;
$typ = isset($_POST['typ']) ? $_POST['typ'] : null;
$anmerkung = isset($_POST['anmerkung']) ? $_POST['anmerkung'] : null;
if(isset($_POST['firma']))
{
$firma_id = $_POST['firma']['firma_id'];
}
else
$firma_id = null;
$firma_id = isset($_POST['firma_id']) ? $_POST['firma_id'] : null;
$result = $this->AdresseModel->insert(
[
@@ -196,25 +221,37 @@ class Kontakt extends FHCAPI_Controller
]
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function updateAddress($address_id)
public function updateAddress()
{
$address_id = $this->input->post('adresse_id');
$this->form_validation->set_data(['address.plz' => $_POST['plz']]);
$uid = getAuthUID();
$this->form_validation->set_rules('plz', 'PLZ', 'required|numeric', [
$this->form_validation->set_rules('address.plz', 'PLZ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ'])
]);
if(isset($_POST['gemeinde']) && isset($_POST['ort']))
$this->form_validation->set_rules('plz', 'Postleitzahl', 'callback_validateLocationCombination', [
if(isset($_POST['nation']) && $_POST['nation'] == 'A')
{
$this->form_validation->set_rules('address.plz', 'PLZ', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ'])
]);
}
if(isset($_POST['gemeinde']) && isset($_POST['ort']) && isset($_POST['nation']) && $_POST['nation'] == 'A')
{
$this->form_validation->set_rules('address.plz', 'Postleitzahl', 'callback_validateLocationCombination', [
'validateLocationCombination' => $this->p->t('ui', 'error_location_combination')
]);
}
if ($this->form_validation->run() == false)
{
@@ -228,17 +265,6 @@ class Kontakt extends FHCAPI_Controller
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Adresse_id']), self::ERROR_TYPE_GENERAL);
}
if(isset($_POST['firma']))
{
$firma_id = $_POST['firma']['firma_id'];
}
elseif(isset($_POST['firma_id']))
{
$firma_id = $_POST['firma_id'];
}
else
$firma_id = null;
$person_id = isset($_POST['person_id']) ? $_POST['person_id'] : null;
$co_name = isset($_POST['co_name']) ? $_POST['co_name'] : null;
$strasse = isset($_POST['strasse']) ? $_POST['strasse'] : null;
@@ -248,6 +274,7 @@ class Kontakt extends FHCAPI_Controller
$name = isset($_POST['name']) ? $_POST['name'] : null;
$typ = isset($_POST['typ']) ? $_POST['typ'] : null;
$anmerkung = isset($_POST['anmerkung']) ? $_POST['anmerkung'] : null;
$firma_id = isset($_POST['firma_id']) ? $_POST['firma_id'] : null;
$result = $this->AdresseModel->update(
[
@@ -272,15 +299,15 @@ class Kontakt extends FHCAPI_Controller
]
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadAddress($adresse_id)
public function loadAddress()
{
$adresse_id = $this->input->post('address_id');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->AdresseModel->addSelect('public.tbl_adresse.*');
@@ -306,8 +333,10 @@ class Kontakt extends FHCAPI_Controller
$this->terminateWithSuccess(current(getData($result)) ? : null);
}
public function deleteAddress($adresse_id)
public function deleteAddress()
{
$adresse_id = $this->input->post('address_id');
$this->load->model('person/Adresse_model', 'AdresseModel');
$result = $this->AdresseModel->load([
'adresse_id'=> $adresse_id,
@@ -350,8 +379,11 @@ class Kontakt extends FHCAPI_Controller
$this->terminateWithSuccess(getData($result) ?: []);
}
public function getFirmen($searchString)
public function getFirmen($searchString = null)
{
if (is_null($searchString))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('ressource/firma_model', 'FirmaModel');
$result = $this->FirmaModel->searchFirmen($searchString);
@@ -361,19 +393,25 @@ class Kontakt extends FHCAPI_Controller
$this->terminateWithSuccess($result ?: []);
}
public function getStandorte($searchString)
public function getStandorte($searchString = null)
{
if (is_null($searchString))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('organisation/standort_model', 'StandortModel');
$result = $this->StandortModel->searchStandorte($searchString);
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess($result ?: []);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStandorteByFirma($firma_id)
public function getStandorteByFirma($firma_id = null)
{
if (is_null($firma_id) || !ctype_digit((string)$firma_id))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->load->model('organisation/standort_model', 'StandortModel');
$result = $this->StandortModel->getStandorteByFirma($firma_id);
@@ -386,15 +424,20 @@ class Kontakt extends FHCAPI_Controller
public function getKontakte($person_id)
{
$this->KontaktModel->addSelect("public.tbl_kontakt.*,
TO_CHAR (CASE
WHEN public.tbl_kontakt.updateamum >= public.tbl_kontakt.insertamum
THEN public.tbl_kontakt.updateamum
ELSE public.tbl_kontakt.insertamum
END::timestamp, 'DD.MM.YYYY HH24:MI:SS') AS lastUpdate, st.bezeichnung, f.name");
(CASE
WHEN public.tbl_kontakt.updateamum >= public.tbl_kontakt.insertamum
THEN public.tbl_kontakt.updateamum
ELSE public.tbl_kontakt.insertamum
END) AS lastUpdate, st.bezeichnung, f.name");
$this->KontakttypModel->addSelect("kt.beschreibung as kontakttypbeschreibung");
$this->StandortModel->addJoin('public.tbl_standort st', 'ON (public.tbl_kontakt.standort_id = st.standort_id)', 'LEFT');
$this->FirmaModel->addJoin('public.tbl_firma f', 'ON (f.firma_id = st.firma_id)', 'LEFT');
$this->KontakttypModel->addJoin('public.tbl_kontakttyp kt', 'ON (public.tbl_kontakt.kontakttyp = kt.kontakttyp)');
$result = $this->KontaktModel->loadWhere(
array('person_id' => $person_id)
array(
'person_id' => $person_id,
'public.tbl_kontakt.kontakttyp !=' => 'hidden'
)
);
if (isError($result))
@@ -402,24 +445,23 @@ class Kontakt extends FHCAPI_Controller
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getKontakttypen()
{
$this->load->model('person/Kontakttyp_model', 'KontakttypModel');
$this->KontakttypModel->addOrder('beschreibung', 'ASC');
$result = $this->KontakttypModel->loadWhere(array('kontakttyp !=' => 'hidden'));
$result = $this->KontakttypModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
else
{
$this->terminateWithSuccess(getData($result) ?: []);
}
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadContact($kontakt_id)
public function loadContact()
{
$kontakt_id = $this->input->post('kontakt_id');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->KontaktModel->addSelect('*, public.tbl_kontakt.*');
@@ -439,7 +481,6 @@ class Kontakt extends FHCAPI_Controller
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Kontakt_id']), self::ERROR_TYPE_GENERAL);
}
// $this->outputJsonSuccess(current(getData($result)));
$this->terminateWithSuccess(current(getData($result)));
}
@@ -492,11 +533,12 @@ class Kontakt extends FHCAPI_Controller
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
$this->terminateWithSuccess($result);
}
public function updateContact($kontakt_id)
public function updateContact()
{
$kontakt_id = $this->input->post('kontakt_id');
$this->load->model('person/Kontakt_model', 'KontaktModel');
if(!$kontakt_id)
@@ -523,13 +565,6 @@ class Kontakt extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
/* if(isset($_POST['standort']))
{
$standort_id = $_POST['standort']['standort_id'];
}
else
$standort_id = null;*/
$uid = getAuthUID();
$kontakttyp = $this->input->post('kontakttyp');
$anmerkung = $this->input->post('anmerkung');
@@ -538,8 +573,6 @@ class Kontakt extends FHCAPI_Controller
$person_id = $this->input->post('person_id');
$standort_id = $this->input->post('standort_id');
//return $this->terminateWithError("in update " . $standort_id, self::ERROR_TYPE_GENERAL);
$result = $this->KontaktModel->update(
[
'kontakt_id' => $kontakt_id
@@ -550,22 +583,21 @@ class Kontakt extends FHCAPI_Controller
'anmerkung' => $anmerkung,
'kontakt' => $kontakt,
'zustellung' => $_POST['zustellung'],
'insertvon' => $uid,
'insertamum' => date('c'),
'updatevon' => $uid,
'updateamum' => date('c'),
'standort_id' => $standort_id,
'ext_id' => $ext_id
]
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteContact($kontakt_id)
public function deleteContact()
{
$kontakt_id = $this->input->post('kontakt_id');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$result = $this->KontaktModel->delete(
@@ -624,6 +656,10 @@ class Kontakt extends FHCAPI_Controller
$bic = $this->input->post('bic');
$blz = $this->input->post('blz');
$kontonr = $this->input->post('kontonr');
$iban = $this->input->post('iban');
$typ = $this->input->post('typ');
$verrechnung = $this->input->post('verrechnung');
$uid = getAuthUID();
$result = $this->BankverbindungModel->insert(
[
@@ -631,27 +667,27 @@ class Kontakt extends FHCAPI_Controller
'name' => $name,
'anschrift' => $anschrift,
'bic' => $bic,
'iban' => $_POST['iban'],
'iban' => $iban,
'blz' => $blz,
'kontonr' => $kontonr,
'insertvon' => 'uid',
'insertvon' => $uid,
'insertamum' => date('c'),
'typ' => $_POST['typ'],
'verrechnung' => $_POST['verrechnung'],
'typ' => $typ,
'verrechnung' => $verrechnung,
'ext_id' => $ext_id,
'oe_kurzbz' => $oe_kurzbz,
'orgform_kurzbz' => $orgform_kurzbz
]
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadBankverbindung($bankverbindung_id)
public function loadBankverbindung()
{
$bankverbindung_id = $this->input->post('bankverbindung_id');
$this->load->model('person/Bankverbindung_model', 'BankverbindungModel');
$this->BankverbindungModel->addSelect('*');
@@ -719,15 +755,15 @@ class Kontakt extends FHCAPI_Controller
]
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function deleteBankverbindung($bankverbindung_id)
public function deleteBankverbindung()
{
$bankverbindung_id = $this->input->post('bankverbindung_id');
$this->load->model('person/Bankverbindung_model', 'BankverbindungModel');
$result = $this->BankverbindungModel->delete(
@@ -740,7 +776,7 @@ class Kontakt extends FHCAPI_Controller
}
if (!hasData($result))
{
$this->outputJson($result);
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Bankverbindung_id']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)) ? : null);
}
@@ -751,4 +787,25 @@ class Kontakt extends FHCAPI_Controller
return $this->GemeindeModel->checkLocation($_POST['plz'], $_POST['gemeinde'], $_POST['ort']);
}
/*
* returns list of all companies
* as key value list to be used in select or autocomplete
*/
public function getAllFirmen()
{
$sql = "
SELECT
f.firma_id, f.name,
f.name AS label
FROM public.tbl_firma f
ORDER BY f.name ASC";
$result = $this->FirmaModel->execReadOnlyQuery($sql);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -116,6 +116,8 @@ class Konto extends FHCAPI_Controller
{
$this->load->model('crm/Buchungstyp_model', 'BuchungstypModel');
$this->BuchungstypModel->addOrder('beschreibung');
$result = $this->BuchungstypModel->load();
$data = $this->getDataOrTerminateWithError($result);
@@ -1,264 +1,137 @@
<?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');
class Stundenplan extends FHCAPI_Controller
{
use \DateTime as DateTime;
/**
* Object initialization
*/
class LvTermine extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getRoomplan' => self::PERM_LOGGED,
'Stunden' => self::PERM_LOGGED,
'Reservierungen' => self::PERM_LOGGED,
'getStundenplan' => self::PERM_LOGGED,
'getLehreinheitStudiensemester' => self::PERM_LOGGED,
'getStundenplan' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r'],
]);
$this->load->library('LogLib');
$this->loglib->setConfigs(array(
'classIndex' => 5,
'functionIndex' => 5,
'lineIndex' => 4,
'dbLogType' => 'API', // required
'dbExecuteUser' => 'RESTful API'
));
$this->load->library('form_validation');
//load models
$this->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$this->load->model('ressource/Reservierung_model', 'ReservierungModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* fetches Stunden layout from database
* @access public
*
*/
public function Stunden()
{
$this->load->model('ressource/Stunde_model', 'StundeModel');
$stunden = $this->StundeModel->load();
$stunden = $this->getDataOrTerminateWithError($stunden);
$this->terminateWithSuccess($stunden);
}
/**
* fetches room events from a certain date
* @access public
*
*/
public function getRoomplan()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('ort_kurzbz',"Ort","required");
$this->form_validation->set_rules('start_date',"start_date","required");
$this->form_validation->set_rules('end_date',"end_date","required");
if($this->form_validation->run() === FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$ort_kurzbz = $this->input->get('ort_kurzbz', TRUE);
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
$roomplan_data = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getRoomQuery($ort_kurzbz, $start_date, $end_date));
$roomplan_data = $this->getDataOrTerminateWithError($roomplan_data);
$this->expand_object_information($roomplan_data);
$this->terminateWithSuccess($roomplan_data);
}
/**
* fetches stundenplan events from a UID and start/end date
* @access public
*
*/
//TODO: getStundenplan fuer Mitarbeiter anpassen
public function getStundenplan(){
$this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel');
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->model('person/Benutzergruppe_model','BenutzergruppeModel');
// form validation
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('start_date', "start_date", "required");
$this->form_validation->set_rules('end_date', "end_date", "required");
if ($this->form_validation->run() === FALSE)
$this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
// Load language phrases
$this->loadPhrases([
'ui',
]);
$student_uid = getAuthUID();
if(is_null($student_uid))
{
$this->terminateWithError("No UID");
}
// Load models
$this->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$is_mitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter($student_uid));
if($is_mitarbeiter)
{
$this->terminateWithError("Not possible to look at the Student Calendar as a Mitarbeiter");
}
$semester_range = $this->studienSemesterErmitteln($start_date,$end_date);
//query verwenden wie im Cis endpoint
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
}
//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")
{
$student_uid = $uid;
$semester_range = $this->studienSemesterErmitteln($start_date, $end_date);
$this->sortStudienSemester($semester_range);
$this->applyLoadUeberSemesterHaelfte($semester_range);
// getting the gruppen_kurzbz of the student in the different studiensemester
$benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($semester_range);
// getting the student_lehrverbaende of the student in the different studiensemester
$student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($semester_range);
$stundenplan_query = $this->StundenplanModel->getStundenplanQuery($start_date, $end_date, $semester_range, $benutzer_gruppen, $student_lehrverband);
$benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($semester_range, $student_uid);
$student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($semester_range, $student_uid);
if(!$groupConsecutiveHours)
$stundenplan_query = $this->StundenplanModel->getStundenplanQuery(
$start_date,
$end_date,
$semester_range,
$benutzer_gruppen,
$student_lehrverband
);
else
$stundenplan_query = $this->StundenplanModel->getStundenplanQuery(
$start_date,
$end_date,
$semester_range,
$benutzer_gruppen,
$student_lehrverband,
true,
$dbStundenplanTable
);
if(!$stundenplan_query)
{
$this->terminateWithSuccess([]);
}
$stundenplan_data = $this->StundenplanModel->stundenplanGruppierung($stundenplan_query);
if($groupConsecutiveHours)
{
$stundenplan_data = $this->StundenplanModel->stundenplanGruppierungConsecutive($stundenplan_query);
}
else
{
$stundenplan_data = $this->StundenplanModel->stundenplanGruppierung($stundenplan_query);
}
$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);
}
// gets the reservierungen of a room if the ort_kurzbz parameter is supplied otherwise gets the reservierungen of the stundenplan of a student
public function Reservierungen($ort_kurzbz = null)
public function getStudiensemester()
{
//form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('start_date', "StartDate", "required");
$this->form_validation->set_rules('end_date', "EndDate", "required");
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
// querying the reservierungen
$reservierungen = $this->ReservierungModel->getReservierungen($start_date, $end_date, $ort_kurzbz);
$reservierungen = $this->getDataOrTerminateWithError($reservierungen) ?? [];
$this->expand_object_information($reservierungen);
$this->terminateWithSuccess($reservierungen);
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addOrder('studienjahr_kurzbz', 'DESC');
$result = $this->StudiensemesterModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLehreinheitStudiensemester($lehreinheit_id){
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->LehreinheitModel->addSelect(["studiensemester_kurzbz"]);
$result = $this->LehreinheitModel->load($lehreinheit_id);
$result = current($this->getDataOrTerminateWithError($result))->studiensemester_kurzbz;
$this->terminateWithSuccess($result);
}
//copied from Stundenplan.php
private function studienSemesterErmitteln($start_date, $end_date)
{
// gets all studiensemester from the student from start_date to end_date
$semester_range = $this->StudiensemesterModel->getByDateRange($start_date, $end_date);
$semester_range = array_map(
function ($sem) {
return $sem->studiensemester_kurzbz;
},
$this->getDataOrTerminateWithError($semester_range)
);
// ################# Private Functions
private function expand_object_information($data){
foreach ($data as $item)
// if no studiensemester is found for the given timespan, get the nearest studiensemester
if(count($semester_range) == 0)
{
$lektor_obj_array = array();
$gruppe_obj_array = array();
// load lektor object
foreach ($item->lektor as $lv_lektor)
{
$this->StundenplanModel->addLimit(1);
$lektor_object = $this->StundenplanModel->execReadOnlyQuery("
SELECT mitarbeiter_uid, vorname, nachname, kurzbz
FROM public.tbl_mitarbeiter
JOIN public.tbl_benutzer benutzer ON benutzer.uid = mitarbeiter_uid
JOIN public.tbl_person person ON person.person_id = benutzer.person_id
WHERE kurzbz = ?", [$lv_lektor]);
if (isError($lektor_object)) {
$this->show_error(getError($lektor_object));
}
$lektor_object = $this->getDataOrTerminateWithError($lektor_object);
if(count($lektor_object) == 0)
{
$this->terminateWithError("No lektor object");
}
$lektor_object = current($lektor_object);
// only provide needed information of the mitarbeiter object
$lektor_obj_array[] = $lektor_object;
$aktuelle_studiensemester = $this->StudiensemesterModel->getNearest();
$aktuelle_studiensemester = $this->getDataOrTerminateWithError($aktuelle_studiensemester);
if (count($aktuelle_studiensemester) == 0) {
$this->terminateWithError("No aktuelles semester");
}
// load gruppe object
foreach ($item->gruppe as $lv_gruppe)
{
$lv_gruppe = strtr($lv_gruppe, ['(' => '', ')' => '', '"' => '']);
$lv_gruppe_array = explode(",", $lv_gruppe);
list($gruppe, $verband, $semester, $studiengang_kz, $gruppen_kuerzel) = $lv_gruppe_array;
$lv_gruppe_object = new stdClass();
$lv_gruppe_object->gruppe = $gruppe;
$lv_gruppe_object->verband = $verband;
$lv_gruppe_object->semester = $semester;
$lv_gruppe_object->studiengang_kz = $studiengang_kz;
$lv_gruppe_object->kuerzel = $gruppen_kuerzel;
$gruppe_obj_array[] = $lv_gruppe_object;
}
$item->gruppe = $gruppe_obj_array;
$item->lektor = $lektor_obj_array;
$aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz;
// push aktuelles semester in active semester array
array_push($semester_range, $aktuelle_studiensemester);
}
return $semester_range;
}
// function used to sort an array of studiensemester strings
private function sortStudienSemester(&$semester_range){
//copied from Stundenplan.php
private function sortStudienSemester(&$semester_range)
{
usort(
$semester_range,
function($first,$second)
{
function ($first, $second) {
$sem_first = null;
$year_first = null;
$match_first = null;
@@ -267,9 +140,9 @@ class Stundenplan extends FHCAPI_Controller
$year_second = null;
$match_second = null;
preg_match('/([WS]+)([0-9]+)/',$first,$match_first);
preg_match('/([WS]+)([0-9]+)/',$second,$match_second);
preg_match('/([WS]+)([0-9]+)/', $first, $match_first);
preg_match('/([WS]+)([0-9]+)/', $second, $match_second);
$sem_first = $match_first[1];
$year_first = intval($match_first[2]);
@@ -280,145 +153,29 @@ class Stundenplan extends FHCAPI_Controller
{
return -1;
}
else if($year_first > $year_second)
elseif($year_first > $year_second)
{
return 1;
}
else if($year_first == $year_second && $sem_first > $sem_second)
elseif($year_first == $year_second && $sem_first > $sem_second)
{
return 1;
}
else if($year_first == $year_second && $sem_first < $sem_second)
elseif($year_first == $year_second && $sem_first < $sem_second)
{
return -1;
}
return 0;
}
);
}
private function fetchBenutzerGruppenFromStudiensemester($semester_range){
$student_uid = getAuthUID();
$benutzer_gruppen = [];
// for each studiensemester fetch the benutzer gruppen and add them to an associate $bentuzer_gruppen array
/*
[
['WS2023'] => [['gruppe1_SS2023','gruppe2_SS2023'],['gruppe1_WS2023','gruppe2_WS2023']],
['SS2024'] => [['gruppe1_WS2023','gruppe2_WS2023'],['gruppe1_SS2024','gruppe2_SS2024']],
['WS2024'] => [['gruppe1_SS2024','gruppe2_SS2024'],['gruppe1_WS2024','gruppe2_WS2024']],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$benutzer_gruppen[$semester_key] = [];
// each semester could have ajoint semesters that need to be checked
foreach($semester_array as $semester=>$semester_date_range)
{
// for each active semester query the benutzer_gruppen associated to the semester
$benutzer_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz = ?",[$student_uid, $semester]);
$benutzer_query_result = $this->getDataOrTerminateWithError($benutzer_query);
array_push(
$benutzer_gruppen[$semester_key],
array_map(
function($item)
{
return "'".$item->gruppe_kurzbz. "'";
},
$benutzer_query_result
)
);
}
}
// merge the gruppen of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => ['gruppe1_SS2023','gruppe2_SS2023','gruppe1_WS2023','gruppe2_WS2023'],
['SS2024'] => ['gruppe1_WS2023','gruppe2_WS2023','gruppe1_SS2024','gruppe2_SS2024'],
['WS2024'] => ['gruppe1_SS2024','gruppe2_SS2024','gruppe1_WS2024','gruppe2_WS2024'],
]
*/
$benutzer_gruppen = array_map(
function($gruppe)
{
$merged_gruppe = [];
foreach($gruppe as $gruppen_array)
{
$merged_gruppe = array_merge($merged_gruppe, $gruppen_array);
}
return $merged_gruppe;
},
$benutzer_gruppen
);
return $benutzer_gruppen;
}
private function fetchStudentlehrverbandFromStudiensemester($semester_range){
$student_uid = getAuthUID();
$student_lehrverband = [];
// for each studiensemester fetch the studentlehrverbaende and add them to an associate $student_lehrverband array
/*
[
['WS2023'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ] ],
['SS2024'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ] ],
['WS2024'] => [ [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ] ],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$student_lehrverband[$semester_key] = [];
foreach($semester_array as $semester=>$semester_date_range)
{
// for each active semester query the student_lehrverband associated to the semester
$lehrverband_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]);
$lehrverband_query_result = $this->getDataOrTerminateWithError($lehrverband_query);
array_push($student_lehrverband[$semester_key], array_map(
function ($item)
{
$result = new stdClass();
$result->studiengang_kz = $item->studiengang_kz;
$result->semester = $item->semester;
$result->verband = $item->verband;
$result->gruppe = $item->gruppe;
return $result;
},
$lehrverband_query_result));
}
}
// merge the studentlehrverband of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ],
['SS2024'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ],
['WS2024'] => [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ],
]
*/
$student_lehrverband = array_map(
function($studentlehrverband)
{
$merged_studentlehrverband = [];
foreach($studentlehrverband as $studentlehrverband_array)
{
$merged_studentlehrverband = array_merge($merged_studentlehrverband, $studentlehrverband_array);
}
return $merged_studentlehrverband;
},
$student_lehrverband
);
return $student_lehrverband;
}
private function applyLoadUeberSemesterHaelfte(&$semester_range){
//copied from Stundenplan.php
private function applyLoadUeberSemesterHaelfte(&$semester_range)
{
/*
@var($semester_collection)
convert the array of studiensemester into an associative array with the studiensemester as the key
convert the array of studiensemester into an associative array with the studiensemester as the key
and the values of each key are the studiensemester needed for the query associated to that studiensemester
example:
@@ -446,7 +203,7 @@ class Stundenplan extends FHCAPI_Controller
/*
@var($studienSemesterDateRanges)
fetches for each studiensemester the start and end date, (SS) summer studiensemester are extended by 1 month to cover the summerbreak
based on the LVPLAN_LOAD_UEBER_SEMESTERHAELFTE constant it will load both the semester and the previous semester with the full date range
based on the LVPLAN_LOAD_UEBER_SEMESTERHAELFTE constant it will load both the semester and the previous semester with the full date range
or the semester with the full date range and the previous semester with the half date range:
#INPUT:
@@ -483,26 +240,26 @@ class Stundenplan extends FHCAPI_Controller
]
]
*/
$studienSemesterDateRanges=[];
$studienSemesterDateRanges=[];
foreach($semester_collection as $semester_original => $semester_adjoint)
{
$semester_start_ende = $this->StudiensemesterModel->getStartEndeFromStudiensemester($semester_original);
$semester_start_ende = current($this->getDataOrTerminateWithError($semester_start_ende));
$semester_start_ende = current($this->getDataOrTerminateWithError($semester_start_ende));
// initialize empty arrays to add key value pairs
$studienSemesterDateRanges[$semester_original] = [];
// check if the studiensemester is a summer semester and add 1 month to bridge the school summer break
$match = null;
preg_match("/^(SS)([0-9]+)/",$semester_original,$match);
preg_match("/^(SS)([0-9]+)/", $semester_original, $match);
if(count($match) >0)
{
$one_month = new DateInterval('P1M');
$one_day = DateInterval::createFromDateString('1 days');
$summer_studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende);
$summer_studiensemester_end_date = DateTime::createFromFormat('Y-m-d', $semester_start_ende->ende);
$summer_studiensemester_end_date->add($one_month);
$summer_studiensemester_end_date->sub($one_day);
$semester_start_ende->ende = date_format($summer_studiensemester_end_date,'Y-m-d');
$semester_start_ende->ende = date_format($summer_studiensemester_end_date, 'Y-m-d');
}
if (defined('LVPLAN_LOAD_UEBER_SEMESTERHAELFTE') && LVPLAN_LOAD_UEBER_SEMESTERHAELFTE === true)
{
@@ -515,13 +272,13 @@ class Stundenplan extends FHCAPI_Controller
{
//TODO: half of a DateInterval might not be correctly calculated
// calculate the half of the studiensemester
$studiensemester_start_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->start);
$studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende);
$studiensemester_start_date = DateTime::createFromFormat('Y-m-d', $semester_start_ende->start);
$studiensemester_end_date = DateTime::createFromFormat('Y-m-d', $semester_start_ende->ende);
$studiensemester_time_difference = $studiensemester_start_date->diff($studiensemester_end_date);
$half_dateNumber = ceil($studiensemester_time_difference->d/2)+ceil(($studiensemester_time_difference->m*30)/2);
$half_dateInterval = new DateInterval('P'.strval($half_dateNumber) .'D');
$studiensemester_half = date_format($studiensemester_start_date->add($half_dateInterval),'Y-m-d');
$studiensemester_half = date_format($studiensemester_start_date->add($half_dateInterval), 'Y-m-d');
$first_half = new stdClass();
$first_half->start = $semester_start_ende->start;
$first_half->ende = $studiensemester_half;
@@ -533,32 +290,119 @@ class Stundenplan extends FHCAPI_Controller
}
}
private function studienSemesterErmitteln($start_date,$end_date){
// gets all studiensemester from the student from start_date to end_date
$semester_range = $this->StudiensemesterModel->getByDate($start_date,$end_date);
$semester_range = array_map(
function($sem)
//copied from Stundenplan.php, extended with $student_uid
private function fetchBenutzerGruppenFromStudiensemester($semester_range, $student_uid)
{
//$student_uid = getAuthUID();
$benutzer_gruppen = [];
// for each studiensemester fetch the benutzer gruppen and add them to an associate $bentuzer_gruppen array
/*
[
['WS2023'] => [['gruppe1_SS2023','gruppe2_SS2023'],['gruppe1_WS2023','gruppe2_WS2023']],
['SS2024'] => [['gruppe1_WS2023','gruppe2_WS2023'],['gruppe1_SS2024','gruppe2_SS2024']],
['WS2024'] => [['gruppe1_SS2024','gruppe2_SS2024'],['gruppe1_WS2024','gruppe2_WS2024']],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$benutzer_gruppen[$semester_key] = [];
// each semester could have ajoint semesters that need to be checked
foreach($semester_array as $semester => $semester_date_range)
{
return $sem->studiensemester_kurzbz;
// for each active semester query the benutzer_gruppen associated to the semester
$benutzer_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]);
$benutzer_query_result = $this->getDataOrTerminateWithError($benutzer_query);
array_push(
$benutzer_gruppen[$semester_key],
array_map(
function ($item) {
return "'".$item->gruppe_kurzbz. "'";
},
$benutzer_query_result
)
);
}
}
// merge the gruppen of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => ['gruppe1_SS2023','gruppe2_SS2023','gruppe1_WS2023','gruppe2_WS2023'],
['SS2024'] => ['gruppe1_WS2023','gruppe2_WS2023','gruppe1_SS2024','gruppe2_SS2024'],
['WS2024'] => ['gruppe1_SS2024','gruppe2_SS2024','gruppe1_WS2024','gruppe2_WS2024'],
]
*/
$benutzer_gruppen = array_map(
function ($gruppe) {
$merged_gruppe = [];
foreach($gruppe as $gruppen_array)
{
$merged_gruppe = array_merge($merged_gruppe, $gruppen_array);
}
return $merged_gruppe;
},
$this->getDataOrTerminateWithError($semester_range)
$benutzer_gruppen
);
// if no studiensemester is found for the given timespan, get the nearest studiensemester
if(count($semester_range) == 0)
{
$aktuelle_studiensemester = $this->StudiensemesterModel->getNearest();
$aktuelle_studiensemester = $this->getDataOrTerminateWithError($aktuelle_studiensemester);
if (count($aktuelle_studiensemester) == 0) {
$this->terminateWithError("No aktuelles semester");
}
$aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz;
// push aktuelles semester in active semester array
array_push($semester_range, $aktuelle_studiensemester);
}
return $semester_range;
return $benutzer_gruppen;
}
//copied from Stundenplan.php, extended with $student_uid
private function fetchStudentlehrverbandFromStudiensemester($semester_range, $student_uid)
{
//$student_uid = getAuthUID();
$student_lehrverband = [];
// for each studiensemester fetch the studentlehrverbaende and add them to an associate $student_lehrverband array
/*
[
['WS2023'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ] ],
['SS2024'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ] ],
['WS2024'] => [ [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ] ],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$student_lehrverband[$semester_key] = [];
foreach($semester_array as $semester => $semester_date_range)
{
// for each active semester query the student_lehrverband associated to the semester
$lehrverband_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]);
$lehrverband_query_result = $this->getDataOrTerminateWithError($lehrverband_query);
array_push($student_lehrverband[$semester_key], array_map(
function ($item) {
$result = new stdClass();
$result->studiengang_kz = $item->studiengang_kz;
$result->semester = $item->semester;
$result->verband = $item->verband;
$result->gruppe = $item->gruppe;
return $result;
},
$lehrverband_query_result));
}
}
// merge the studentlehrverband of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ],
['SS2024'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ],
['WS2024'] => [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ],
]
*/
$student_lehrverband = array_map(
function ($studentlehrverband) {
$merged_studentlehrverband = [];
foreach($studentlehrverband as $studentlehrverband_array)
{
$merged_studentlehrverband = array_merge($merged_studentlehrverband, $studentlehrverband_array);
}
return $merged_studentlehrverband;
},
$student_lehrverband
);
return $student_lehrverband;
}
}
@@ -0,0 +1,559 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
use CI3_Events as Events;
class Mobility extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getMobilitaeten' => ['admin:r', 'assistenz:r'],
'loadMobility' => ['admin:r', 'assistenz:r'],
'insertMobility' => ['admin:rw', 'assistenz:rw'],
'updateMobility' => ['admin:rw', 'assistenz:rw'],
'deleteMobility' => ['admin:rw', 'assistenz:rw'],
'getProgramsMobility' => ['admin:r', 'assistenz:r'],
'getLVList' => ['admin:r', 'assistenz:r'],
'getAllLehreinheiten' => ['admin:r', 'assistenz:r'],
'getLvsandLesByStudent' => ['admin:r', 'assistenz:r'],
'getPurposes' => ['admin:r', 'assistenz:r'],
'getSupports' => ['admin:r', 'assistenz:r'],
'getListPurposes' => ['admin:r', 'assistenz:r'],
'getListSupports' => ['admin:r', 'assistenz:r'],
'deleteMobilityPurpose' => ['admin:r', 'assistenz:r'],
'addMobilityPurpose' => ['admin:r', 'assistenz:r'],
'deleteMobilitySupport' => ['admin:r', 'assistenz:r'],
'addMobilitySupport' => ['admin:r', 'assistenz:r'],
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'mobility'
]);
// Load models
$this->load->model('codex/Bisio_model', 'BisioModel');
//Permission checks for Studiengangsarray
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
if ($this->router->method == 'insertMobility' || $this->router->method == 'updateMobility')
{
$student_uid = $this->input->post('uid');
if(!$student_uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedStgsFromUid($student_uid, $allowedStgs);
}
if ($this->router->method == 'deleteMobility') {
$bisio_id = $this->input->post('bisio_id');
if(!$bisio_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Bisio ID']), self::ERROR_TYPE_GENERAL);
}
$result = $this->BisioModel->load(
array('bisio_id' => $bisio_id)
);
$data = $this->getDataOrTerminateWithError($result);
$student_uid = current($data)->student_uid;
$this->_checkAllowedStgsFromUid($student_uid, $allowedStgs);
}
}
private function _checkAllowedStgsFromUid($student_uid, $allowedStgs)
{
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]);
$data = $this->getDataOrTerminateWithError($result);
$studiengang_kz = current($data)->studiengang_kz;
if (!in_array($studiengang_kz, $allowedStgs))
{
return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL);
}
}
public function getMobilitaeten($student_uid)
{
$this->BisioModel->addSelect("*");
$this->BisioModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_bisio.mobilitaetsprogramm_code)', 'LEFT');
$this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)', 'LEFT');
$this->BisioModel->addOrder('von', 'DESC');
$this->BisioModel->addOrder('bis', 'DESC');
$this->BisioModel->addOrder('bisio_id', 'DESC');
$result = $this->BisioModel->loadWhere(
array('student_uid' => $student_uid)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getProgramsMobility()
{
$this->load->model('codex/Mobilitaetsprogramm_model', 'MobilitaetsprogrammModel');
$result = $this->MobilitaetsprogrammModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function insertMobility()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$student_uid = $this->input->post('uid');
if(!$student_uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$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;
$ects_erworben = $formData['ects_erworben'] ?? null;
$ects_angerechnet = $formData['ects_angerechnet'] ?? null;
$lehreinheit_id = $formData['lehreinheit_id'] ?? null;
$ort = $formData['ort'] ?? null;
$universitaet = $formData['universitaet'] ?? null;
$localPurposes = $formData['localPurposes'] ?? null;
$localSupports = $formData['localSupports'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('nation_code', 'Nation_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Nation_code'])
]);
$this->form_validation->set_rules('herkunftsland_code', 'Herkunftsland_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Herkunftsland_code'])
]);
$this->form_validation->set_rules('mobilitaetsprogramm_code', 'Mobilitaetsprogramm_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Mobilitaetsprogramm_code'])
]);
$this->form_validation->set_rules('von', 'VonDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
]);
$this->form_validation->set_rules('bis', 'VBisDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VBisDatum'])
]);
$this->form_validation->set_rules('ects_erworben', 'Ects_erworben', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_erworben'])
]);
$this->form_validation->set_rules('ects_angerechnet', 'Ects_angerechnet', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_angerechnet'])
]);
$this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->BisioModel->insert([
'student_uid' => $student_uid,
'von' => $von,
'bis' => $bis,
'mobilitaetsprogramm_code' => $mobilitaetsprogramm_code,
'nation_code' => $nation_code,
'herkunftsland_code' => $herkunftsland_code,
'lehreinheit_id' => $lehreinheit_id,
'ort' => $ort,
'universitaet' => $universitaet,
'ects_erworben' => $ects_erworben ,
'ects_angerechnet' => $ects_angerechnet,
'insertamum' => date('c'),
'insertvon' => $authUID,
]);
$bisio_id = $this->getDataOrTerminateWithError($result);
//check if localData (purposes)
if(count($localPurposes) > 0){
foreach ($localPurposes as $zweck){
$zweck = (int)$zweck;
$this->addMobilityPurpose($bisio_id, $zweck);
}
}
//check if localData (supports)
if(count($localSupports) > 0){
foreach ($localSupports as $support){
$this->addMobilitySupport($bisio_id, $support);
}
}
$this->terminateWithSuccess($bisio_id);
}
public function loadMobility($bisio_id)
{
$this->BisioModel->addSelect("*");
$this->BisioModel->addJoin('bis.tbl_mobilitaetsprogramm mp', 'ON (mp.mobilitaetsprogramm_code = bis.tbl_bisio.mobilitaetsprogramm_code)', 'LEFT');
$this->BisioModel->addJoin('lehre.tbl_lehreinheit le', 'ON (le.lehreinheit_id = bis.tbl_bisio.lehreinheit_id)', 'LEFT');
$result = $this->BisioModel->loadWhere(
array('bisio_id' => $bisio_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function updateMobility()
{
$this->load->library('form_validation');
$authUID = getAuthUID();
$student_uid = $this->input->post('uid');
if(!$student_uid)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$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;
$ects_erworben = $formData['ects_erworben'] ?? null;
$ects_angerechnet = $formData['ects_angerechnet'] ?? null;
$lehreinheit_id = $formData['lehreinheit_id'] ?? null;
$ort = $formData['ort'] ?? null;
$universitaet = $formData['universitaet'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('nation_code', 'Nation_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Nation_code'])
]);
$this->form_validation->set_rules('herkunftsland_code', 'Herkunftsland_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Herkunftsland_code'])
]);
$this->form_validation->set_rules('mobilitaetsprogramm_code', 'Mobilitaetsprogramm_code', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Mobilitaetsprogramm_code'])
]);
$this->form_validation->set_rules('von', 'VonDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VonDatum'])
]);
$this->form_validation->set_rules('bis', 'VBisDatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'VBisDatum'])
]);
$this->form_validation->set_rules('ects_erworben', 'Ects_erworben', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_erworben'])
]);
$this->form_validation->set_rules('ects_angerechnet', 'Ects_angerechnet', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Ects_angerechnet'])
]);
$this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->BisioModel->update(
[
'bisio_id' => $formData['bisio_id']
],
[
'student_uid' => $student_uid,
'von' => $von,
'bis' => $bis,
'mobilitaetsprogramm_code' => $mobilitaetsprogramm_code,
'nation_code' => $nation_code,
'herkunftsland_code' => $herkunftsland_code,
'lehreinheit_id' => $lehreinheit_id,
'ort' => $ort,
'universitaet' => $universitaet,
'ects_erworben' => $ects_erworben ,
'ects_angerechnet' => $ects_angerechnet,
'updateamum' => date('c'),
'updatevon' => $authUID,
]
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function deleteMobility()
{
$bisio_id = $this->input->post('bisio_id');
//check if entry in MobilityOnline extension exists
Events::trigger('mobility_delete', $bisio_id);
$result = $this->BisioModel->delete(
array('bisio_id' => $bisio_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLVList($studiengang_kz)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudiengangkz($studiengang_kz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAllLehreinheiten()
{
$lv_id = $this->input->post('lv_id');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$result = $this->LehreinheitModel->getLesFromLvIds($lv_id, $studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLvsandLesByStudent($student_uid)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudent($student_uid);
$data = $this->getDataOrTerminateWithError($result);
$lv_ids = array();
$allData = array();
foreach ($data as $lehrveranstaltung) {
$lv_ids[] = $lehrveranstaltung->lehrveranstaltung_id;
}
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
foreach ($lv_ids as $id)
{
$result = $this->LehreinheitModel->getLesFromLvIds($id);
$data = $this->getDataOrTerminateWithError($result);
if (is_array($data)) {
$allData = array_merge($allData, $data);
}
}
return $this->terminateWithSuccess($allData);
}
public function getPurposes($bisio_id)
{
$bisio_id = (int)$bisio_id;
$this->load->model('codex/Bisiozweck_model', 'BisiozweckModel');
$this->BisiozweckModel->addSelect("*");
$this->BisiozweckModel->addJoin('bis.tbl_zweck zw', 'ON (zw.zweck_code = bis.tbl_bisio_zweck.zweck_code)');
$result = $this->BisiozweckModel->loadWhere(
array('bisio_id' => $bisio_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getSupports($bisio_id)
{
$bisio_id = (int)$bisio_id;
$this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel');
$this->BisioaufenthaltfoerderungModel->addSelect("*");
$this->BisioaufenthaltfoerderungModel->addJoin('bis.tbl_aufenthaltfoerderung af', 'ON (af.aufenthaltfoerderung_code = bis.tbl_bisio_aufenthaltfoerderung.aufenthaltfoerderung_code)');
$result = $this->BisioaufenthaltfoerderungModel->loadWhere(
array('bisio_id' => $bisio_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getListPurposes()
{
$this->load->model('codex/Zweck_model', 'ZweckModel');
$result = $this->ZweckModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getListSupports()
{
$this->load->model('codex/Aufenthaltfoerderung_model', 'AufenthaltfoerderungModel');
$result = $this->AufenthaltfoerderungModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function addMobilityPurpose($bisio_id, $local_purpose = null)
{
$zweck_code = $this->input->post('zweck_code');
if($local_purpose){
$zweck_code = $local_purpose;
}
$this->load->model('codex/Bisiozweck_model', 'BisiozweckModel');
if(!$local_purpose)
{
$check = $this->BisiozweckModel->loadWhere(
[
'bisio_id' => $bisio_id,
'zweck_code' => $zweck_code,
]
);
if (hasData($check))
{
$this->terminateWithError($this->p->t('ui', 'error_entryExisting'), self::ERROR_TYPE_GENERAL);
}
}
$result = $this->BisiozweckModel->insert(
array(
'bisio_id' => $bisio_id,
'zweck_code' => $zweck_code
)
);
$data = $this->getDataOrTerminateWithError($result);
if($local_purpose)
{
return $data;
}
return $this->terminateWithSuccess(current($data));
}
public function deleteMobilityPurpose($bisio_id)
{
$zweck_code = $this->input->post('zweck_code');
$this->load->model('codex/Bisiozweck_model', 'BisiozweckModel');
$result = $this->BisiozweckModel->delete(
array(
'bisio_id' => $bisio_id,
'zweck_code' => $zweck_code
)
);
$data = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess(current($data));
}
public function addMobilitySupport($bisio_id, $local_support = null)
{
$aufenthaltfoerderung_code = $this->input->post('aufenthaltfoerderung_code');
if($local_support){
$aufenthaltfoerderung_code = $local_support;
}
$this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel');
if(!$local_support)
{
$check = $this->BisioaufenthaltfoerderungModel->loadWhere(
[
'bisio_id' => $bisio_id,
'aufenthaltfoerderung_code' => $aufenthaltfoerderung_code,
]
);
if (hasData($check))
{
$this->terminateWithError($this->p->t('ui', 'error_entryExisting'), self::ERROR_TYPE_GENERAL);
}
}
$result = $this->BisioaufenthaltfoerderungModel->insert(
array(
'bisio_id' => $bisio_id,
'aufenthaltfoerderung_code' => $aufenthaltfoerderung_code
)
);
$data = $this->getDataOrTerminateWithError($result);
if($local_support)
{
return $data;
}
return $this->terminateWithSuccess(current($data));
}
public function deleteMobilitySupport($bisio_id)
{
$aufenthaltfoerderung_code = $this->input->post('aufenthaltfoerderung_code');
$this->load->model('codex/Bisioaufenthaltfoerderung_model', 'BisioaufenthaltfoerderungModel');
$result = $this->BisioaufenthaltfoerderungModel->delete(
array(
'bisio_id' => $bisio_id,
'aufenthaltfoerderung_code' => $aufenthaltfoerderung_code
)
);
$data = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess(current($data));
}
}
@@ -16,7 +16,8 @@ class Notiz extends Notiz_Controller
'updateNotiz' => ['admin:rw', 'assistenz:rw'], // TODO(manu): self::PERM_LOGGED
'deleteNotiz' => ['admin:r', 'assistenz:r'],
'loadDokumente' => ['admin:r', 'assistenz:r'],
'getMitarbeiter' => ['admin:r', 'assistenz:r']
'getMitarbeiter' => ['admin:r', 'assistenz:r'],
'getCountNotes' => ['admin:r', 'assistenz:r'],
]);
//Load Models
@@ -19,6 +19,7 @@ class Prestudent extends FHCAPI_Controller
'getAufmerksamdurch' => ['admin:r', 'assistenz:r'],
'getBerufstaetigkeit' => ['admin:r', 'assistenz:r'],
'getTypenStg' => ['admin:r', 'assistenz:r'],
'getBisstandort' => ['admin:r', 'assistenz:r'],
'getStudienplaene' => ['admin:r', 'assistenz:r'],
'getStudiengang' => ['admin:r', 'assistenz:r']
]);
@@ -135,10 +136,32 @@ class Prestudent extends FHCAPI_Controller
$update_prestudent = array();
foreach ($array_allowed_props_prestudent as $prop)
{
$val = $this->input->post($prop);
if ($val !== null || $prop == 'foerderrelevant') {
$val = $this->input->post($prop, true);
if ($val !== null) {
if(in_array($prop, ['dual', 'bismelden', 'foerderrelevant']))
{
$val = boolval($val);
}
elseif (
$val === ''
&& in_array($prop, ['zgvnation', 'zgvmanation', 'zgvdoktornation', 'berufstaetigkeit_code', 'ausbildungcode'])
)
{
$val = null;
}
$update_prestudent[$prop] = $val;
}
// allowed to be null, but has to be in postparameter
if (
in_array($prop, ['foerderrelevant', 'zgvdatum', 'zgvmadatum', 'zgvdoktordatum', 'zgv_code', 'zgvmas_code', 'zgvdoktor_code'])
&& !isset($update_prestudent[$prop])
&& array_key_exists($prop, $_POST)
)
{
$update_prestudent[$prop] = null;
}
}
$update_prestudent['updateamum'] = date('c');
@@ -173,7 +196,11 @@ class Prestudent extends FHCAPI_Controller
{
$this->load->model('codex/Zgv_model', 'ZgvModel');
$this->ZgvModel->addOrder('zgv_code');
$this->ZgvModel->addSelect('zgv_code');
$this->ZgvModel->addSelect('zgv_bez');
$this->ZgvModel->addSelect('aktiv');
$this->ZgvModel->addSelect('zgv_bez as label');
$this->ZgvModel->addOrder('zgv_bez');
$result = $this->ZgvModel->load();
if (isError($result))
@@ -187,7 +214,11 @@ class Prestudent extends FHCAPI_Controller
{
$this->load->model('codex/Zgvdoktor_model', 'ZgvdoktorModel');
$this->ZgvdoktorModel->addOrder('zgvdoktor_code');
$this->ZgvdoktorModel->addSelect('zgvdoktor_code');
$this->ZgvdoktorModel->addSelect('zgvdoktor_bez');
$this->ZgvdoktorModel->addSelect('aktiv');
$this->ZgvdoktorModel->addSelect('zgvdoktor_bez as label');
$this->ZgvdoktorModel->addOrder('zgvdoktor_bez');
$result = $this->ZgvdoktorModel->load();
if (isError($result))
@@ -201,7 +232,11 @@ class Prestudent extends FHCAPI_Controller
{
$this->load->model('codex/Zgvmaster_model', 'ZgvmasterModel');
$this->ZgvmasterModel->addOrder('zgvmas_code');
$this->ZgvmasterModel->addSelect('zgvmas_code');
$this->ZgvmasterModel->addSelect('zgvmas_bez');
$this->ZgvmasterModel->addSelect('aktiv');
$this->ZgvmasterModel->addSelect('zgvmas_bez as label');
$this->ZgvmasterModel->addOrder('zgvmas_bez');
$result = $this->ZgvmasterModel->load();
if (isError($result))
@@ -265,6 +300,17 @@ class Prestudent extends FHCAPI_Controller
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getBisstandort()
{
$this->load->model('codex/Bisstandort_model', 'BisstandortModel');
$result = $this->BisstandortModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getStudienplaene($prestudent_id)
{
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
@@ -0,0 +1,577 @@
<?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 addresses
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Pruefung extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getPruefungen' => ['admin:r', 'assistenz:r'],
'loadPruefung' => ['admin:r', 'assistenz:r'],
'getTypenPruefungen' => ['admin:r', 'assistenz:r'],
'getLehreinheiten' => ['admin:r', 'assistenz:r'],
'getAllLehreinheiten' => ['admin:r', 'assistenz:r'],
'getLvsByStudent' => ['admin:r', 'assistenz:r'],
'getLvsandLesByStudent' => ['admin:r', 'assistenz:r'],
'getLvsAndMas' => ['admin:r', 'assistenz:r'],
'getMitarbeiterLv' => ['admin:r', 'assistenz:r'],
'getNoten' => ['admin:r', 'assistenz:r'],
'checkZeugnisnoteLv' => ['admin:r', 'assistenz:r'],
'checkTermin1' => ['admin:r', 'assistenz:r'],
'insertPruefung' => self::PERM_LOGGED,
'updatePruefung' =>self::PERM_LOGGED,
'deletePruefung' =>self::PERM_LOGGED,
]);
//Load Models
$this->load->model('education/LePruefung_model', 'PruefungModel');
//version with postParameter
if ($this->router->method == 'insertPruefung')
{
$student_uid = $this->input->post('student_uid');
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$student_uid]);
$student = $this->getDataOrTerminateWithError($result);
$prestudent_id = current($student)->prestudent_id;
$this->checkPermissionsForPrestudent($prestudent_id, ['admin:w', 'assistenz:w']);
}
// parameter from uri
if ($this->router->method == 'updatePruefung' || $this->router->method == 'deletePruefung')
{
$pruefung_id = current(array_slice($this->uri->rsegments, 2));
$result = $this->PruefungModel->load($pruefung_id);
$pruefung = $this->getDataOrTerminateWithError($result);
$student_uid = current($pruefung)->student_uid;
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$student_uid]);
$student = $this->getDataOrTerminateWithError($result);
$prestudent_id = current($student)->prestudent_id;
$this->checkPermissionsForPrestudent($prestudent_id, ['admin:rw', 'assistenz:rw']);
}
if ($this->router->method == 'loadPruefung')
{
$pruefung_id = current(array_slice($this->uri->rsegments, 2));
$result = $this->PruefungModel->load($pruefung_id);
$pruefung = $this->getDataOrTerminateWithError($result);
$student_uid = current($pruefung)->student_uid;
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$student_uid]);
$student = $this->getDataOrTerminateWithError($result);
$prestudent_id = current($student)->prestudent_id;
$this->checkPermissionsForPrestudent($prestudent_id, ['admin:r', 'assistenz:r']);
}
if ($this->router->method == 'getPruefungen')
{
$student_uid = current(array_slice($this->uri->rsegments, 2));
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$student_uid]);
$student = $this->getDataOrTerminateWithError($result);
$prestudent_id = current($student)->prestudent_id;
$this->checkPermissionsForPrestudent($prestudent_id, ['admin:r', 'assistenz:r']);
}
// Load language phrases
$this->loadPhrases([
'global', 'ui','lehre'
]);
}
public function getPruefungen($student_uid, $studiensemester_kurzbz = null)
{
$result = $this->PruefungModel->getPruefungenByStudentuid($student_uid);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function loadPruefung($pruefung_id)
{
$this->PruefungModel->addSelect('tbl_pruefung.datum');
$this->PruefungModel->addSelect("TO_CHAR(tbl_pruefung.datum::timestamp, 'DD.MM.YYYY') AS format_datum");
$this->PruefungModel->addSelect('tbl_pruefung.anmerkung');
$this->PruefungModel->addSelect('tbl_pruefung.pruefungstyp_kurzbz');
$this->PruefungModel->addSelect('tbl_pruefung.pruefung_id');
$this->PruefungModel->addSelect('tbl_pruefung.lehreinheit_id');
$this->PruefungModel->addSelect('tbl_pruefung.student_uid');
$this->PruefungModel->addSelect('tbl_pruefung.mitarbeiter_uid');
$this->PruefungModel->addSelect('tbl_pruefung.punkte');
$this->PruefungModel->addSelect('tbl_pruefung.note');
$this->PruefungModel->addSelect('tbl_lehrveranstaltung.bezeichnung as lehrveranstaltung_bezeichnung');
$this->PruefungModel->addSelect('tbl_lehrveranstaltung.lehrveranstaltung_id');
$this->PruefungModel->addSelect('tbl_lehrveranstaltung.semester');
$this->PruefungModel->addSelect('tbl_lehrveranstaltung.lehrform_kurzbz');
$this->PruefungModel->addSelect('tbl_note.bezeichnung as note_bezeichnung');
$this->PruefungModel->addSelect('tbl_pruefungstyp.beschreibung as typ_beschreibung');
$this->PruefungModel->addSelect('tbl_lehreinheit.studiensemester_kurzbz as studiensemester_kurzbz');
$this->PruefungModel->addJoin('lehre.tbl_lehreinheit', 'lehre.tbl_pruefung.lehreinheit_id = lehre.tbl_lehreinheit.lehreinheit_id');
$this->PruefungModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id');
$this->PruefungModel->addJoin('lehre.tbl_note', 'note');
$this->PruefungModel->addJoin('lehre.tbl_pruefungstyp', 'pruefungstyp_kurzbz');
$this->PruefungModel->addLimit(1);
$result = $this->PruefungModel->loadWhere(
array('pruefung_id' => $pruefung_id)
);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Pruefung_id']), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(current(getData($result)) ? : null);
}
/**
* Inserts a pruefung
*
* @param lehrveranstaltung_id, student_uid, lehreinheit_id
*
* @return values on success
* retval 0: pruefung inserted
* reval 1: pruefung and zeugnisnote inserted
* retval 2: pruefung inserted, no insert Zeugnisnote
* (change after date of examination)
* retval 3: pruefung of type Termin2 inserted
* and pruefung of type Termin1 as well
* retval 5: prueufungen Termin 2 and 1 inserted
* and no insert Zeugnisnote (change after date of examination)
*/
public function insertPruefung()
{
$authUID = getAuthUID();
$this->load->library('form_validation');
$this->form_validation->set_rules('lehrveranstaltung_id', $this->p->t('lehre', 'lehrveranstaltung'), 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'lehrveranstaltung')]),
]);
$this->form_validation->set_rules('lehreinheit_id', $this->p->t('lehre', 'lehreinheit'), 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'lehreinheit')]),
]);
$this->form_validation->set_rules('pruefungstyp_kurzbz', $this->p->t('lehre', 'pruefung'), 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('global', 'typ')]),
]);
$this->form_validation->set_rules(
'datum',
$this->p->t('global', 'datum'),
['is_valid_date']
);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
//calculate studiensemester_kurzbz this from lehreinheit (case newPruefung)
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
if (!$studiensemester_kurzbz)
{
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$result = $this->LehreinheitModel->load($this->input->post('lehreinheit_id'));
$lehreinheit = $this->getDataOrTerminateWithError($result);
$studiensemester_kurzbz = current($lehreinheit)->studiensemester_kurzbz;
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
}
$result = $this->PruefungModel->insert([
'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'),
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'note' => $this->input->post('note'),
'anmerkung' => $this->input->post('anmerkung'),
'insertamum' => date('c'),
'insertvon' => $authUID,
]);
$this->getDataOrTerminateWithError($result);
//check if existing zeugnisnote
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$result = $this->ZeugnisnoteModel->loadWhere(array(
'lehrveranstaltung_id' => $this->input->post('lehrveranstaltung_id'),
'student_uid' => $this->input->post('student_uid'),
'studiensemester_kurzbz' => $studiensemester_kurzbz));
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
//insert zeugnisnote, if not existing
$result = $this->ZeugnisnoteModel->insert(array(
'lehrveranstaltung_id' => $this->input->post('lehrveranstaltung_id'),
'student_uid' => $this->input->post('student_uid'),
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'note' => $this->input->post('note'),
'uebernahmedatum' => date('c'),
'benotungsdatum' => $this->input->post('datum'),
'insertamum' => date('c'),
'insertvon' => $authUID
));
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(1);
}
$return_code = 0;
//handling Termin1 if not existing
if($this->input->post('pruefungstyp_kurzbz') == "Termin2")
{
$resultP = $this->PruefungModel->loadWhere(array(
'lehreinheit_id' => $this->input->post('lehreinheit_id'),
'student_uid' => $this->input->post('student_uid'),
'pruefungstyp_kurzbz' => 'Termin1'));
if (isError($resultP))
{
$this->terminateWithError(getError($resultP), self::ERROR_TYPE_GENERAL);
}
if(!hasData($resultP))
{
//check if existing Zeugnisnote
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$this->ZeugnisnoteModel->addJoin('lehre.tbl_lehreinheit', 'lehrveranstaltung_id');
$resultP = $this->ZeugnisnoteModel->loadWhere(array(
'lehrveranstaltung_id' => $this->input->post('lehrveranstaltung_id'),
'student_uid' => $this->input->input->post('student_uid'),
'lehre.tbl_zeugnisnote.studiensemester_kurzbz' => $studiensemester_kurzbz));
if (isError($resultP))
{
$this->terminateWithError(getError($resultP), self::ERROR_TYPE_GENERAL);
}
if (!hasData($resultP))
{
$this->terminateWithError("Zeugnisnote existiert nicht", self::ERROR_TYPE_GENERAL);
}
$dataNote = current(getData($resultP));
$resultN = $this->PruefungModel->insert([
'lehreinheit_id' => $this->input->post('lehreinheit_id'),
'student_uid' => $this->input->post('student_uid'),
'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'),
'datum' => $dataNote->benotungsdatum,
'pruefungstyp_kurzbz' => 'Termin1',
'note' => $dataNote->note,
'punkte' => $dataNote->punkte,
'anmerkung' => 'automatisiert aus Zeugnisnote erstellt',
'insertamum' => date('c'),
'insertvon' => $authUID,
]);
if (isError($resultN)) {
$this->terminateWithError(getError($resultN), self::ERROR_TYPE_GENERAL);
}
$return_code = 3;
}
}
$note = current(getData($result));
$uebernahmedatum = new DateTime($note->uebernahmedatum);
$benotungsdatum = new DateTime($note->benotungsdatum);
$checkDate = $uebernahmedatum === '' || $benotungsdatum > $uebernahmedatum
? $benotungsdatum
: $uebernahmedatum;
if ($checkDate >= $this->input->post('datum') && $note !== $note->note)
{
$this->terminateWithSuccess($return_code + 2);
}
$this->terminateWithSuccess($return_code + 2);
}
/**
* Updates a pruefung
*
* @param pruefung_id
*
* @return success or error
*
* no impact on lehre.tbl_zeugnisnote
*/
public function updatePruefung($pruefung_id)
{
$result = $this->PruefungModel->load($pruefung_id);
$oldpruefung = $this->getDataOrTerminateWithError($result);
if (!$oldpruefung)
show_404(); // Pruefung that should be updated does not exist
$authUID = getAuthUID();
$this->load->library('form_validation');
$this->form_validation->set_rules('lehrveranstaltung_id', $this->p->t('lehre', 'lehrveranstaltung'), 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'lehrveranstaltung')]),
]);
$this->form_validation->set_rules('lehreinheit_id', $this->p->t('lehre', 'lehreinheit'), 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'lehreinheit')]),
]);
$this->form_validation->set_rules('pruefungstyp_kurzbz', $this->p->t('lehre', 'pruefung'), 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('global', 'typ')]),
]);
$this->form_validation->set_rules(
'datum',
$this->p->t('global', 'datum'),
['is_valid_date']
);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->PruefungModel->update(
[
'pruefung_id' => $pruefung_id
],
[ 'lehreinheit_id' => $this->input->post('lehreinheit_id'),
'student_uid' => $this->input->post('student_uid'),
'mitarbeiter_uid' => $this->input->post('mitarbeiter_uid'),
'note' => $this->input->post('note'),
'pruefungstyp_kurzbz' => $this->input->post('pruefungstyp_kurzbz'),
'datum' => $this->input->post('datum'),
'anmerkung' => $this->input->post('anmerkung'),
'updatevon' => $authUID,
'updateamum' => date('c'),
]
);
$this->getDataOrTerminateWithError($result);
return $this->outputJsonSuccess(true);
}
/**
* Deletes a pruefung
*
* @param pruefung_id
*
* @return success or error
*
* no impact on lehre.tbl_zeugnisnote
*/
public function deletePruefung($pruefung_id)
{
$result = $this->PruefungModel->load($pruefung_id);
$oldpruefung = $this->getDataOrTerminateWithError($result);
if (!$oldpruefung)
show_404(); // Pruefung that should be deleted does not exist
$result = $this->PruefungModel->delete(
[
'pruefung_id' => $pruefung_id
]
);
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess(true);
}
public function getTypenPruefungen()
{
$this->load->model('education/Pruefungstyp_model', 'PruefungtypModel');
//TODO(Manu) sort Termin3
$this->PruefungtypModel->addOrder('sort', 'ASC');
$result = $this->PruefungtypModel->loadWhere(
array('abschluss' => 'false')
);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getAllLehreinheiten()
{
$lv_id = $this->input->post('lv_id');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$result = $this->LehreinheitModel->getLesFromLvIds($lv_id, $studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getLvsandLesByStudent($student_uid, $semester_kurzbz=null)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudent($student_uid, $semester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$lv_ids = array();
$allData = array();
foreach ($data as $lehrveranstaltung) {
$lv_ids[] = $lehrveranstaltung->lehrveranstaltung_id;
}
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
foreach ($lv_ids as $id)
{
$result = $this->LehreinheitModel->getLesFromLvIds($id, $semester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
if (is_array($data)) {
$allData = array_merge($allData, $data);
}
}
return $this->terminateWithSuccess($allData);
}
public function getLvsAndMas($student_uid)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudent($student_uid);
$data = $this->getDataOrTerminateWithError($result);
$lv_ids = array();
$allDataMa = array();
foreach ($data as $lehrveranstaltung)
{
$lv_ids[] = $lehrveranstaltung->lehrveranstaltung_id;
}
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
foreach ($lv_ids as $id)
{
$resultMa = $this->MitarbeiterModel->getMitarbeiterFromLV($id);
$dataMa = $this->getDataOrTerminateWithError($resultMa);
if (is_array($dataMa))
{
$allDataMa = array_merge($allDataMa, $dataMa);
}
}
return $this->terminateWithSuccess($allDataMa);
}
public function getLvsByStudent($student_uid, $studiensemester_kurzbz = null)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudent($student_uid, $studiensemester_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($data);
}
public function getMitarbeiterLv($lv_id)
{
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->MitarbeiterModel->getMitarbeiterFromLV($lv_id);
$data = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($data);
}
public function getNoten()
{
$this->load->model('education/Note_model', 'NoteModel');
$this->NoteModel->addOrder('note', 'ASC');
$result = $this->NoteModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function checkZeugnisnoteLv()
{
$student_uid = $this->input->post('student_uid');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$result = $this->ZeugnisnoteModel->loadWhere(array(
'lehrveranstaltung_id' => $lehrveranstaltung_id,
'student_uid' => $student_uid,
'studiensemester_kurzbz' => $studiensemester_kurzbz));
$data = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($data);
}
}
@@ -24,12 +24,12 @@ class Status extends FHCAPI_Controller
'updateStatus' => ['admin:rw', 'assistenz:rw'],
'advanceStatus' => ['admin:rw', 'assistenz:rw'],
'confirmStatus' => ['admin:rw', 'assistenz:rw'],
]);
//Load Models
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
@@ -189,9 +189,13 @@ class Status extends FHCAPI_Controller
$studiensemester_kurzbz = $lastStatusData->studiensemester_kurzbz;
if ($status_kurzbz == Prestudentstatus_model::STATUS_ABSOLVENT
|| $status_kurzbz == Prestudentstatus_model::STATUS_DIPLOMAND
) {
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
)
{
$studiensemester_kurzbz = $this->input->post('currentSemester');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
}
$ausbildungssemester = $lastStatusData->ausbildungssemester;
@@ -282,11 +286,11 @@ class Status extends FHCAPI_Controller
]);
$this->form_validation->set_rules('_default', '', [
['meldestichtag_not_exceeded', function () use ($datum, $isBerechtigtNoStudstatusCheck) {
['meldestichtag_not_exceeded', function () use ($datum_string, $isBerechtigtNoStudstatusCheck) {
if ($isBerechtigtNoStudstatusCheck)
return true; // Skip if access right says so
$result = $this->prestudentstatuschecklib->checkIfMeldestichtagErreicht($datum);
$result = $this->prestudentstatuschecklib->checkIfMeldestichtagErreicht($datum_string);
return !$this->getDataOrTerminateWithError($result);
}],
@@ -435,9 +439,10 @@ class Status extends FHCAPI_Controller
]);
if (!$this->form_validation->run())
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->load->library('PrestudentLib');
$this->db->trans_start();
@@ -623,8 +628,9 @@ class Status extends FHCAPI_Controller
]);
if (!$this->form_validation->run())
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
// Start DB transaction
$this->db->trans_start();
@@ -647,15 +653,8 @@ class Status extends FHCAPI_Controller
return $this->outputJsonSuccess(true);
}
public function loadStatus()
public function loadStatus($prestudent_id, $status_kurzbz, $studiensemester_kurzbz, $ausbildungssemester)
{
$_POST = json_decode(utf8_encode($this->input->raw_input_stream), true);
$prestudent_id = $this->input->post('prestudent_id');
$status_kurzbz = $this->input->post('status_kurzbz');
$ausbildungssemester = $this->input->post('ausbildungssemester');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$result = $this->PrestudentstatusModel->loadWhere(
array(
'prestudent_id' => $prestudent_id,
@@ -734,8 +733,9 @@ class Status extends FHCAPI_Controller
);
$result = $this->prestudentstatuschecklib->checkIfMeldestichtagErreicht($oldstatus->datum);
$isMeldestichtagErreicht = $this->getDataOrTerminateWithError($result);
if (!$this->getDataOrTerminateWithError($result))
if ($isMeldestichtagErreicht)
$this->terminateWithError(
$this->p->t('lehre', 'error_dataVorMeldestichtag'),
self::ERROR_TYPE_GENERAL,
@@ -746,8 +746,12 @@ class Status extends FHCAPI_Controller
// Start DB transaction
$this->db->trans_begin();
//Delete Studentlehrverband if no Status left in this semester
$cilsresult = $this->PrestudentstatusModel->checkIfLastStatusEntry($prestudent_id, $studiensemester_kurzbz);
$isLastPrestudentStatusForSemester = $this->getDataOrTerminateWithError($cilsresult);
//Delete Status
$result = $this->PrestudentstatusModel->delete(
$delpsresult = $this->PrestudentstatusModel->delete(
[
'prestudent_id' => $prestudent_id,
'status_kurzbz' => $status_kurzbz,
@@ -755,14 +759,9 @@ class Status extends FHCAPI_Controller
'studiensemester_kurzbz' => $studiensemester_kurzbz
]
);
$this->getDataOrTerminateWithError($delpsresult);
$this->getDataOrTerminateWithError($result);
//Delete Studentlehrverband if no Status left in this semester
$result = $this->PrestudentstatusModel->checkIfLastStatusEntry($prestudent_id, $studiensemester_kurzbz);
$result = $this->getDataOrTerminateWithError($result);
if ($result)
if ($isLastPrestudentStatusForSemester)
{
//get student_uid
$this->load->model('crm/Student_model', 'StudentModel');
@@ -1344,13 +1343,13 @@ class Status extends FHCAPI_Controller
'updatevon' => $authUID
];
foreach ([
'orgform_kurzbz',
'anmerkung',
'bewerbung_abgeschicktamum',
'studienplan_id',
'rt_stufe',
'statusgrund_id'
] as $key)
'orgform_kurzbz',
'anmerkung',
'bewerbung_abgeschicktamum',
'studienplan_id',
'rt_stufe',
'statusgrund_id'
] as $key)
if ($this->input->post($key))
$updateData[$key] = $this->input->post($key);
@@ -1536,9 +1535,32 @@ class Status extends FHCAPI_Controller
$newStudentlvb['semester'] = $ausbildungssemester;
} // If there is no lehrverband just use the same as in the previous studiensemester
//add studentlehrverband
$result = $this->StudentlehrverbandModel->insert($newStudentlvb);
$checkres = $this->StudentlehrverbandModel->load(array(
'student_uid' => $studentlvb->student_uid,
'studiensemester_kurzbz' => $studiensemester_kurzbz
));
if(hasData($checkres))
{
$result = $this->StudentlehrverbandModel->update(
array(
'student_uid' => $studentlvb->student_uid,
'studiensemester_kurzbz' => $studiensemester_kurzbz
),
array(
'studiengang_kz' => $studentlvb->studiengang_kz,
'semester' => $studentlvb->semester,
'verband' => $studentlvb->verband,
'gruppe' => $studentlvb->gruppe,
'updateamum' => $now,
'updatevon' => $authUID
)
);
}
else
{
//add studentlehrverband
$result = $this->StudentlehrverbandModel->insert($newStudentlvb);
}
$this->getDataOrTerminateWithError($result);
@@ -55,7 +55,7 @@ class Student extends FHCAPI_Controller
// Load language phrases
$this->loadPhrases([
'ui'
'ui', 'lehre'
]);
}
@@ -68,13 +68,28 @@ class Student extends FHCAPI_Controller
* @param string $prestudent_id
* @return void
*/
public function get($prestudent_id)
public function get($prestudent_id, $studiensemester_kurzbz)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$this->PrestudentModel->addSelect('p.*');
$this->PrestudentModel->addSelect('p.person_id');
$this->PrestudentModel->addSelect('p.titelpre');
$this->PrestudentModel->addSelect('p.nachname');
$this->PrestudentModel->addSelect('p.vorname');
$this->PrestudentModel->addSelect('p.wahlname');
$this->PrestudentModel->addSelect('p.vornamen');
$this->PrestudentModel->addSelect('p.titelpost');
$this->PrestudentModel->addSelect('p.svnr');
$this->PrestudentModel->addSelect('p.ersatzkennzeichen');
$this->PrestudentModel->addSelect('p.gebdatum');
$this->PrestudentModel->addSelect('p.geschlecht');
$this->PrestudentModel->addSelect('p.foto');
$this->PrestudentModel->addSelect('p.foto_sperre');
$this->PrestudentModel->addSelect('s.student_uid');
$this->PrestudentModel->addSelect('matrikelnr');
$this->PrestudentModel->addSelect('b.aktiv');
@@ -82,6 +97,16 @@ class Student extends FHCAPI_Controller
$this->PrestudentModel->addSelect('v.verband');
$this->PrestudentModel->addSelect('v.gruppe');
$this->PrestudentModel->addSelect('b.alias');
$this->PrestudentModel->addSelect('p.geburtsnation');
$this->PrestudentModel->addSelect('p.sprache');
$this->PrestudentModel->addSelect('p.gebort');
$this->PrestudentModel->addSelect('p.homepage');
$this->PrestudentModel->addSelect('p.anmerkung');
$this->PrestudentModel->addSelect('p.familienstand');
$this->PrestudentModel->addSelect('p.staatsbuergerschaft');
$this->PrestudentModel->addSelect('p.matr_nr');
$this->PrestudentModel->addSelect('p.anrede');
$this->PrestudentModel->addSelect('p.zugangscode');
if (defined('ACTIVE_ADDONS') && strpos(ACTIVE_ADDONS, 'bewerbung') !== false) {
$this->PrestudentModel->addSelect(
@@ -97,6 +122,16 @@ class Student extends FHCAPI_Controller
false
);
}
$this->PrestudentModel->addSelect(
"(
SELECT status_kurzbz
FROM public.tbl_prestudentstatus pss
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
LIMIT 1
) AS statusofsemester"
);
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 'student_uid = uid', 'LEFT');
@@ -106,43 +141,76 @@ class Student extends FHCAPI_Controller
'LEFT'
);
$this->PrestudentModel->addJoin('public.tbl_person p', 'p.person_id = tbl_prestudent.person_id');
/* $this->PrestudentModel->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id = tbl_prestudent.prestudent_id
AND pss.studiensemester_kurzbz = ' . $this->PrestudentModel->escape($studiensemester_kurzbz),
'LEFT');*/
$result = $this->PrestudentModel->loadWhere(['prestudent_id' => $prestudent_id]);
$result = $this->PrestudentModel->loadWhere(['tbl_prestudent.prestudent_id' => $prestudent_id]);
$student = $this->getDataOrTerminateWithError($result);
if (!$student)
return show_404();
$this->terminateWithSuccess(current($student));
}
protected function isLaufendesSemester($selectedSemester)
{
$laufendesStudiensemester = '';
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudiensemesterModel->getAktOrNextSemester();
if(hasData($result)) {
$laufendesStudiensemester = (getData($result))[0]->studiensemester_kurzbz;
}
$islaufendesSemester = $selectedSemester === $laufendesStudiensemester;
return $islaufendesSemester;
}
/**
* Saves data to a prestudent
*
* @param string $prestudent_id
* @return void
*/
public function save($prestudent_id)
public function save($prestudent_id, $studiensemester_kurzbz)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->library('form_validation');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$authuid = getAuthUID();
$now = date('c');
$this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'is_valid_date');
$this->form_validation->set_rules('semester', 'Semester', 'integer');
$this->form_validation->set_rules('semester', 'Semester', 'integer', [
'integer' => $this->p->t('ui', 'error_fieldNotInteger')
]
);
$this->form_validation->set_rules('alias', 'Alias', 'regex_match[/^[-a-z0-9\_\.]*[a-z0-9]{1,}\.[-a-z0-9\_]{1,}$/]',
[
'regex_match' => $this->p->t('ui', 'error_fieldInvalidAlias')
]);
$this->load->library('UDFLib');
$result = $this->udflib->getCiValidations($this->PersonModel, $this->input->post());
//TODO(Manu) check with Chris: input number not allowed
$udf_field_validations = $this->getDataOrTerminateWithError($result);
$this->form_validation->set_rules($udf_field_validations);
@@ -156,6 +224,8 @@ class Student extends FHCAPI_Controller
$uid = $student ? current($student)->student_uid : null;
$studiengang_kz = $student ? current($student)->studiengang_kz : null;
$result = $this->PrestudentModel->loadWhere(['prestudent_id' => $prestudent_id]);
$person = $this->getDataOrTerminateWithError($result);
@@ -184,7 +254,6 @@ class Student extends FHCAPI_Controller
'gebdatum',
'gebort',
'geburtsnation',
'svnr',
'ersatzkennzeichen',
'staatsbuergerschaft',
'matr_nr',
@@ -195,7 +264,7 @@ class Student extends FHCAPI_Controller
'anmerkung',
'homepage'
];
// add UDFs
$result = $this->udflib->getDefinitionForModel($this->PersonModel);
@@ -207,12 +276,26 @@ class Student extends FHCAPI_Controller
$update_person = array();
foreach ($array_allowed_props_person as $prop) {
$val = $this->input->post($prop);
if ($val !== null) {
if ($val === null)
{
continue;
}
if($prop == 'foto')
{
$fotoval = ($val == '') ? null : str_replace('data:image/jpeg;base64,', '', $val);
$update_person[$prop] = $fotoval;
}
else
{
$update_person[$prop] = $val;
}
}
$array_allowed_props_student = ['matrikelnr'];
if($this->isLaufendesSemester($studiensemester_kurzbz))
{
$array_allowed_props_student = ['matrikelnr', 'verband', 'semester', 'gruppe'];
}
$update_student = array();
foreach ($array_allowed_props_student as $prop) {
$val = $this->input->post($prop);
@@ -221,26 +304,85 @@ class Student extends FHCAPI_Controller
}
}
$array_allowed_props_benutzer = ['aktiv', 'alias'];
$update_benutzer = array();
foreach ($array_allowed_props_benutzer as $prop) {
$val = $this->input->post($prop);
if ($val !== null) {
$update_benutzer[$prop] = $val;
}
}
// Check PKs
if (count($update_lehrverband) + count($update_student) && $uid === null) {
// TODO(chris): phrase
$this->terminateWithValidationErrors(['' => "Kein/e StudentIn vorhanden!"]);
$this->terminateWithValidationErrors(['' => $this->p->t('lehre', 'error_no_student')]);
}
if (count($update_person) && $person_id === null) {
// TODO(chris): phrase
$this->terminateWithValidationErrors(['' => "Keine Person vorhanden!"]);
$this->terminateWithValidationErrors(['' => $this->p->t('lehre', 'error_no_person')]);
}
if (count($update_benutzer) && $uid === null) {
$this->terminateWithValidationErrors(['' => $this->p->t('lehre', 'error_no_student')]);
}
// Do Updates
if (count($update_lehrverband)) {
$result = $this->StudentlehrverbandModel->update([
$curstudlvb = $this->StudentlehrverbandModel->load([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $uid
], $update_lehrverband);
]);
$data = $this->getDataOrTerminateWithError($curstudlvb);
$data = current($data);
$verbandCurrent = $data->verband;
$studiengang_kz = $data->studiengang_kz;
$semesterCurrent = $data->semester;
$gruppeCurrent = $data->gruppe;
$verband = isset($update_lehrverband['verband']) ? $update_lehrverband['verband'] : $verbandCurrent;
$gruppe = isset($update_lehrverband['gruppe']) ? $update_lehrverband['gruppe'] : $gruppeCurrent;
$semester = isset($update_lehrverband['semester']) ? $update_lehrverband['semester'] : $semesterCurrent;
//check if existing Lehrverband of new data to avoid Error
$result = $this->LehrverbandModel->loadWhere([
'verband' => $verband,
'gruppe' => $gruppe,
'semester' => $semester,
'studiengang_kz' => $studiengang_kz,
]);
if(!hasData($result))
{
$this->terminateWithError($this->p->t('lehre', 'error_noLehrverband'), self::ERROR_TYPE_GENERAL);
}
if(hasData($curstudlvb) && count(getData($curstudlvb)) > 0 )
{
$update_lehrverband['updatevon'] = $authuid;
$update_lehrverband['updateamum'] = $now;
$result = $this->StudentlehrverbandModel->update([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $uid
], $update_lehrverband);
}
else
{
$update_lehrverband['insertvon'] = $authuid;
$update_lehrverband['insertamum'] = $now;
$result = $this->StudentlehrverbandModel->insert(array_merge([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $uid,
'studiengang_kz' => $studiengang_kz
], $update_lehrverband));
}
$this->getDataOrTerminateWithError($result);
}
if (count($update_person)) {
$update_person['updatevon'] = $authuid;
$update_person['updateamum'] = $now;
$result = $this->PersonModel->update(
$person_id,
$update_person
@@ -250,6 +392,8 @@ class Student extends FHCAPI_Controller
if (count($update_student)) {
$update_student['updatevon'] = $authuid;
$update_student['updateamum'] = $now;
$result = $this->StudentModel->update(
[$uid],
$update_student
@@ -257,10 +401,26 @@ class Student extends FHCAPI_Controller
$this->getDataOrTerminateWithError($result);
}
if (count($update_benutzer)) {
$update_benutzer['updatevon'] = $authuid;
$update_benutzer['updateamum'] = $now;
if (array_key_exists("aktiv", $update_benutzer))
{
$update_benutzer['updateaktivvon'] = $authuid;
$update_benutzer['updateaktivam'] = $now;
}
$result = $this->BenutzerModel->update(
[$uid],
$update_benutzer
);
$this->getDataOrTerminateWithError($result);
}
$this->terminateWithSuccess(array_fill_keys(array_merge(
array_keys($update_lehrverband),
array_keys($update_person),
array_keys($update_student)
array_keys($update_student),
array_keys($update_benutzer)
), ''));
}
@@ -543,7 +703,7 @@ class Student extends FHCAPI_Controller
return $result;
}*/
$this->terminateWithSuccess(true);
return success(true);
}
public function requiredIfNotPersonId($value)
@@ -559,4 +719,9 @@ class Student extends FHCAPI_Controller
return true;
return !!$value;
}
public function isValidDate($value)
{
return isValidDate($value);
}
}
@@ -45,142 +45,118 @@ class Students extends FHCAPI_Controller
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('PhrasesLib');
$this->loadPhrases(
array(
'lehre'
)
);
}
/**
* Remap calls:
* / => return []
* /inout => return []
* /inout/incoming => getIncoming
* /inout/outgoing => getOutgoing
* /inout/gemeinsamestudien => getGemeinsamestudien
* /(studiengang_kz) => getStudents
* /(studiengang_kz)/prestudent => getPrestudents
* /(studiengang_kz)/prestudent/* => getPrestudents
* /(studiengang_kz)/(semester) => getStudents
* /(studiengang_kz)/(semester)/grp/(gruppe_kurzbz) => getStudents
* /(studiengang_kz)/(semester)/(verband) => getStudents
* /(studiengang_kz)/(semester)/(verband)/(gruppe) => getStudents
* /(studiengang_kz)/(org_form) => getStudents
* /(studiengang_kz)/(org_form)/prestudent => getPrestudents
* /(studiengang_kz)/(org_form)/prestudent/* => getPrestudents
* /(studiengang_kz)/(org_form)/(semester) => getStudents
* /(studiengang_kz)/(org_form)/(semester)/grp/(gruppe_kurzbz)
* => getStudents
* /(studiengang_kz)/(org_form)/(semester)/(verband) => getStudents
* /(studiengang_kz)/(org_form)/(semester)/(verband)/(gruppe)
* => getStudents
* /uid/(student_uid) => getStudent
* /prestudent/(prestudent_id) => getPrestudent
* /person/(person_id) => getPerson
* Routing
*
* @param string $method
* @param array $params (optional)
* /inout => index
* /(studiensemester_kurzbz) => index
* /(studiensemester_kurzbz)/inout => index
*
* /(studiensemester_kurzbz)/inout/incoming => getIncoming
* /(studiensemester_kurzbz)/inout/outgoing => getOutgoing
* /(studiensemester_kurzbz)/inout/gemeinsamestudien => getGemeinsamestudien
*
* /(studiengang_kz)/prestudent => getPrestudents
* /(studiengang_kz)/prestudent/(studiensemester_kurzbz) => getPrestudents
* /(studiengang_kz)/prestudent/(studiensemester_kurzbz)/(filter) => getPrestudents
* /(studiengang_kz)/prestudent/(studiensemester_kurzbz)/(filter)/(otherfilter) => getPrestudents
*
* /(studiengang_kz)/(orgform)/prestudent => getPrestudentsOrgform
* /(studiengang_kz)/(orgform)/prestudent/(studiensemester_kurzbz) => getPrestudentsOrgform
* /(studiengang_kz)/(orgform)/prestudent/(studiensemester_kurzbz)/(filter) => getPrestudentsOrgform
* /(studiengang_kz)/(orgform)/prestudent/(studiensemester_kurzbz)/(filter)/(otherfilter) => getPrestudentsOrgform
*
* /(studiensemester_kurzbz)/(studiengang_kz)/(semester)/grp/(gruppe) => getStudentsSpezialguppe
*
* /(studiensemester_kurzbz)/(studiengang_kz) => getStudents
* /(studiensemester_kurzbz)/(studiengang_kz)/(semester) => getStudents
* /(studiensemester_kurzbz)/(studiengang_kz)/(semester)/(verband) => getStudents
* /(studiensemester_kurzbz)/(studiengang_kz)/(semester)/(verband)/(gruppe) => getStudents
*
* /(studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester)/grp/(gruppe) => getStudentsOrgformSpezialgruppe
*
* /(studiensemester_kurzbz)/(studiengang_kz)/(orgform) => getStudentsOrgform
* /(studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester) => getStudentsOrgform
* /(studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester)/(verband) => getStudentsOrgform
* /(studiensemester_kurzbz)/(studiengang_kz)/(orgform)/(semester)/(verband)/(gruppe) => getStudentsOrgform
*
* /(studiensemester_kurzbz)/uid/(student_uid) => getStudent
* /(studiensemester_kurzbz)/prestudent/(prestudent_id) => getPrestudent
* /(studiensemester_kurzbz)/person/(person_id) => getPerson
*/
public function index()
{
$this->addMeta('ci_method', __FUNCTION__);
$this->terminateWithSuccess([]);
}
/**
* @return void
*/
public function _remap($method, $params = [])
public function getIncoming()
{
if ($method == '' || $method == 'index')
return $this->terminateWithSuccess([]);
$this->addMeta('ci_method', __FUNCTION__);
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
}
if ($method == 'inout') {
if (!count($params))
return $this->terminateWithSuccess([]);
switch ($params[0]) {
case 'incoming':
return $this->getIncoming();
case 'outgoing':
return $this->getOutgoing();
case 'gemeinsamestudien':
return $this->getGemeinsamestudien();
default:
return show_404();
}
}
/**
* @return void
*/
public function getOutgoing()
{
$this->addMeta('ci_method', __FUNCTION__);
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
}
$count = count($params);
if (!$count)
return $this->getStudents($method);
/**
* @return void
*/
public function getGemeinsamestudien()
{
$this->addMeta('ci_method', __FUNCTION__);
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
}
if ($method == 'uid' && $count == 1)
return $this->getStudent($params[0]);
if ($method == 'prestudent' && $count == 1)
return $this->getPrestudent($params[0]);
if ($method == 'person' && $count == 1)
return $this->getPerson($params[0]);
if (is_numeric($params[0])) {
$sem = $params[0];
if ($count == 3 && $params[1] == 'grp') {
$g = $params[2];
$ver = null;
$grp = null;
} else {
$g = null;
$ver = $count > 1 ? $params[1] : null;
$grp = $count > 2 ? $params[2] : null;
}
return $this->getStudents($method, $sem, $ver, $grp, $g);
} elseif ($params[0] == 'prestudent') {
if ($count == 1)
return $this->getPrestudents($method);
if ($count == 2)
return $this->getPrestudents($method, $params[1]);
return $this->getPrestudents($method, $params[1], $params[$count-1]);
} else {
$org = $params[0];
if ($count > 1 && $params[1] == 'prestudent') {
if ($count == 2)
return $this->getPrestudents($method, null, null, $org);
if ($count == 3)
return $this->getPrestudents($method, $params[2], null, $org);
return $this->getPrestudents($method, $params[2], $params[$count-1], $org);
}
$sem = $count > 1 ? $params[1] : null;
if ($count == 4 && $params[2] == 'grp') {
$g = $params[3];
$ver = null;
$grp = null;
} else {
$g = null;
$ver = $count > 2 ? $params[2] : null;
$grp = $count > 3 ? $params[3] : null;
}
return $this->getStudents($method, $sem, $ver, $grp, $g, $org);
}
public function getPrestudents($studiengang_kz,
$studiensemester_kurzbz = null, $filter = null
)
{
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiengang_kz' => $studiengang_kz,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'filter' => $filter
));
show_404();
$this->fetchPrestudents($studiengang_kz, $studiensemester_kurzbz, $filter);
}
/**
* @return void
*/
protected function getIncoming()
public function getPrestudentsOrgform($studiengang_kz, $orgform_kurzbz,
$studiensemester_kurzbz = null, $filter = null
)
{
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
}
/**
* @return void
*/
protected function getOutgoing()
{
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
}
/**
* @return void
*/
protected function getGemeinsamestudien()
{
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiengang_kz' => $studiengang_kz,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'filter' => $filter,
'orgform_kurzbz' => $orgform_kurzbz
));
$this->fetchPrestudents($studiengang_kz, $studiensemester_kurzbz, $filter, $orgform_kurzbz);
}
/**
@@ -191,7 +167,7 @@ class Students extends FHCAPI_Controller
*
* @return void
*/
protected function getPrestudents($studiengang_kz, $studiensemester_kurzbz = null, $filter = null, $orgform_kurzbz = null)
protected function fetchPrestudents($studiengang_kz, $studiensemester_kurzbz = null, $filter = null, $orgform_kurzbz = null)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
@@ -223,25 +199,25 @@ class Students extends FHCAPI_Controller
break;
case "bewerbungnichtabgeschickt":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bewerbung_abgeschicktamum'] = null;
$where['ps.bewerbung_abgeschicktamum'] = null;
break;
case "bewerbungabgeschickt":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bewerbung_abgeschicktamum IS NOT NULL'] = null;
$where['bestaetigtam'] = null;
$where['ps.bewerbung_abgeschicktamum IS NOT NULL'] = null;
$where['ps.bestaetigtam'] = null;
break;
case "statusbestaetigt":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bestaetigtam IS NOT NULL'] = null;
$where['ps.bestaetigtam IS NOT NULL'] = null;
break;
case "statusbestaetigtrtnichtangemeldet":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bestaetigtam IS NOT NULL'] = null;
$where['ps.bestaetigtam IS NOT NULL'] = null;
$this->PrestudentModel->db->where('NOT EXISTS(' . $selectRT . ')', null, false);
break;
case "statusbestaetigtrtangemeldet":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bestaetigtam IS NOT NULL'] = null;
$where['ps.bestaetigtam IS NOT NULL'] = null;
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
break;
case "zgv":
@@ -358,6 +334,18 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect("'' AS gruppe");
$this->addSelectPrioRel();
//add status per semester
$this->PrestudentModel->addSelect(
"(
SELECT status_kurzbz
FROM public.tbl_prestudentstatus pss
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
LIMIT 1
) AS statusofsemester"
);
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->loadWhere($where);
@@ -367,8 +355,73 @@ class Students extends FHCAPI_Controller
$this->terminateWithSuccess($data);
}
public function getStudents($studiensemester_kurzbz,
$studiengang_kz, $semester = null, $verband = null, $gruppe = null
)
{
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'studiengang_kz' => $studiengang_kz,
'semester' => $semester,
'verband' => $verband,
'gruppe' => $gruppe
));
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, $verband, $gruppe, null, null);
}
public function getStudentsOrgform($studiensemester_kurzbz,
$studiengang_kz, $orgform_kurzbz, $semester = null, $verband = null, $gruppe = null
)
{
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'studiengang_kz' => $studiengang_kz,
'orgform_kurzbz' => $orgform_kurzbz,
'semester' => $semester,
'verband' => $verband,
'gruppe' => $gruppe
));
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, $verband, $gruppe, null, $orgform_kurzbz);
}
public function getStudentsSpezialgruppe($studiensemester_kurzbz,
$studiengang_kz, $semester, $gruppe_kurzbz,
$orgform_kurzbz = null)
{
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'studiengang_kz' => $studiengang_kz,
'semester' => $semester,
'gruppe_kurzbz' => $gruppe_kurzbz
));
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, null, null, $gruppe_kurzbz, null);
}
public function getStudentsOrgformSpezialgruppe($studiensemester_kurzbz,
$orgform_kurzbz, $studiengang_kz, $semester, $gruppe_kurzbz
)
{
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'orgform_kurzbz' => $orgform_kurzbz,
'studiengang_kz' => $studiengang_kz,
'semester' => $semester,
'gruppe_kurzbz' => $gruppe_kurzbz
));
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, null, null, $gruppe_kurzbz, $orgform_kurzbz);
}
/**
* @param integer $studiengang_kz
* @param string $studiensemester_kurzbz
* @param integer $semester (optional)
* @param string $verband (optional)
* @param integer $gruppe (optional)
@@ -377,12 +430,15 @@ class Students extends FHCAPI_Controller
*
* @return void
*/
protected function getStudents($studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null)
protected function fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
/*
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
@@ -406,6 +462,18 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect('v.gruppe');
$this->PrestudentModel->addSelect("'' AS priorisierung_relativ");
//add status per semester
$this->PrestudentModel->addSelect(
"(
SELECT status_kurzbz
FROM public.tbl_prestudentstatus pss
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
LIMIT 1
) AS statusofsemester"
);
$where = [];
@@ -455,9 +523,20 @@ class Students extends FHCAPI_Controller
*
* @return void
*/
protected function getPrestudent($prestudent_id)
public function getPrestudent($studiensemester_kurzbz, $prestudent_id)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'prestudent_id' => $prestudent_id,
));
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
@@ -482,6 +561,19 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect("COALESCE(v.semester::text, CASE WHEN public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent') THEN public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)::text ELSE ''::text END) AS semester", false);
$this->PrestudentModel->addSelect('v.verband');
$this->PrestudentModel->addSelect('v.gruppe');
//add status per semester
$this->PrestudentModel->addSelect(
"(
SELECT status_kurzbz
FROM public.tbl_prestudentstatus pss
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
LIMIT 1
) AS statusofsemester"
);
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
@@ -500,9 +592,20 @@ class Students extends FHCAPI_Controller
*
* @return void
*/
protected function getStudent($student_uid)
public function getStudent($studiensemester_kurzbz, $student_uid)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $student_uid,
));
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
@@ -527,8 +630,23 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect('v.semester');
$this->PrestudentModel->addSelect('v.verband');
$this->PrestudentModel->addSelect('v.gruppe');
//add status per semester
$this->PrestudentModel->addSelect(
"(
SELECT status_kurzbz
FROM public.tbl_prestudentstatus pss
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
LIMIT 1
) AS statusofsemester"
);
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->loadWhere([
@@ -541,13 +659,25 @@ class Students extends FHCAPI_Controller
}
/**
* @param string $studiensemester_kurzbz
* @param integer $person_id
*
* @return void
*/
protected function getPerson($person_id)
public function getPerson($studiensemester_kurzbz, $person_id)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'person_id' => $person_id,
));
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if (!$this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
{
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
@@ -565,6 +695,19 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect('v.semester');
$this->PrestudentModel->addSelect('v.verband');
$this->PrestudentModel->addSelect('v.gruppe');
//add status per semester
$this->PrestudentModel->addSelect(
"(
SELECT status_kurzbz
FROM public.tbl_prestudentstatus pss
WHERE pss.prestudent_id = public.tbl_prestudent.prestudent_id
AND pss.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
ORDER BY GREATEST(pss.datum, '0001-01-01') DESC
LIMIT 1
) AS statusofsemester"
);
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
@@ -618,10 +761,11 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect('wahlname');
$this->PrestudentModel->addSelect('vornamen');
$this->PrestudentModel->addSelect('titelpost');
$this->PrestudentModel->addSelect('svnr');
$this->PrestudentModel->addSelect('ersatzkennzeichen');
$this->PrestudentModel->addSelect('gebdatum');
$this->PrestudentModel->addSelect('geschlecht');
$this->PrestudentModel->addSelect('foto');
$this->PrestudentModel->addSelect('foto_sperre');
// semester
// verband
@@ -629,6 +773,7 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect('UPPER(stg.typ || stg.kurzbz) AS studiengang');
$this->PrestudentModel->addSelect('tbl_prestudent.studiengang_kz');
$this->PrestudentModel->addSelect('stg.bezeichnung AS stg_bezeichnung');
$this->PrestudentModel->addSelect("s.matrikelnr");
$this->PrestudentModel->addSelect('p.person_id');
$this->PrestudentModel->addSelect('pls.status_kurzbz AS status');
@@ -640,7 +785,7 @@ class Students extends FHCAPI_Controller
);
$this->PrestudentModel->addSelect("
CASE WHEN b.uid IS NOT NULL AND b.uid<>''
THEN b.uid || " . $this->PrestudentModel->escape(DOMAIN) . "
THEN CONCAT(b.uid, '@', " . $this->PrestudentModel->escape(DOMAIN) . ")
ELSE '' END AS mail_intern", false);
$this->PrestudentModel->addSelect('p.anmerkung AS anmerkungen');
$this->PrestudentModel->addSelect('tbl_prestudent.anmerkung');
@@ -709,7 +854,12 @@ class Students extends FHCAPI_Controller
*/
protected function addFilter($studiensemester_kurzbz)
{
$filter = $this->input->get('filter');
$filter = json_decode($this->input->get('filter'), true);
if (!is_array($filter))
{
$this->addMeta('addfilter', 'invalid filter: ' . $this->input->get('filter'));
return;
}
if (isset($filter['konto_count_0'])) {
$bt = $this->PrestudentModel->escape($filter['konto_count_0']);
$stdsem = $this->PrestudentModel->escape($studiensemester_kurzbz);
@@ -188,6 +188,7 @@ class Verband extends FHCAPI_Controller
array_unshift($list, [
'name' => 'PreStudent',
'link' => $link . 'prestudent',
'stg_kz' => (int)$studiengang_kz,
'children' => $this->getStdSem($link . 'prestudent/', $studiengang_kz)
]);
@@ -355,7 +356,11 @@ class Verband extends FHCAPI_Controller
$this->load->model('system/Variable_model', 'VariableModel');
$result = $this->VariableModel->getVariables(getAuthUID(), ['number_displayed_past_studiensemester']);
$data = $this->getDataOrTerminateWithError($result);
$number_displayed_past_studiensemester = $data['number_displayed_past_studiensemester'] ?? null;
$this->load->config('stv');
$number_displayed_past_studiensemester_default = $this->config->item('number_displayed_past_studiensemester_default');
$number_displayed_past_studiensemester = $data['number_displayed_past_studiensemester'] ?? $number_displayed_past_studiensemester_default;
$this->StudiensemesterModel->addPlusMinus(null, $number_displayed_past_studiensemester);
$this->StudiensemesterModel->addOrder('ende');
@@ -0,0 +1,720 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Vertraege extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAllVertraege' => ['vertrag/mitarbeiter:r'],
'getAllContractsNotAssigned' => ['vertrag/mitarbeiter:r'],
'getAllContractsAssigned' => ['vertrag/mitarbeiter:r'],
'getAllContractTypes' => ['vertrag/mitarbeiter:r'],
'getAllContractStati' => ['vertrag/mitarbeiter:r'],
'getStatiOfContract' => ['vertrag/mitarbeiter:r'],
'loadContract' => ['vertrag/mitarbeiter:r'],
'loadContractStatus' => ['vertrag/mitarbeiter:r'],
'updateContract' =>['vertrag/mitarbeiter:w'],
'addNewContract' =>['vertrag/mitarbeiter:w'],
'deleteContract' =>['vertrag/mitarbeiter:w'],
'insertContractStatus' =>['vertrag/mitarbeiter:w'],
'deleteContractStatus' =>['vertrag/mitarbeiter:w'],
'updateContractStatus' =>['vertrag/mitarbeiter:w'],
'deleteLehrauftrag' =>['vertrag/mitarbeiter:w'],
'deleteBetreuung' =>['vertrag/mitarbeiter:w'],
'getMitarbeiter' => ['vertrag/mitarbeiter:r'],
'getHeader' => ['vertrag/mitarbeiter:r'],
'getPersonAbteilung' => ['vertrag/mitarbeiter:r'],
'getLeitungOrg' => ['vertrag/mitarbeiter:r'],
]);
//Load Models and Libraries
$this->load->model('accounting/Vertrag_model', 'VertragModel');
$this->load->model('accounting/Vertragsstatus_model', 'VertragsstatusModel');
$this->load->model('accounting/Vertragstyp_model', 'VertragstypModel');
$this->load->model('accounting/Vertragvertragsstatus_model', 'VertragvertragsstatusModel');
// Load language phrases
$this->loadPhrases([
'ui',
'vertrag'
]);
}
public function getAllVertraege($person_id)
{
$result = $this->VertragModel->loadContractsOfPerson($person_id);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getAllContractsNotAssigned($person_id)
{
$result = $this->VertragModel->loadContractsOfPersonNotAssigned($person_id);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getAllContractsAssigned($person_id, $vertrag_id)
{
$result = $this->VertragModel->loadContractsOfPersonAssigned($person_id, $vertrag_id);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getStatiOfContract($person_id, $vertrag_id)
{
//check if vertrag_id corresponds with person_id and return null if not
$result = $this->VertragModel->loadWhere(
array(
'vertrag_id' => $vertrag_id,
'person_id' => $person_id
)
);
if(!hasData($result))
{
$this->terminateWithSuccess([]);
}
$result = $this->VertragModel->getStatiOfContract($vertrag_id);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getAllContractTypes()
{
$result = $this->VertragstypModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(getData($result) ?: []);
}
public function getAllContractStati()
{
$result = $this->VertragsstatusModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(getData($result) ?: []);
}
public function addNewContract()
{
$this->load->library('form_validation');
$person_id = $this->input->post('person_id');
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person_id']), self::ERROR_TYPE_GENERAL);
}
$formData = $this->input->post('formData');
$vertragstyp_kurzbz = $formData['vertragstyp_kurzbz'] ?? null;
$vertragsdatum = $formData['vertragsdatum'] ?? null;
$bezeichnung = $formData['bezeichnung'] ?? null;
$betrag = $formData['betrag'] ?? null;
$vertragsstunden = $formData['vertragsstunden'] ?? null;
$vertragsstunden_studiensemester_kurzbz = $formData['vertragsstunden_studiensemester_kurzbz'] ?? null;
$anmerkung = $formData['anmerkung'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('bezeichnung', 'Bezeichnung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Bezeichnung'])
]);
$this->form_validation->set_rules('vertragstyp_kurzbz', 'Vertragstyp', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Vertragstyp'])
]);
$this->form_validation->set_rules('vertragsdatum', 'Vertragsdatum', 'required|is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Vertragsdatum']),
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Vertragsdatum'])
]);
$this->form_validation->set_rules('betrag', 'Betrag', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Betrag']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Betrag'])
]);
$this->form_validation->set_rules('vertragsstunden', 'Stunden(Vertrags-Urfassung)', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Stunden(Vertrags-Urfassung)'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$lehrauftraege = $this->input->post('clickedRows');
$this->db->trans_start();
$result = $this->VertragModel->insert([
'person_id' => $person_id,
'vertragsdatum' => $vertragsdatum,
'bezeichnung' => $bezeichnung,
'vertragstyp_kurzbz' => $vertragstyp_kurzbz,
'betrag' => $betrag,
'vertragsstunden' => $vertragsstunden,
'vertragsstunden_studiensemester_kurzbz' => $vertragsstunden_studiensemester_kurzbz,
'anmerkung' => $anmerkung,
'insertamum' => date('c'),
'insertvon' => getAuthUID()
]);
$this->getDataOrTerminateWithError($result);
$vertrag_id = $result->retval;
$status_result = $this->VertragvertragsstatusModel->insert([
'vertrag_id' => $vertrag_id,
'uid' => getAuthUID(),
'vertragsstatus_kurzbz' => 'neu',
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
'datum' => date('c')
]);
if (!$status_result) {
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_insertOrUpdateStatusVertrag'), self::ERROR_TYPE_GENERAL);
}
//Hinzufügen der Lehraufträge
foreach ($lehrauftraege as $row)
{
if ($row['type'] == 'Lehrauftrag')
{
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$result_lehrauftrag = $this->LehreinheitmitarbeiterModel->update(
[
'lehreinheit_id' => $row['lehreinheit_id'],
'mitarbeiter_uid' => $row['mitarbeiter_uid']
],
[
'vertrag_id' => $vertrag_id
]
);
if (!$result_lehrauftrag) {
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_addOrUpdateLehrauftraege'), self::ERROR_TYPE_GENERAL);
}
}
if ($row['type'] == 'Betreuung')
{
$this->load->model('education/Projektbetreuer_model', 'Projektbetreuermodel');
$result_projektbetreuer = $this->Projektbetreuermodel->update(
[
'person_id' => $person_id,
'projektarbeit_id' => $row['projektarbeit_id'],
'betreuerart_kurzbz' => $row['betreuerart_kurzbz']
],
[
'vertrag_id' => $vertrag_id
]
);
if (!$result_projektbetreuer)
{
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_addOrUpdateLehrauftraege'), self::ERROR_TYPE_GENERAL);
}
}
}
$this->db->trans_complete();
$this->terminateWithSuccess(true);
}
public function updateContract()
{
$this->load->library('form_validation');
$vertrag_id = $this->input->post('vertrag_id');
$person_id = $this->input->post('person_id');
$formData = $this->input->post('formData');
$lehrauftraege = $this->input->post('clickedRows');
$vertragstyp_kurzbz = $formData['vertragstyp_kurzbz'] ?? null;
$vertragsdatum = $formData['vertragsdatum'] ?? null;
$bezeichnung = $formData['bezeichnung'] ?? null;
$betrag = $formData['betrag'] ?? null;
$vertragsstunden = $formData['vertragsstunden'] ?? null;
$vertragsstunden_studiensemester_kurzbz = $formData['vertragsstunden_studiensemester_kurzbz'] ?? null;
$anmerkung = $formData['anmerkung'] ?? null;
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('bezeichnung', 'Bezeichnung', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Bezeichnung'])
]);
$this->form_validation->set_rules('vertragstyp_kurzbz', 'Vertragstyp', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Vertragstyp'])
]);
$this->form_validation->set_rules('vertragsdatum', 'Vertragsdatum', 'required|is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Vertragsdatum']),
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Vertragsdatum'])
]);
$this->form_validation->set_rules('betrag', 'Betrag', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Betrag']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Betrag'])
]);
$this->form_validation->set_rules('vertragsstunden', 'Stunden(Vertrags-Urfassung)', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Stunden(Vertrags-Urfassung)'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->db->trans_start();
$result = $this->VertragModel->update(
$vertrag_id,
[
'person_id' => $person_id,
'vertragsdatum' => $vertragsdatum,
'bezeichnung' => $bezeichnung,
'vertragstyp_kurzbz' => $vertragstyp_kurzbz,
'betrag' => $betrag,
'vertragsstunden' => $vertragsstunden,
'vertragsstunden_studiensemester_kurzbz' => $vertragsstunden_studiensemester_kurzbz,
'anmerkung' => $anmerkung,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
$this->getDataOrTerminateWithError($result);
//Adding of Lehraufträge
foreach ($lehrauftraege as $row)
{
if ($row['type'] == 'Lehrauftrag')
{
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$result_lehrauftrag = $this->LehreinheitmitarbeiterModel->update(
[
'lehreinheit_id' => $row['lehreinheit_id'],
'mitarbeiter_uid' => $row['mitarbeiter_uid']
],
[
'vertrag_id' => $vertrag_id,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
if (!$result_lehrauftrag) {
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_addOrUpdateLehrauftraege'), self::ERROR_TYPE_GENERAL);
}
}
if ($row['type'] == 'Betreuung')
{
$this->load->model('education/Projektbetreuer_model', 'Projektbetreuermodel');
$result_projektbetreuer = $this->Projektbetreuermodel->update(
[
'person_id' => $person_id,
'projektarbeit_id' => $row['projektarbeit_id'],
'betreuerart_kurzbz' => $row['betreuerart_kurzbz']
],
[
'vertrag_id' => $vertrag_id,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
if (!$result_projektbetreuer)
{
$this->db->trans_rollback();
$this->terminateWithError($this->p->t('vertrag', 'error_addOrUpdateLehrauftraege'), self::ERROR_TYPE_GENERAL);
}
}
}
$this->db->trans_complete();
$this->terminateWithSuccess(true);
}
public function loadContract($vertrag_id)
{
$result = $this->VertragModel->load($vertrag_id);
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result)) {
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Vertrag_id']), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(current(getData($result)));
}
public function deleteContract($vertrag_id)
{
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
//check if attached Lehrauftrag
$resultLehrauftrag = $this->LehreinheitmitarbeiterModel->load([
'vertrag_id' => $vertrag_id
]);
if(hasData($resultLehrauftrag))
{
$resultLehrauftrag = getData($resultLehrauftrag);
foreach($resultLehrauftrag as $lehrauftrag)
{
$result = $this->LehreinheitmitarbeiterModel->update(
[
'lehreinheit_id' => $lehrauftrag->lehreinheit_id,
'mitarbeiter_uid' => $lehrauftrag->mitarbeiter_uid,
'vertrag_id' => $vertrag_id
],
[
'vertrag_id' => null,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
$this->getDataOrTerminateWithError($result);
}
}
//if attached Betreuung
$this->load->model('education/Projektbetreuer_model', 'Projektbetreuermodel');
//if attached Betreuung
$resultBetreuung = $this->Projektbetreuermodel->load([
'vertrag_id' => $vertrag_id
]);
if(hasData($resultBetreuung))
{
$resultBetreuung = getData($resultBetreuung);
foreach($resultBetreuung as $betreuung)
{
$result = $this->Projektbetreuermodel->update(
[
'person_id' => $betreuung->person_id,
'projektarbeit_id' => $betreuung->projektarbeit_id,
'betreuerart_kurzbz' => $betreuung->betreuerart_kurzbz,
'vertrag_id' => $vertrag_id
],
[
'vertrag_id' => null,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
$this->getDataOrTerminateWithError($result);
}
}
$result = $this->VertragvertragsstatusModel->load([
'vertrag_id' => $vertrag_id
]);
if(hasData($result))
{
$data = getData($result);
foreach ($data as $item)
{
//delete all entries in lehre.tbl_vertrag_vertragsstatus
$result = $this->VertragvertragsstatusModel->delete([
'vertrag_id' => $vertrag_id,
'vertragsstatus_kurzbz' => $item->vertragsstatus_kurzbz,
'uid' => $item->uid
]);
if(isError($result))
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
}
//delete Contract
$result = $this->VertragModel->delete(
array('vertrag_id' => $vertrag_id,
)
);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result)) {
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Vertrag_id']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function insertContractStatus()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('vertragsstatus_kurzbz', 'vertragsstatus_kurzbz', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'vertragsstatus_kurzbz'])
]);
$this->form_validation->set_rules('datum', 'Datum', 'required|is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Datum']),
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Datum'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->VertragvertragsstatusModel->loadWhere(
array(
'vertrag_id' => $this->input->post('vertrag_id'),
'vertragsstatus_kurzbz' => $this->input->post('vertragsstatus_kurzbz')
)
);
if (hasData($result))
{
$this->terminateWithError($this->p->t('vertrag', 'error_statusVorhanden'), self::ERROR_TYPE_GENERAL);
}
$status_result = $this->VertragvertragsstatusModel->insert([
'vertrag_id' => $this->input->post('vertrag_id'),
'uid' => getAuthUID(),
'vertragsstatus_kurzbz' => $this->input->post('vertragsstatus_kurzbz'),
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
'datum' => $this->input->post('datum')
]);
if (!$status_result) {
$this->terminateWithError('Fehler beim Hinzufügen des Vertragsstatus.');
}
return $this->terminateWithSuccess(current(getData($status_result)));
}
public function deleteContractStatus()
{
$status = $this->input->post('vertragsstatus_kurzbz');
$vertrag_id = $this->input->post('vertrag_id');
$result = $this->VertragvertragsstatusModel->delete(
array(
'vertrag_id' => $vertrag_id,
'vertragsstatus_kurzbz' => $status
)
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'vertragsstatus_kurzb']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function loadContractStatus()
{
$status = $this->input->get('vertragsstatus_kurzbz');
$vertrag_id = $this->input->get('vertrag_id');
$result = $this->VertragvertragsstatusModel->loadWhere(
array(
'vertrag_id' => $vertrag_id,
'vertragsstatus_kurzbz' => $status
)
);
if (!$result) {
$this->terminateWithError('Status not existing');
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function updateContractStatus()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('vertragsstatus_kurzbz', 'vertragsstatus_kurzbz', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'vertragsstatus_kurzbz'])
]);
$this->form_validation->set_rules('datum', 'Datum', 'required|is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Datum']),
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Datum'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$status_result = $this->VertragvertragsstatusModel->update(
[
'vertrag_id' => $this->input->post('vertrag_id'),
'vertragsstatus_kurzbz' => $this->input->post('vertragsstatus_kurzbz')
],
[
'uid' => getAuthUID(),
'updateamum' => date('c'),
'updatevon' => getAuthUID(),
'datum' => $this->input->post('datum')
]
);
if (!$status_result) {
$this->terminateWithError('Fehler beim Updaten des Vertragsstatus.');
}
return $this->terminateWithSuccess(current(getData($status_result)));
}
public function deleteLehrauftrag()
{
$lehreinheit_id = $this->input->post('lehreinheit_id');
$mitarbeiter_uid = $this->input->post('mitarbeiter_uid');
$vertrag_id = $this->input->post('vertrag_id');
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
//kein delete: ein update, bei dem die vertrag_id auf null gesetzt wird
$result = $this->LehreinheitmitarbeiterModel->update(
[
'lehreinheit_id' => $lehreinheit_id,
'mitarbeiter_uid' => $mitarbeiter_uid,
'vertrag_id' => $vertrag_id
],
[
'vertrag_id' => null,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Id_Lehrauftrag']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function deleteBetreuung()
{
$person_id= $this->input->post('person_id');
$projektarbeit_id = $this->input->post('projektarbeit_id');
$betreuerart_kurzbz = $this->input->post('betreuerart_kurzbz');
$vertrag_id = $this->input->post('vertrag_id');
$this->load->model('education/Projektbetreuer_model', 'Projektbetreuermodel');
$result = $this->Projektbetreuermodel->update(
[
'person_id' => $person_id,
'projektarbeit_id' => $projektarbeit_id,
'betreuerart_kurzbz' => $betreuerart_kurzbz,
'vertrag_id' => $vertrag_id
],
[
'vertrag_id' => null,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Id_Projektbetreuung']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)));
}
public function getMitarbeiter()
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getPersonenWithContractDetails();
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
//return data before PV21 (with filter fix angestellt, active and with bisverwendung)
$result = $this->Mitarbeitermodel->getPersonal(true, true, true);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
}
return $this->terminateWithSuccess(getData($result));
}
public function getPersonAbteilung($mitarbeiter_uid)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getPersonAbteilung($mitarbeiter_uid);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function getLeitungOrg($oekurzbz)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getLeitungOrg($oekurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function getHeader($person_id)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getHeader($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
}
@@ -0,0 +1,63 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Vorlagen extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getVorlagen' => ['admin:r', 'assistenz:r'],
'getVorlagenByLoggedInUser' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('system/Vorlage_model', 'VorlageModel');
// Additional Permission Checks
//TODO(manu) check permissions
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
$this->load->library('VorlageLib');
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function getVorlagen()
{
$this->load->model('system/Vorlage_model', 'VorlageModel');
$this->VorlageModel->addOrder('vorlage_kurzbz', 'ASC');
$result = $this->VorlageModel->loadWhere(
array(
'mimetype' => 'text/html'
));
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getVorlagenByLoggedInUser()
{
//get oe of user
$uid = getAuthUID();
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung');
$data = $this->getDataOrTerminateWithError($result);
$oe_kurzbz = current($data);
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
+73 -24
View File
@@ -11,6 +11,7 @@ class UHSTAT1 extends FHC_Controller
const CODEX_UNKNOWN_YEAR = 9999;
const CODEX_UNKNOWN_NATION = 'XXX';
const CODEX_UNKNOWN_BILDUNGMAX = 999;
const CODEX_EXCLUDED_NATIONS = ['ZZZ'];
const LOWER_BOUNDARY_YEARS = 160;
const UPPER_BOUNDARY_YEARS = 20;
@@ -32,8 +33,7 @@ class UHSTAT1 extends FHC_Controller
$this->load->library('PermissionLib');
// load models
$this->load->model('codex/Oehbeitrag_model', 'OehbeitragModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->load->model('codex/Abschluss_model', 'AbschlussModel');
$this->load->model('codex/Uhstat1daten_model', 'Uhstat1datenModel');
@@ -104,7 +104,7 @@ class UHSTAT1 extends FHC_Controller
{
$saved = false;
$person_id = $this->_getValidPersonId('sui');
$person_id = $this->_getUHSTATPersonId('sui');
$this->form_validation->set_error_delimiters('<span class="text-danger">', '</span>');
@@ -245,7 +245,7 @@ class UHSTAT1 extends FHC_Controller
// uhstat data can only be deleted with permission
if (!$this->_checkPermission('suid')) show_error('no permission');
$person_id = $this->_getValidPersonId('suid');
$person_id = $this->_getUHSTATPersonId('suid');
$uhstat1datenRes = $this->Uhstat1datenModel->delete(
array('person_id' => $person_id)
@@ -287,13 +287,17 @@ class UHSTAT1 extends FHC_Controller
*/
private function _getFormMetaData()
{
$person_id = $this->_getValidPersonId('s');
$person_id = $this->_getUHSTATPersonId('s');
// read only display param
$readOnly = $this->input->get('readOnly');
// depending on permissions, editing or deleting is possible
$editPermission = $this->_checkPermission('sui');
// checking permissions for form
// saving is possible if there permission or student log in (but not from application tool)
$savePermission = $this->_checkPermission('sui') || ($this->_getUserPersonId() && !$this->_getApplicationToolPersonId());
// deleting only possible with permission
$deletePermission = $this->_checkPermission('suid');
$languageIdx = $this->_getLanguageIndex();
@@ -304,7 +308,7 @@ class UHSTAT1 extends FHC_Controller
'abschluss_nicht_oesterreich' => array(),
'jahre' => array(),
'person_id' => $person_id,
'editPermission' => $editPermission,
'savePermission' => $savePermission,
'deletePermission' => $deletePermission,
'readOnly' => $readOnly
);
@@ -336,15 +340,19 @@ class UHSTAT1 extends FHC_Controller
if (hasData($nationRes))
{
$dropdownNations = [];
$nations = getData($nationRes);
// put austria in beginning of selection
foreach ($nations as $nation)
{
if ($nation->nation_code == self::CODEX_OESTERREICH) array_unshift($nations, $nation);
// put austria in beginning of selection
if ($nation->nation_code == self::CODEX_OESTERREICH)
array_unshift($dropdownNations, $nation);
elseif (!in_array($nation->nation_code, self::CODEX_EXCLUDED_NATIONS)) // add nation if not excluded
$dropdownNations[] = $nation;
}
$formMetaData['nation'] = $nations;
$formMetaData['nation'] = $dropdownNations;
}
// get abschluss list
@@ -386,7 +394,7 @@ class UHSTAT1 extends FHC_Controller
*/
private function _getUHSTAT1Data()
{
$person_id = $this->_getValidPersonId('s');
$person_id = $this->_getUHSTATPersonId('s');
$this->Uhstat1datenModel->addSelect(
implode(', ', array_keys($this->_uhstat1Fields))
@@ -417,29 +425,70 @@ class UHSTAT1 extends FHC_Controller
}
/**
* Gets Id of person having permissions to manage UHSTAT1 data.
* Can be passed as parameter or be in session.
* Gets Id of person, for which UHSTAT1 data is edited.
* Can be passed as parameter, id of logged in person, or be in session.
* @param berechtigungsArt type of permission (suid)
* @return int person_id
*/
private function _getValidPersonId($berechtigungsArt)
private function _getUHSTATPersonId($berechtigungsArt)
{
// if coming from bewerbungstool - person id is in session (person must be logged in bewerbungstool)
$applicationToolPersonId = $this->_getApplicationToolPersonId();
if (isset($applicationToolPersonId) && is_numeric($applicationToolPersonId)) return $applicationToolPersonId;
// if successfully logged in
$loggedInPersonId = $this->_getUserPersonId();
if (isset($loggedInPersonId) && is_numeric($loggedInPersonId))
{
// if person id passed directly...
$person_id = $this->input->post('person_id');
if (!isset($person_id)) $person_id = $this->input->get('person_id');
if (isset($person_id))
{
if (!is_numeric($person_id)) show_error("invalid person id");
// ...check if there is a permission for editing UHSTAT1 data
if ($this->_checkPermission($berechtigungsArt)) return $person_id;
}
// if no id passed, use logged in person id
return $loggedInPersonId;
}
show_error("No permission");
}
/**
* Gets person Id if there is a application tool login.
* @return person Id or null
*/
private function _getApplicationToolPersonId()
{
// if coming from aplication tool - person id is in session (person must be logged in bewerbungstool)
if (isset($_SESSION[self::PERSON_ID_SESSION_INDEX])
&& is_numeric($_SESSION[self::PERSON_ID_SESSION_INDEX])
&& isset($_SESSION[self::LOGIN_SESSION_INDEX])
)
return $_SESSION[self::PERSON_ID_SESSION_INDEX];
// if person id passed directly...
$person_id = $this->input->post('person_id');
if (!isset($person_id)) $person_id = $this->input->get('person_id');
return null;
}
if (!isset($person_id) || !is_numeric($person_id)) show_error("invalid person id");
// ...check if there is a permission for editing UHSTAT1 data
if ($this->_checkPermission($berechtigungsArt)) return $person_id;
show_error("No permission");
/**
* Gets person Id if there is a user login.
* @return person Id or null
*/
private function _getUserPersonId()
{
$loggedInPersonId = getAuthPersonId();
if (isset($loggedInPersonId) && is_numeric($loggedInPersonId))
{
// check if the the user is a student and if the benutzer is active
$this->BenutzerModel->addSelect('1');
$res = $this->BenutzerModel->loadWhere(["public.tbl_benutzer.person_id" => $loggedInPersonId, "public.tbl_benutzer.aktiv" => TRUE]);
if (hasData($res)) return $loggedInPersonId;
}
return null;
}
/**
@@ -5,7 +5,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Stundenplan extends Auth_Controller
class LvPlan extends Auth_Controller
{
/**
@@ -1,168 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Noten extends Auth_Controller
{
public function __construct()
{
parent::__construct([
'get' => 'student/noten:r',
'getZeugnis' => 'student/noten:r',
'update' => ['admin:w', 'assistenz:w']
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
public function get()
{
$this->load->model('codex/Note_model', 'NoteModel');
$result = $this->NoteModel->addOrder('note');
$result = $this->NoteModel->load();
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
return $this->outputJson($result);
}
public function getZeugnis($prestudent_id, $all = null)
{
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$result = $this->StudentModel->loadWhere([
'prestudent_id' => $prestudent_id
]);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
return $this->outputJson($result);
}
if (!hasData($result))
return $this->outputJsonSuccess(null);
$student_uid = current(getData($result))->student_uid;
$studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null;
$result = $this->ZeugnisnoteModel->getZeugnisnoten($student_uid, $studiensemester_kurzbz);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
return $this->outputJson($result);
}
public function update()
{
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$this->load->library('form_validation');
$_POST = json_decode(utf8_encode($this->input->raw_input_stream), true);
if (empty($_POST) || !is_array(current($_POST))) {
$result = $this->hasPermissionUpdate($this->input->post('lehrveranstaltung_id'), $this->input->post('student_uid'));
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
return $this->outputJson($result);
}
$this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrverantaltung ID', 'required|numeric');
$this->form_validation->set_rules('student_uid', 'Student UID', 'required');
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester Kurzbezeichnung', 'required');
$this->form_validation->set_rules('note', 'Note', 'required|numeric');
$post = [$_POST];
} else {
foreach ($_POST as $i => $data) {
$lvid = isset($data['lehrveranstaltung_id']) ? $data['lehrveranstaltung_id'] : null;
$uid = isset($data['student_uid']) ? $data['student_uid'] : null;
$result = $this->hasPermissionUpdate($lvid, $uid);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
return $this->outputJson($result);
}
$this->form_validation->set_rules($i . '[lehrveranstaltung_id]', '#' . $i . ' Lehrverantaltung ID', 'required|numeric');
$this->form_validation->set_rules($i . '[student_uid]', '#' . $i . ' Student UID', 'required');
$this->form_validation->set_rules($i . '[studiensemester_kurzbz]', '#' . $i . ' Studiensemester Kurzbezeichnung', 'required');
$this->form_validation->set_rules($i . '[note]', '#' . $i . ' Note', 'required|numeric');
}
$post = $_POST;
}
if ($this->form_validation->run() == false) {
$this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
return $this->outputJsonError($this->form_validation->error_array());
}
$final_result = success();
$this->ZeugnisnoteModel->db->trans_start();
foreach ($post as $i => $data) {
$note = $data['note'];
unset($data['note']);
$result = $this->ZeugnisnoteModel->update($data, [
'note' => $note,
'benotungsdatum' => date('c'),
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]);
if (isError($result)) {
$final_result = $result;
break;
}
}
$this->ZeugnisnoteModel->db->trans_complete();
if (isError($final_result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
$this->outputJson($final_result);
}
protected function hasPermissionUpdate($lehrveranstaltung_id, $student_uid)
{
// TODO(chris): error phrases!
if ($lehrveranstaltung_id === null || $student_uid === null)
return success();
$result = $this->StudentModel->load([$student_uid]);
if (isError($result))
return $result;
if (!hasData($result))
return error('Fehler beim Ermitteln des Studenten');
$student = current(getData($result));
if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz))
return success();
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz))
return success();
$result = $this->StudienplanModel->getAllOesForLv($lehrveranstaltung_id);
if (isError($result))
return $result;
$oes = getData($result) ?: [];
$result = $this->LehrveranstaltungModel->getStg($lehrveranstaltung_id);
if (isError($result))
return $result;
if (hasData($result))
$oes[] = current(getData($result));
foreach ($oes as $oe) {
if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz))
return success();
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz))
return success();
}
return error('Forbidden');
}
}
+6 -6
View File
@@ -65,7 +65,7 @@ class Config extends Auth_Controller
$preset_decoded = json_decode($preset->preset, true);
$this->DashboardLib->addWidgetsToWidgets($preset_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$this->DashboardLib->addWidgetsToWidgets($preset_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$preset->preset = json_encode($preset_decoded);
@@ -92,7 +92,7 @@ class Config extends Auth_Controller
}
$preset_decoded = json_decode($preset->preset, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded['widgets'], $funktion_kurzbz, $widgetid))
if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded, $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
@@ -119,7 +119,7 @@ class Config extends Auth_Controller
$override_decoded = json_decode($override->override, true);
$this->DashboardLib->addWidgetsToWidgets($override_decoded['widgets'], $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$this->DashboardLib->addWidgetsToWidgets($override_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$override->override = json_encode($override_decoded);
@@ -148,7 +148,7 @@ class Config extends Auth_Controller
$override_decoded = json_decode($override->override, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded['widgets'], $funktion_kurzbz, $widgetid))
if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded, $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
@@ -202,10 +202,10 @@ class Config extends Auth_Controller
if ($conf)
{
$preset = json_decode($conf->preset, true);
if (!isset($preset['widgets']) || !isset($preset['widgets'][$funktion]))
if (!isset($preset[$funktion]) || !isset($preset[$funktion]['widgets']))
$result[$funktion] = [];
else
$result[$funktion] = $preset['widgets'][$funktion];
$result[$funktion] = $preset[$funktion]['widgets'];
}
else
$result[$funktion] = [];
+7 -4
View File
@@ -95,12 +95,15 @@ class AntragJob extends JOB_Controller
continue;
}
$leitung = current(getData($result));
if (!isset($stgLeitungen[$leitung->uid]))
$leitungen = getData($result);
foreach ($leitungen as $leitung)
{
$stgLeitungen[$leitung->uid] = [ 'Details' => $leitung, 'stgs' => [] ];
if (!isset($stgLeitungen[$leitung->uid]))
{
$stgLeitungen[$leitung->uid] = ['Details' => $leitung, 'stgs' => []];
}
$stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz;
}
$stgLeitungen[$leitung->uid]['stgs'][] = $antrag->studiengang_kz;
$result = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id);
if (isError($result))
@@ -48,7 +48,9 @@ class IssueResolver extends IssueResolver_Controller
'CORE_PERSON_0001' => 'CORE_PERSON_0001',
'CORE_PERSON_0002' => 'CORE_PERSON_0002',
'CORE_PERSON_0003' => 'CORE_PERSON_0003',
'CORE_PERSON_0004' => 'CORE_PERSON_0004'
'CORE_PERSON_0004' => 'CORE_PERSON_0004',
'CORE_PERSON_0005' => 'CORE_PERSON_0005',
'CORE_PERSON_0006' => 'CORE_PERSON_0006'
);
// fehler which are resolved by the job the same way as they are produced
@@ -52,6 +52,7 @@ class OneTimeMessages extends JOB_Controller
JOIN public.tbl_prestudentstatus ps USING (prestudent_id)
JOIN public.tbl_studiengang s USING (studiengang_kz)
WHERE get_rolle_prestudent(ps.prestudent_id, NULL) = \'Wartender\'
AND ps.status_kurzbz = \'Wartender\'
AND ps.studiensemester_kurzbz = ?
AND ps.datum <= NOW() - \''.$days.' days\'::interval
AND s.typ = ?

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