Compare commits

...

929 Commits

Author SHA1 Message Date
adisposkofh 0a4906c5ac added course-specific mailing lists 2026-05-13 16:07:43 +02:00
Harald Bamberger bbb4f8a01c Merge branch 'bug-76146/studvw_karteireiter_dokumente_akzeptiert_eintraege_ohne_vorhandenes_dokument' 2026-05-06 16:13:50 +02:00
Harald Bamberger fdbb93a5c5 bugfix download booking receipt failed. only fetch oehbeitrag from bis.tbl_oehbeitrag if a user is logged in 2026-05-05 14:36:07 +02:00
Harald Bamberger b7e48633ab Merge branch 'master' into bug-76146/studvw_karteireiter_dokumente_akzeptiert_eintraege_ohne_vorhandenes_dokument 2026-05-05 13:33:38 +02:00
Harald Bamberger 04dc1eb07b Merge branch 'bug-76519/StudVW_Messages_Table_column_Stati' 2026-05-05 13:04:58 +02:00
Harald Bamberger 50b229090b prefetch phrases and then render filter component instead of redrawing the table 2026-05-05 13:04:11 +02:00
Harald Bamberger 2d27a998c4 Merge branch 'bug-76109/VVW_Details_und_Status_not_Loading' 2026-05-05 11:17:49 +02:00
Harald Bamberger 090e535466 add header filters, increase height of tables, use correct category for phrase lehreinheit_id 2026-05-05 11:04:48 +02:00
Harald Bamberger c4d35181db Merge branch 'master' into bug-76109/VVW_Details_und_Status_not_Loading 2026-05-05 09:01:49 +02:00
Harald Bamberger 0ac6ef4599 Merge branch 'feature-62607/konto_oh_beitrag_betrag_aus_eigener_tabelle' 2026-05-05 08:46:22 +02:00
Harald Bamberger cb60ddcc94 Merge branch 'master' into feature-62607/konto_oh_beitrag_betrag_aus_eigener_tabelle 2026-05-04 15:41:52 +02:00
Harald Bamberger bd4ced9559 bugfix: comma as decimal separator prevents saving booking, bugfix messages tinymce not resizeable 2026-05-04 14:39:19 +02:00
Andreas Österreicher a04d2acb86 Fixed Blank on Phrase for Abgabetool 2026-05-04 10:49:33 +02:00
Harald Bamberger de2aabf00b readd dokument preview link to api response 2026-05-04 09:30:16 +02:00
ma0068 685fc69e5d update css and add provisional height 2026-04-30 18:02:38 +02:00
Andreas Österreicher 552faefa51 Merge branch 'feature-76108/microdegree_abschlussurkunde' 2026-04-27 08:55:08 +02:00
Harald Bamberger 954397f028 Merge branch 'feature-70376/Lohnguide' 2026-04-22 18:52:51 +02:00
Harald Bamberger 80faa61c91 Merge branch 'master' into feature-70376/Lohnguide 2026-04-22 18:46:57 +02:00
Werner Masik 961ede66a9 lohnguide db update changed 2026-04-22 18:40:22 +02:00
Andreas Österreicher 6fec8382b5 Merge branch 'feature-76554/Personalmeldung_alt_bei_Lehre_nicht_melderelevant_rausfiltern' 2026-04-22 09:15:23 +02:00
Andreas Österreicher 4eb076d115 Fixed Saving of Entwicklungsteam 2026-04-21 17:34:36 +02:00
Harald Bamberger 7427aa87ea Merge branch 'feature-76545/findAbgabenNewOrUpdatedSinceByAbgabedatumFixTimestampDateComparison' 2026-04-21 17:01:04 +02:00
Johann Hoffmann 85043e57db added missing parenthesis 2026-04-21 17:00:07 +02:00
Johann Hoffmann 5beddbccb4 changed the where clause to a simpler = CURRENT_DATE comparison -> works the same if the job runs daily and fetches updates of one day/date; has to be changed back in case we want to find updates in a range larger than 1 day in an interval larger than 1 day; 2026-04-21 14:18:45 +02:00
kindlm e2ae9b88c8 Merge remote-tracking branch 'origin/master' 2026-04-21 12:56:30 +02:00
kindlm ca3abf9154 Small Style-Fix in Testtool
To make headings stand out more clearly from the buttons
2026-04-21 12:56:02 +02:00
Alexei Karpenko f863c6d728 personalmeldung legacy system: melderelevant is checked for lehre, bugfix: lehre is correctly added if studiengang already has sws 2026-04-20 18:24:30 +02:00
Harald Bamberger 92a2053b42 Merge branch 'feature-40870/BUG_Studstatus_unpause_order_should_be_DESC' 2026-04-20 17:30:14 +02:00
kindlm 70602be54e SaveSort und Filter-Reset in RaumÜbersicht 2026-04-20 11:30:17 +02:00
kindlm dac71f597a Spalte Anmeldedatum in RT-Übersicht
Spalte Frage_ID in RT-Administration
JQuery und Tabelsorter aus Include in Service_Uebersicht
2026-04-20 11:24:59 +02:00
Johann Hoffmann 3a646ffe77 adapt AbgabeJob relevant queries so they compare with the pgsql date function CURRENT_DATE instead of NOW() to avoid the cutoff from uploads the happened "yesterday but more than 24 hours ago"; also added another "abgabedatum < CURRENT_DATE" condition, to avoid sending this exact case as updates 2 days in a row; 2026-04-20 11:06:06 +02:00
ma0068 26db4a5e7a adding redraw tabulator and fallback to avoid empty column 2026-04-20 09:31:52 +02:00
Harald Bamberger 98a10a2f55 Merge branch 'feature-69389/AbmeldungSTGL_Anzeige_mit_Studiengangskuerzel' 2026-04-17 12:37:49 +02:00
Harald Bamberger e48b94b858 studiengangskuerzel statt kurzbzlang 2026-04-17 12:35:55 +02:00
Andreas Österreicher 0ff29ba6af Merge branch 'epic-56039/LV-Evaluierung' 2026-04-16 13:22:40 +02:00
Harald Bamberger ba543448ae Merge branch 'bug-76260/StudVW_Messages_TinyMCE_Cursor_Jumping_TextInput' 2026-04-16 11:26:32 +02:00
Harald Bamberger f121f9b5a2 deactivate pagination - since potentially msg threads are not shown completely 2026-04-16 11:23:57 +02:00
Harald Bamberger 88b22f5490 revert to v-if to not render element when not necessary and use Vue.nextTick for dependent code 2026-04-15 17:02:58 +02:00
Harald Bamberger 4b7ee9abe1 Merge branch 'feature-70376/Lohnguide' 2026-04-15 15:52:12 +02:00
Cristina d499619cf3 Added phrase endedatumMussInZukunftLiegen 2026-04-15 13:39:06 +02:00
Cristina f489153ff3 Merge branch 'master' into epic-56039/LV-Evaluierung 2026-04-15 12:25:05 +02:00
Cristina 9b79a07fa2 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-04-15 12:24:44 +02:00
Harald Bamberger 6ce14a25d7 Merge branch 'master' into feature-70376/Lohnguide 2026-04-15 11:49:26 +02:00
Werner Masik c701d92779 fix db_update 2026-04-15 11:15:10 +02:00
Werner Masik 73e03ba901 Gehaltstyp Überstundenpauschale und Sachbezug PKW 2026-04-15 10:44:03 +02:00
ma0068 95a7797ae9 delete unused apicall for mode modal
add editor.setContent to function getReplyData
readd loadReplyData and use v-show for visibleDiv for mode inSamePage
2026-04-14 15:46:34 +02:00
ma0048 3ce3eff022 fehlendes mapping hinzugefuegt 2026-04-14 09:30:45 +02:00
ma0048 21d80905a2 akzeptierte dokumente anzeigen, auch wenn kein dokument vorhanden ist 2026-04-13 13:04:46 +02:00
Andreas Österreicher 3a91b12f31 Merge branch 'epic-56039/LV-Evaluierung' 2026-04-13 10:39:00 +02:00
ma0048 ea0a249612 micro degree abschlussdokumente hinzugefuegt 2026-04-13 09:14:27 +02:00
ma0068 843894405e changes for NewDiv
remove Watcher for formData Fields
add predefault settings for tabulator fields
add setContent for Editor
change text for closing window/tab
show alertSuccess for sending Message just in case of inSamePage
2026-04-10 13:03:24 +02:00
ma0068 8fddbc3a32 delete watcher for formData fields, add setContent for loading Vorlage 2026-04-10 09:15:34 +02:00
Harald Bamberger b2538075ee use STV_TAGS_ENABLED config when preparing sql statement for students list to query tags only if enabled 2026-04-07 10:35:06 +02:00
Werner Masik 5c463c0866 add vordienstzeit to lohnguide 2026-04-06 22:25:13 +02:00
Werner Masik 423bbd95a6 add vordienstzeit to lohnguide 2026-04-06 22:25:12 +02:00
Cristina 386cc779bf Merge branch 'master' into epic-56039/LV-Evaluierung 2026-04-02 15:49:20 +02:00
Cristina 08c6d58a50 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-04-02 14:24:39 +02:00
Cristina 3f53c5feba Added: method getKFLByUID to get Kompetenzfeldleitung by UID 2026-04-02 14:23:59 +02:00
ma0068 298dbbf400 use context vm for tabulator event, refactor function toggleRowClick, delete unused commented sections 2026-04-02 10:58:49 +02:00
Andreas Österreicher 2c057aad58 Updated Startup Dump to Final 3.3 Version 2026-04-01 13:00:50 +02:00
kindlm c2ce831bca Merge remote-tracking branch 'origin/master' 2026-03-26 11:43:59 +01:00
kindlm 21c1f13b28 Spalte "faktiv" (Foebis-Aktiv) im FAS 2026-03-26 11:43:20 +01:00
Andreas Österreicher e0079bb812 Merge branch 'feature-71665/mc4_vorlage' 2026-03-26 09:27:00 +01:00
Andreas Österreicher 966d1d10f6 Merge branch 'feature-71566/Studienordnung_Anpassungen_fuer_Programme_und_Lehrgaenge' 2026-03-26 09:05:31 +01:00
Andreas Österreicher 76936ad74f Merge branch 'feature-75703/BIS_Personalmeldung_Lehrgaenge' 2026-03-26 08:31:13 +01:00
Harald Bamberger 6fbb09eb6e group or clause 2026-03-25 16:32:43 +01:00
Harald Bamberger cfe1307018 Merge branch 'feature-68530/Dashboard_Cleanup_Admin' 2026-03-25 15:37:34 +01:00
Harald Bamberger 5139c3e44e use array_replace_recursive instead of array_merge_recursive to prevent two scalar values being merged to an array 2026-03-25 15:15:05 +01:00
Harald Bamberger 627a52e3d1 Merge branch 'master' into feature-70376/Lohnguide 2026-03-25 09:36:27 +01:00
chfhtw 1951cd6fa8 split/rename dashboard api factories 2026-03-24 16:08:02 +01:00
chfhtw e3093bdf3f get magic funktionen (Mitarbeiter, Student) as dashboard presets 2026-03-24 15:15:36 +01:00
chfhtw b11d8d056a get access rights from permissionlib 2026-03-24 15:15:12 +01:00
chfhtw 3a4015eced dashboard useroverwrite: remove doubles in other funktionen 2026-03-24 15:15:04 +01:00
chfhtw aeb5d40840 rename api endpoints 2026-03-24 15:14:39 +01:00
Alexei Karpenko 49c712a5b6 Personalmeldung sws: rounding to 2 decimals 2026-03-24 13:57:23 +01:00
Harald Bamberger 46817b846a fix e.g. long lines of underscores in cms content 2026-03-24 13:29:20 +01:00
Harald Bamberger 8c75608eaf add menu entry for Dashboard Admin 2026-03-24 13:21:50 +01:00
chfhtw 2720ed9ffb timezone from global object 2026-03-24 11:00:09 +01:00
chfhtw 2fc392c084 refactor dashboards Preset->addWidgets to (single) Preset->addWidget 2026-03-23 16:05:22 +01:00
chfhtw ca630e94ae remove debug line 2026-03-23 15:46:13 +01:00
chfhtw 9cff50fa3b extract preset logic from dashboard admin api 2026-03-23 15:44:42 +01:00
chfhtw 3d7a6b1ad3 dashboard user api: empty -> check for false/null 2026-03-23 15:42:28 +01:00
chfhtw f15fd40636 dashboardlib bug: array <=> stdclass 2026-03-23 15:41:32 +01:00
chfhtw 054cf2f258 correct form validation & typo in api dashboard widget 2026-03-23 15:06:25 +01:00
chfhtw dc067a619b make widgets resizeable in dashboard admin 2026-03-23 14:07:31 +01:00
chfhtw 2a762fa4ab add renderers & timezone to dashboard admin for calendar widget 2026-03-23 13:22:30 +01:00
chfhtw ccade6ae0e rename dashboard admin controller and views 2026-03-23 11:47:28 +01:00
chfhtw 6971aed030 parsing happens in backend not frontend 2026-03-23 11:46:45 +01:00
chfhtw 60e556b2a8 wrong case 2026-03-23 11:33:45 +01:00
chfhtw 42fbbc5257 remove unused file 2026-03-23 11:28:31 +01:00
chfhtw d01dedb79c remove unused file 2026-03-23 11:23:01 +01:00
chfhtw 1972b461e7 replace controllers/dashboard/Config.php with controllers/api/frontend/v1/dashboard/User.php & controllers/api/frontend/v1/dashboard/DashboardAdmin.php 2026-03-23 11:21:15 +01:00
chfhtw e957926a4d replace controllers/dashboard/Widget.php with controllers/api/frontend/v1/dashboard/Widget.php 2026-03-23 10:57:43 +01:00
chfhtw bac2c13da3 viewData is mandatory so we dont need to load it if its not set 2026-03-23 10:44:39 +01:00
ma0068 b90c26412a DB update: new Organisationseinheittyp Programm 2026-03-20 13:06:16 +01:00
chfhtw 65c7ad2aac use correct error handling in FhcApi in case of success 2026-03-20 12:29:01 +01:00
chfhtw 126a2d3b7b add deepToRaw function to helpers/ObjectUtils 2026-03-20 11:23:35 +01:00
Harald Bamberger 60734f708e Merge branch 'master' into feature-68530/Dashboard_Cleanup_Admin 2026-03-19 16:20:06 +01:00
Harald Bamberger 9e6c15a10d Merge branch 'bug-76010/StudVW_Archivieren_Ausbildungsvertrag_Aufgenommene' 2026-03-19 15:41:44 +01:00
Harald Bamberger 14a8e2f001 Funktionen fett schreiben, die schon presets hinterlegt haben, demo aus views und Controller namen entfernen, preview hinzufuegen 2026-03-18 15:48:57 +01:00
ma0068 7603f8f12b Bugfix: use null instead of empty string, provide kuerzel 2026-03-18 14:32:09 +01:00
Harald Bamberger 059b13938e Merge branch 'master' into feature-70376/Lohnguide 2026-03-18 11:46:27 +01:00
Harald Bamberger a4f2502fe6 dashboard admin: funktionen sortieren, allgemein/general wieder hinzufuegen 2026-03-18 10:58:05 +01:00
Harald Bamberger 7c1762d467 Merge branch 'master' into feature-68530/Dashboard_Cleanup_Admin 2026-03-18 09:20:53 +01:00
Andreas Österreicher 96745525f1 Merge branch 'feature-71530/Error_beim_Archivieren_von_Diplomasupplement_STUDVW_Neu' 2026-03-16 11:28:56 +01:00
Andreas Österreicher 8d6e04ea77 Merge branch 'feature-61164/AbgabetoolQualityGates' 2026-03-16 11:09:52 +01:00
Andreas Österreicher d9e5acb52c Merge branch 'master' into feature-61164/AbgabetoolQualityGates 2026-03-16 11:08:44 +01:00
Johann Hoffmann 6ec32b0ca3 update tabulator persistence id 2026-03-16 11:05:48 +01:00
Johann Hoffmann 4778bb82c3 assistenz action buttons lefthand alignment & lower minwidth 2026-03-16 10:56:51 +01:00
Andreas Österreicher e20ff52f5b Merge branch 'feature-75417/pep_finetuning' 2026-03-16 09:08:10 +01:00
Andreas Österreicher df05af98d2 FHB - Markierung von Outgoing ohne Endedatum 2026-03-16 09:01:33 +01:00
Harald Bamberger 0764a597af do not allow foto editing in contract management 2026-03-12 15:18:26 +01:00
Harald Bamberger 8c36fe585a filter component add missing this 2026-03-12 15:09:46 +01:00
Johann Hoffmann 5ef1dccfc9 added missing phrase c4noZuordnungBetreuerStudent 2026-03-12 14:58:35 +01:00
Harald Bamberger d4b81da437 fix filter component also consider tabulator 6 selectableRows option to determine if tabulator has selector 2026-03-12 14:34:42 +01:00
Harald Bamberger b91efb6189 stv notizperson fix permission check to be able to add notes to prestudents that do not have an uid 2026-03-12 13:56:03 +01:00
Johann Hoffmann 6d28b8986d Merge remote-tracking branch 'origin/master' into feature-61164/AbgabetoolQualityGates
# Conflicts:
#	public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit/Projektbetreuer.js
2026-03-12 09:47:54 +01:00
kindlm 40757322e7 Spalte "FGM" (Förder-Guthaben-Monate) bei Prestudentstatus einblendbar 2026-03-11 17:52:31 +01:00
Johann Hoffmann b43f1ec920 AbgabetoolAssistenz download latest uploaded file action button; UX changes Projektarbeit Tab Stv; fix stv form input bug after invalidation for selects; 2026-03-11 17:00:56 +01:00
Harald Bamberger 6cd4aebe8d stv projektarbeit projektbetreuer use correct ref 2026-03-11 14:54:06 +01:00
Andreas Österreicher 2b527bccd2 Merge branch 'feature-75873/Noteneingabe-Punkte' 2026-03-11 13:42:17 +01:00
Andreas Österreicher 41271711ec Merge branch 'bugfix-55630/Falsche-Nachpruefungsdaten-auf-Notenliste-bei-Wiederholern' into feature-75873/Noteneingabe-Punkte 2026-03-11 13:26:46 +01:00
Harald Bamberger 6287b6aef8 Merge branch 'feature-68296/Vue_Router_via_Extensions_erweitern_ma0080' 2026-03-11 13:19:02 +01:00
Harald Bamberger 3e9d960781 Merge branch 'master' into feature-68296/Vue_Router_via_Extensions_erweitern_ma0080 2026-03-11 12:52:18 +01:00
Alexei Karpenko c3d20bb181 Personalmeldung Lehrgaenge: distributed sws among Lehrgang types (Zertifikat, Master etc...) 2026-03-11 12:37:28 +01:00
Harald Bamberger 5ce0232890 fix bug in archiv tab 2026-03-11 11:50:09 +01:00
Harald Bamberger cf4ec12c00 Merge branch 'master' into feature-68296/Vue_Router_via_Extensions_erweitern_ma0080 2026-03-10 17:08:03 +01:00
Andreas Österreicher d35eca919f Merge branch 'hotfix-69228/DOCSBOX' 2026-03-10 13:53:58 +01:00
Harald Bamberger 61d133b2fd Merge branch 'master' into feature-68296/Vue_Router_via_Extensions_erweitern_ma0080 2026-03-10 12:14:35 +01:00
Andreas Österreicher 7cd438d188 Wenn Punkteeingabe aktiviert ist werden auch Punkte in der Excel Notenliste exportiert damit es beim Import von Spezialnoten (zb 18) nicht zu Problemen kommt 2026-03-10 11:47:24 +01:00
Harald Bamberger a733d9a861 Merge branch 'vv_und_studvw_2026_02_rc4_ma0080' 2026-03-10 11:37:34 +01:00
Harald Bamberger 33252de895 use ma0646 tabulator scroll fix on students/prestudents list 2026-03-10 11:11:40 +01:00
Harald Bamberger fb388346bf Merge branch 'master' into vv_und_studvw_2026_02_rc4_ma0080 2026-03-10 08:41:56 +01:00
Harald Bamberger 32a2e7708f remove bg color in stv and lvvw Tabs, detailsheader ajust foto buttons 2026-03-09 12:10:22 +01:00
Werner Masik 6b816def31 add lohnguide to vertragsbestandteil SQL 2026-03-05 15:34:51 +01:00
Werner Masik 5fbcf588ed fix vertragsbestandteil lohnguide 2026-03-05 14:29:56 +01:00
Harald Bamberger c40fdb2c4f getMessagesForTable laststatus only for filteredmessages 2026-03-05 11:35:57 +01:00
Harald Bamberger 47b5eecb9b Merge branch 'master' into vv_und_studvw_2026_02_rc4_ma0080 2026-03-04 18:57:13 +01:00
Harald Bamberger b7fd7e4298 Merge branch 'vv_und_studvw_2026_02_rc4' into vv_und_studvw_2026_02_rc4_ma0080 2026-03-04 17:53:53 +01:00
Harald Bamberger 1af334989e Merge branch 'feature-71601/drag_drop_aus_tabulator_heraus_ohne_vorheriges_selektieren' into vv_und_studvw_2026_02_rc4 2026-03-04 17:53:19 +01:00
Harald Bamberger 4f541495ad Merge branch 'feature-71610/verbandsbaum_togglen_ohne_select' into vv_und_studvw_2026_02_rc4 2026-03-04 17:25:32 +01:00
Harald Bamberger 35d83942c0 use primevue tabs in LVVerwaltung 2026-03-04 16:03:51 +01:00
Alexei Karpenko fc4e79c1f5 Personalmeldung: include Lehrgaenge in Lehre in legacy script 2026-03-04 11:12:58 +01:00
Werner Masik 41b2a6d1d4 added db migration for lohnguide 2026-03-04 10:53:30 +01:00
Harald Bamberger 1810bd40bd fix bug introduced in commit 043b1bcf11 send intern also using private email addresses 2026-03-04 09:39:58 +01:00
Harald Bamberger 5347cb1d63 add config STV_TAGS_ENABLED and use it to enable or disable tags in StudVw 2026-03-03 17:15:23 +01:00
Harald Bamberger 77731ed559 Merge branch 'feature-68767/FHC4_Studierendenverwaltung_Details_4spaltig_ma0080' into vv_und_studvw_2026_02_rc4_ma0080 2026-03-03 13:46:29 +01:00
Harald Bamberger 0283c6ca43 bg-color in details, padding-y tabs, messages align table and preview area 2026-03-03 12:24:34 +01:00
Werner Masik e054f1222b basic model and factory for lohnguide 2026-03-03 11:50:45 +01:00
Andreas Österreicher 8abb38123a Merge branch 'feature-70440/Change_var_dump_to_error_log_to_show_the_referring_script' 2026-03-03 11:41:16 +01:00
Andreas Österreicher d1928d4151 Merge branch 'bug-56209/is_valid_date_vs_isValidDate' 2026-03-03 11:29:29 +01:00
Andreas Österreicher bcd8f11f35 Fixed Merge Problem 2026-03-03 11:26:18 +01:00
Andreas Österreicher 5949527ee2 Merge branch 'master' into bug-56209/is_valid_date_vs_isValidDate 2026-03-03 11:07:18 +01:00
Johann Hoffmann 56a6aa993e getMitarbeiterProjektarbeiten safeguard in case a person without any assigned betreuungen opens the page for some reason to avoid nasty confusing sql error messages from querying with empty parameters 2026-03-03 10:52:12 +01:00
Andreas Österreicher ea19ba099e Merge branch 'bug-70950/Coodle_ICS_Organizer_falsch' 2026-03-03 10:44:55 +01:00
Johann Hoffmann db75cd2f62 also skip email loop/relevant abgaben loop when every occurance is filtered out to avoid empty notification emails; 2026-03-03 10:42:47 +01:00
Cristina c57eb1b8de Adapted method getLvLeitung: filter Dummy and allow only active Benutzer/Person 2026-03-02 11:00:05 +01:00
Harald Bamberger 28f4a38752 refactor helper function extendableApps to singleton helper class ExtendableAppsHelper and use it in FHC-Header and FHC-Footer, revert previous changes to other CI views 2026-02-27 16:50:50 +01:00
Andreas Österreicher 8495c74a7d Merge branch 'feature-61164/AbgabetoolQualityGates' 2026-02-27 10:48:35 +01:00
Harald Bamberger 43a37021a5 ensure extend_app js files from extensions are loaded directly before the apps js file 2026-02-27 09:24:47 +01:00
Johann Hoffmann abeb411742 betreuer email button config 2026-02-26 18:00:14 +01:00
Johann Hoffmann aa2334afe7 sammelmail button betreuer page; fix notenOpt retrieval in setDetailComponent for Betreuer when reopening detailView; $emit("paUpdated") after savingTermin/deletingTermin to update projektarbeit in overview table aswell; 2026-02-26 17:58:48 +01:00
Harald Bamberger 667a00d64b Merge branch 'master' into feature-68296/Vue_Router_via_Extensions_erweitern_ma0080 2026-02-26 16:05:32 +01:00
Harald Bamberger 4deed45f29 prepend extend_app js to customJSModules array, use FhcApps in Dashboard/Fhc App 2026-02-26 15:53:41 +01:00
Harald Bamberger 1ae072390e revert changes to add fhcApps property, not using path based syntax, to CI views include array 2026-02-26 15:27:52 +01:00
Andreas Österreicher 9eb2cb847d Merge branch 'feature-61164/AbgabetoolQualityGates' 2026-02-26 15:06:42 +01:00
Harald Bamberger 26fca87c75 refactor VueJs App magic into a helper function 2026-02-26 14:56:33 +01:00
ma0048 f3986688f2 selfoverview:
nur aktive kategorien anzeigen
uebersetzungen hinzugefuegt
2026-02-26 12:50:37 +01:00
Johann Hoffmann 859cb39a9d EmailJobs log & skip cases where no benutzer_uid email and no private email is available 2026-02-26 11:36:06 +01:00
Johann Hoffmann 4e2c3f7741 show qgate benotungsstatus of saved note, not currently selected note 2026-02-26 11:18:27 +01:00
ma0048 f1dbc6ab7d mc4 vorlage hinzugefuegt 2026-02-25 14:46:15 +01:00
Johann Hoffmann 325c84e6fe phrasen consistency "Short description of the submitted file" -> "Short description of the submitted document" + "Type of document submitted" 2026-02-25 13:31:00 +01:00
Johann Hoffmann 379880aef8 filter paabgabe uploads from newOrChanged job, since uploading a file still writes updateamum/updatevon fields -> compare student_uid with updatevon; when logging new paabgabe termine insert the whole paabgabe object into the logs, not just the result id; 2026-02-25 13:10:30 +01:00
Johann Hoffmann 16186bbee8 Merge branch 'master' into feature-61164/AbgabetoolQualityGates 2026-02-25 11:09:50 +01:00
Cristina d1015956d1 Merge branch 'master' into epic-56039/LV-Evaluierung 2026-02-25 10:54:29 +01:00
Cristina 726fce9fac Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-02-25 10:52:50 +01:00
Harald Bamberger ee0fa9f7d4 studvw reduce height of elements e.g:
- tabulator header filter
 - tabulator rows
 - form input and select
 - primevue autocomplete
 - primevue tabs
2026-02-24 17:23:50 +01:00
Harald Bamberger 7680a5c773 add bpk to api output if authuser has permission 2026-02-24 17:19:49 +01:00
Johann Hoffmann 1e827fffee additional erstbetreuer/zweitbetreuer name parts fetch & columns default invisible, columns next/prev termin header filter & custom sort func, list header filter for qgate 1/2 status assistenz & mitarbeiter, change all "Assessor" and "Assesor" phrasen to "Reviewer" 2026-02-24 15:58:44 +01:00
Harald Bamberger 0468b2b523 Merge branch 'master' into feature-68767/FHC4_Studierendenverwaltung_Details_4spaltig 2026-02-23 16:56:07 +01:00
Paolo d6108d816e Merge branch 'master' into hotfix-69228/DOCSBOX 2026-02-23 14:28:54 +01:00
Paolo f274b74ab1 Merge branch 'master' into feature-70440/Change_var_dump_to_error_log_to_show_the_referring_script 2026-02-23 14:25:40 +01:00
Paolo 029c51c2b2 Merge branch 'master' into bug-70950/Coodle_ICS_Organizer_falsch 2026-02-23 13:36:17 +01:00
Paolo 356a5fb51b Merge branch 'master' into bug-56209/is_valid_date_vs_isValidDate 2026-02-23 13:03:06 +01:00
Andreas Österreicher 9b114c5fb1 Merge branch 'feature-71344/LVEvaluierungZeitfenster' 2026-02-23 09:51:47 +01:00
Harald Bamberger 00fae2fa15 Merge branch 'master' into vv_und_studvw_2026_02_rc4 2026-02-23 09:28:54 +01:00
Johann Hoffmann 6c8eb9ac38 abgabetool dbupdate script check&insert new tbl_vorlage entry "PAANoSigAssSM" 2026-02-20 13:56:11 +01:00
Andreas Österreicher 2228b4d683 Sancho Header LV-Evaluierung 2026-02-20 13:29:01 +01:00
Johann Hoffmann 5558f6fc17 Signatur Sammelmail Job an Assistenz 2026-02-20 12:20:26 +01:00
kindlm 32fc029bd3 Merge remote-tracking branch 'origin/master' 2026-02-20 11:20:19 +01:00
kindlm f4e0516d89 Prüfung ob jede Fragen mindestens 2 Vorschläge hat auf Warning geändert
- Kleines Padding vor "Blättern"-Text
2026-02-20 11:20:09 +01:00
Harald Bamberger d98b7fd67a fix duplicates in lvplan for special groups 2026-02-19 18:34:27 +01:00
Johann Hoffmann 4b1a9fe892 avoid loading paabgaben a 2nd time for mitarbeiter; extracted getDateStyleClass from components; 2026-02-19 17:33:41 +01:00
ma0068 118dcbd252 remove testoutput 2026-02-19 15:45:34 +01:00
ma0068 d279f955a0 add emit-event for resetFilter 2026-02-19 15:12:38 +01:00
ma0068 1e8ec83965 add tileUid to StudentHeader, show Tiles only for selection of 1 student, just allow single selection of Mitarbeiter in MitarbeiterHeader 2026-02-19 11:57:28 +01:00
Harald Bamberger f2d49e02a7 Merge branch 'master' into vv_und_studvw_2026_02_rc4 2026-02-19 09:49:44 +01:00
Harald Bamberger 7169cb68a2 fix bug when sending multi messages introduced by loading time optimisation 2026-02-19 09:20:10 +01:00
Harald Bamberger f8da0b0915 Merge branch 'feature-69551/Einmeldeformular_als_VueJS_Component_fuer_LV-Evaluierung' 2026-02-19 07:46:15 +01:00
Alexei Karpenko f068b56083 PlausiIssueProducer: removed debugging output and die 2026-02-18 22:30:29 +01:00
Alexei Karpenko fa7a125727 Studierendenverwaltung archivieren: error message when no studentlehrverband found 2026-02-18 21:18:57 +01:00
Johann Hoffmann 4724008c2d betreuer page update table after adding serientermin qgate1/2 status prev/next; preserve scrollX/Y in betreuer/assistenz page 2026-02-18 14:32:57 +01:00
ma0068 34cd5d1a80 Filter List: only emit to updateURL if there is final dropdown result or change 2026-02-18 13:17:37 +01:00
Johann Hoffmann 6f28696556 getDateStyleClass evaluation also with precise luxon calculation on all pages; qgate12 status col, next/prev termin col on betreuer page; table persistence on mitarbeiter page; same rowheight on betreuer table as in assistenz to achieve similar UX; 2026-02-18 13:00:19 +01:00
Andreas Österreicher 6ec4737b22 Merge branch 'bug-71685/bewerbungstool_login_zugangscode' 2026-02-18 12:47:02 +01:00
Johann Hoffmann 328affa35c actually set deadline calculation to IANA timezone 'Europe/Vienna', so the code still works once Berlin moves to another timezone away from Austria. You never know. 2026-02-18 11:53:24 +01:00
ma0068 4b875bf019 also show filterActiveModule for HeaderFilters, change colour to red 2026-02-18 11:27:14 +01:00
Johann Hoffmann 90c845899f explicitely set deadline to end of day to achieve the desired "valid until 23:59" logic, instead of just moving the deadline by one day; endupload deadline is now optional by defining it as a "nachreichen möglich" aka non fixtermin; 2026-02-18 11:15:59 +01:00
Andreas Österreicher bb273d10bd Merge branch 'bug-71662/Bug_cancelVertrag_Berechtigungspruefung' 2026-02-18 10:50:59 +01:00
Johann Hoffmann a6daa7bf0c all abgabetool datepickers use date format via format="dd.MM.yyyy" instead of :format="formatDate" to enable text-input + autoapply; backend deadline datetime check for endupload; 2026-02-17 17:32:11 +01:00
ma0068 f0597e99e5 VV: update persistanceId 2026-02-17 16:51:56 +01:00
ma0048 1d8c4b7159 bug behoben, login wieder nur mit zugangscode moeglich 2026-02-17 16:49:09 +01:00
ma0068 f860fd3dc7 Studvw: update persistance_id for all tabs 2026-02-17 16:46:22 +01:00
Johann Hoffmann ee7254a964 assistenz preserve table state (selection, scroll) when adding serientermin; update isPastDate() function to luxon timezone safe logic; 2026-02-17 16:22:26 +01:00
ma0068 5ffd22c1f7 refactor last tabs from updateDefinition to setHeader variante 2026-02-17 16:11:43 +01:00
Alexei Karpenko c58674d133 Projektarbeiten cancelVertrag permission check bugfix (added array_column to get oes) 2026-02-17 15:15:30 +01:00
Harald Bamberger 006393704c Merge branch 'master' into vv_und_studvw_2026_02_rc4 2026-02-17 12:17:15 +01:00
Harald Bamberger 4825c75b5d revert changes made in commit b1a1cdf235 2026-02-17 12:11:37 +01:00
Harald Bamberger d82c186643 Merge branch 'master' into vv_und_studvw_2026_02_rc4 2026-02-17 11:23:18 +01:00
ma0048 2f51f18447 studierende in die gruppe ziehen ohne vorheriges selektieren 2026-02-17 11:16:44 +01:00
ma0048 5b34a226bd verbandsbaum nur toggeln und nicht automatisch selektieren 2026-02-17 11:09:54 +01:00
ma0068 1c69f3f654 VV: refactor Modal, change height of Table Unassigned Contracts 2026-02-17 10:31:45 +01:00
Harald Bamberger f6fd5ab678 Merge branch 'feature-71645/StudVw_MessageTab_Ladezeit' 2026-02-17 10:29:10 +01:00
Harald Bamberger 3d1aef617f add phrase error.opproject_does_not_exists in category kvp 2026-02-17 08:13:07 +01:00
Harald Bamberger e12b7e1ed5 add indexes for person_id to table msg_message and msg_recipient, ensure tabulator data request is made before requests of create msg components 2026-02-17 08:06:30 +01:00
ma0068 d9d3b1a245 VV: show Details und Status only if one Vertrag is selected 2026-02-17 07:58:03 +01:00
ma0068 ce27964df9 Detailheader VV and StudV: show - if no value for Tile 2026-02-16 16:46:46 +01:00
Harald Bamberger 0496eb7cc9 use union instead of or to avoid parallel seq scan 2026-02-16 15:56:40 +01:00
ma0068 556683574c Ignore typing inside editable elements for handling of keyboards event in function onKeydown 2026-02-16 15:44:01 +01:00
Harald Bamberger 962cbf4e78 join person table for sender and recipient instead of using subselect 2026-02-16 15:16:49 +01:00
Harald Bamberger 5415180b2c fetch count and paginated data in one query 2026-02-16 14:18:59 +01:00
ma0068 9d789d9a97 Tab Messages: remove unused computed statusText 2026-02-16 10:37:15 +01:00
ma0068 3d061df1d7 merge master into feature-68767/FHC4_Studierendenverwaltung_Details_4spaltig 2026-02-16 10:05:45 +01:00
Andreas Österreicher 827b6148a7 Merge branch 'feature-61164/AbgabetoolQualityGates' 2026-02-16 08:47:30 +01:00
Johann Hoffmann 3831f3c1d7 consistent use of :optionDisabled="getOptionDisabled" for paabgabetyp dropdowns in assistenz view 2026-02-16 03:41:30 +01:00
Johann Hoffmann 60294dd8f2 paBenotet evaluation fix 2026-02-16 03:22:39 +01:00
Andreas Österreicher 9d5adc1ed2 Merge branch 'feature-61164/AbgabetoolQualityGates' 2026-02-13 13:58:30 +01:00
Johann Hoffmann 632866c8c4 reset newTermin object when switching projektarbeit so they are assigned to the correct student 2026-02-13 13:45:12 +01:00
Andreas Österreicher 7f029ec8b5 Merge branch 'einspielen_12_02_2026' 2026-02-13 11:20:22 +01:00
ma0048 d9d15c1ed3 neue tag farben 2026-02-13 11:10:16 +01:00
Harald Bamberger a9b343646e Merge branch 'master' into vv_und_studvw_2026_02_rc4 2026-02-13 10:49:09 +01:00
ma0068 fd35d20955 refactor VV: change handling of selections, allow only strg for multiselect in vetraegen and for adding unassignedVertraege 2026-02-13 09:24:36 +01:00
Paolo 34b00f8dd6 cis/public/coodle.php now produces the correct ORGANIZER:MAILTO: 2026-02-12 21:44:12 +01:00
Johann Hoffmann 043b1bcf11 extracted email split method from stv/kontakt component to helperfile; adjusted that method to take subject param & make phrasen/alert call via parameter reference; 2026-02-12 17:38:00 +01:00
Johann Hoffmann 5c1e967d5e dont reset z-index on opening tiered menu (email button) by setting its autoZIndex property to false 2026-02-12 16:05:02 +01:00
Harald Bamberger 664b0a81bb use vilesci base url in combinePeople component 2026-02-12 15:52:11 +01:00
ma0068 aec0e5227f get selection after reload of added or updated contract, remove selection, stati and details after delete 2026-02-12 15:09:51 +01:00
Harald Bamberger fa807f37ae gehaltsbestandteil chart data: spezialfall neuer Gehaltsbestandteil und sofort valorisiert 2026-02-12 14:47:07 +01:00
Harald Bamberger 8f62d0d351 use correct category for phrase notiz_edit 2026-02-12 13:20:54 +01:00
Harald Bamberger e016deb042 add more space between download and delete button 2026-02-12 13:14:23 +01:00
Harald Bamberger ed170645df use plsql function public.get_rolle_prestudent instead of local sql 2026-02-12 11:27:50 +01:00
Andreas Österreicher 3a441228b8 Merge branch 'feature-61164/AbgabetoolQualityGates' 2026-02-12 11:07:36 +01:00
Andreas Österreicher 0a97e5781e Nicht beurteilt aus Default Config entfernt 2026-02-12 11:02:16 +01:00
ma0048 3465e299f7 tag - helper and formatter 2026-02-12 08:16:31 +01:00
Andreas Österreicher 136d6f9f28 Fix von BFI übernommen 2026-02-11 16:08:15 +01:00
Johann Hoffmann 67838eb630 load projektarbeit.note correctly for mitarbeiter; evaluate projektarbeit termin editability correctly and define a notenarray which does NOT count (currently "Nicht beurteilt" & "Noch nicht eingetragen"). such rules apply for betreuer, assistenz is allowed to do whatever they want since we never defined an actual business process anywhere and people do whatever they want anyways 2026-02-11 13:39:23 +01:00
Johann Hoffmann 609e226057 place email buttons inside a tiered menu (dropdown for some) to save space in the ui; 2026-02-10 14:25:45 +01:00
kindlm ffaff361b7 Merge remote-tracking branch 'origin/master' 2026-02-10 11:51:24 +01:00
kindlm d17206fe40 Admin-Seite: Padding bei Vorschau; Login Bugfix Fallback STG-Name 2026-02-10 11:51:02 +01:00
Andreas Österreicher 34e8b2e36d Merge branch 'feature-69180/AnwUID4CSV' 2026-02-10 11:14:39 +01:00
Andreas Österreicher fbea5a9306 Merge branch 'master' into feature-69180/AnwUID4CSV 2026-02-10 11:02:20 +01:00
Johann Hoffmann 6da19585ff optional sammelmail buttons assistenz abgabetool 2026-02-09 13:45:01 +01:00
ma0068 e13a7069dc Studverwaltung: refactor from Tabulator5 to 6, reformat some date entries 2026-02-06 13:18:09 +01:00
Andreas Österreicher f4ae8dd8e1 Korrektur zur Ermittlung der (legacy) Anwesenheit von BFI übernommen 2026-02-06 13:10:31 +01:00
ma0068 1cd332115b Changes Vertragsverwaltung
- refactor from Tabulator 5 to Tabulator 6
- not reloading contract list after changes of Status or Detail to keep row selection
- Start reselection of current row
2026-02-06 10:38:29 +01:00
ma0068 0bf9d8fa8a Adaptions Detailheader: center Title and Values for Tiles, change size for mitarbeiterDetailHeader 2026-02-05 14:50:20 +01:00
ma0068 464f04b254 merge studvw_2026_02_rc4 in vv_und_studvw_2026_02_rc4 2026-02-05 11:57:03 +01:00
ma0068 2a63b99816 handle emit redirectToLeitung in parent 2026-02-05 11:50:43 +01:00
ma0068 2aca2cd6ab Custom Filter: change colour to green for filter symbol 2026-02-05 09:55:07 +01:00
ma0068 ee619004bd refactor tabulatorevents to avoid updateDefinitions (Tabs Betriebsmittel, Funktionen, Messages, Notizen, Abschlusspruefung, Anrechnungen, Aufnahmetermine, Dokumente, Kontakt, Lehrveranstaltungstermine, Mobility, Prestudent, Pruefungen) 2026-02-05 09:41:15 +01:00
Johann Hoffmann 1eda652fba remove old code 2026-02-04 17:34:21 +01:00
Johann Hoffmann cc302ed5a1 lazyload signatur status for assistenz view to avoid worst case loading times due to 50 x 30mb signatur server payload 2026-02-04 17:32:17 +01:00
Andreas Österreicher f2308a32c8 Merge branch 'feature-61164/AbgabetoolQualityGates' 2026-02-04 11:37:57 +01:00
Johann Hoffmann c8cb484299 add missing email template public.tbl_vorlage inserts to checksystem script; checked template naming convention for higher case 2026-02-04 11:34:36 +01:00
ma0068 fc0fdc7909 Merge branch 'studvw_2026-02_rc4' of github.com:FH-Complete/FHC-Core into studvw_2026-02_rc4 2026-02-04 11:34:19 +01:00
ma0068 3053289146 Filter: change type filter Active, change position filter item, default values All Buchungstypen 2026-02-04 11:33:54 +01:00
Andreas Österreicher 7c67e65c9b Merge branch 'feature-61164/AbgabetoolQualityGates' 2026-02-04 11:11:59 +01:00
Johann Hoffmann a4dcf9e935 use phrase c4betrart + pa.betrart_kurzbz for betreuer/zweitbetreuer: text 2026-02-04 11:04:55 +01:00
Andreas Österreicher 6f99f493ea Merge branch 'feature-61164/AbgabetoolQualityGates' 2026-02-04 10:46:10 +01:00
Andreas Österreicher 023c2a10be Merge branch 'master' into feature-61164/AbgabetoolQualityGates 2026-02-04 10:21:17 +01:00
Harald Bamberger f6b13c0bdf Merge branch 'master' into studvw_2026-02_rc4 2026-02-03 17:16:42 +01:00
Harald Bamberger a7cd6c35f1 Merge branch 'feature-71399/Javscript_Caching_Problem_fhc-build-version_in_URL_und_mod_rewrite' 2026-02-03 16:29:05 +01:00
ma0068 e0082db7c9 Tab Aufnahmetermine: add context self to computed properties and adapt name of 2 variables, Tab Lehrveranstaltungstermine: add space 2026-02-03 16:16:18 +01:00
Harald Bamberger 87ff7acef0 use absoluteJsImportUrl helper instead of APP_ROOT constant to build js components file path 2026-02-03 14:27:02 +01:00
ma0068 936858948b merge bug-71363/FHC4_Stvw_Refactor_TabulatorOptions_As_Computed into origin/studvw_2026-02_rc4 2026-02-03 14:15:58 +01:00
ma0068 18c949eed4 refactor tabulator options and events into computed section: Tabs Betriebsmittel, Abschlusspruefung, Anrechnungen, Aufnahmetermine, Kontakt, Prestudent, Status, bugfix Lehrveranstaltungstermine: sorter for Lektor as string 2026-02-03 13:57:30 +01:00
Harald Bamberger d192489c6f use correct filename in comment 2026-02-03 13:52:04 +01:00
Harald Bamberger 7028fe0ac8 Merge branch 'master' into feature-71399/Javscript_Caching_Problem_fhc-build-version_in_URL_und_mod_rewrite 2026-02-03 13:49:48 +01:00
Harald Bamberger a3a03f6362 update check system to create or update widget path to start with public/... 2026-02-03 13:49:06 +01:00
Harald Bamberger 82f0f3f5e3 Merge branch 'bug-71363/FHC4_Stvw_Refactor_TabulatorOptions_As_Computed_Part1' into studvw_2026-02_rc4 2026-02-03 13:39:59 +01:00
Harald Bamberger 8b9601502a Merge branch 'bug-71363/FHC4_Stvw_Refactor_TabulatorOptions_As_Computed' into studvw_2026-02_rc4 2026-02-03 13:38:28 +01:00
ma0068 888bb1c7c0 Merge branch 'master' into bug-71363/FHC4_Stvw_Refactor_TabulatorOptions_As_Computed_Part1 2026-02-03 13:26:04 +01:00
ma0068 372c932c47 Merge branch 'master' into bug-71363/FHC4_Stvw_Refactor_TabulatorOptions_As_Computed 2026-02-03 13:16:17 +01:00
Johann Hoffmann 6391bf5a45 tippfehler in phrase "c4tooltipStandard" ausgebessert: 'Termin mehr als 12 Tag entfernt' => 'Termin mehr als 12 Tage entfernt' 2026-02-03 12:52:25 +01:00
Johann Hoffmann d774335bcf assistenz view query now also checks for betreuerart_kurzbz ("Erstbegutachter", "Begutachter", "Betreuer", "Erstbetreuer", "Senatsvorsitz") instead of only ("Erstbegutachter", "Begutachter") 2026-02-03 12:35:06 +01:00
Harald Bamberger 69749da331 Merge branch 'master' into feature-52533_62055/Vertragsverwaltung_mit_CoreComponent_DetailHeader 2026-02-03 11:46:19 +01:00
Andreas Österreicher b4f28d5426 Abstract zum Default Config für Betreuer hinzugefügt 2026-02-03 11:12:50 +01:00
Harald Bamberger 0442a3da0a Merge branch 'bug-71363/FHC4_Stvw_Refactor_TabulatorOptions_As_Computed' into studvw_2026-02_rc4 2026-02-03 10:58:24 +01:00
Harald Bamberger 2492a4fc06 Merge branch 'bug-70848/FHC4_Studierendenverwaltung_Notiz_handleVisibleColumns_pp' into studvw_2026-02_rc4 2026-02-03 10:57:38 +01:00
Harald Bamberger 9ae9feb9ea Merge branch 'bug-69548/FHC4_Studierendenverwaltung_Aufnahmetermine_Gesamtnote_berechnen' into studvw_2026-02_rc4 2026-02-03 10:48:06 +01:00
Harald Bamberger a535fd85cd Merge branch 'feature-69516/studvw_verbandsbaum_zu_ausklappbar_machen' into studvw_2026-02_rc4 2026-02-03 10:47:31 +01:00
Harald Bamberger 269860252e Merge branch 'feature-69710/FHC4_Studierendenverwaltung/Filterverhalten_bei_Aenderungen' into studvw_2026-02_rc4 2026-02-03 10:46:57 +01:00
Harald Bamberger d0faba03a2 Merge branch 'feature-39571/Studierendenverwaltung_CoreNotizcontroller' into studvw_2026-02_rc4 2026-02-03 10:43:39 +01:00
ma0068 88a06194d4 Merge branch 'master' into bug-70848/FHC4_Studierendenverwaltung_Notiz_handleVisibleColumns_pp 2026-02-03 10:36:13 +01:00
Andreas Österreicher 3e1b9865b1 Merge branch 'master' into feature-61164/AbgabetoolQualityGates 2026-02-03 10:33:54 +01:00
Andreas Österreicher 3534118261 Merge branch 'feature-71355/constructor_config_bewerbungstool_datenschutz' 2026-02-03 08:50:20 +01:00
Harald Bamberger 5d73f051ba sample .htaccess to use with config option use_fhcomplete_build_version_in_path 2026-02-03 08:13:57 +01:00
Harald Bamberger 85a10e27cc fix setFirstStudent if GENERATE_ALIAS_STUDENT is false 2026-02-02 17:59:15 +01:00
ma0068 8c22a652fa merge master into bug-71363/FHC4_Stvw_Refactor_TabulatorOptions_As_Computed 2026-02-02 17:24:36 +01:00
ma0068 a70e25d0e8 Merge branch 'master' into feature-69516/studvw_verbandsbaum_zu_ausklappbar_machen 2026-02-02 16:48:02 +01:00
ma0068 e689531224 merge master into bug-69548/FHC4_Studierendenverwaltung_Aufnahmetermine_Gesamtnote_berechnen 2026-02-02 16:31:13 +01:00
ma0068 3ab1a002f0 Merge branch 'master' into feature-69710/FHC4_Studierendenverwaltung/Filterverhalten_bei_Aenderungen 2026-02-02 16:24:51 +01:00
ma0068 b9eaac18b0 merge Master into feature-39571/Studierendenverwaltung_CoreNotizcontroller 2026-02-02 16:21:47 +01:00
ma0068 b26df9ac21 Tab Kontakt: Bankaccount: move tabulator options to computed, fix bug height 2026-02-02 11:48:02 +01:00
ma0068 0539281adf Messages: move tabulator options and event to computed 2026-02-02 11:36:03 +01:00
Johann Hoffmann 1b35569797 Merge branch 'master' into feature-69180/AnwUID4CSV 2026-02-02 10:22:10 +01:00
ma0068 e01d814ae9 Tab Dokumente: move tabulator options and event to computed 2026-02-02 09:44:47 +01:00
Harald Bamberger 77abcb6129 use absoluteJsImportUrl in Dashboard Widget Api Endpoints, send widget setup and arguments column values as json to frontend, remove JSON.parse from frontend dashboard code 2026-01-30 18:58:20 +01:00
Harald Bamberger 63f198098d use absoluteJsImportUrl Helper for calendar Event renderers 2026-01-30 18:55:25 +01:00
Harald Bamberger f7478ff05c add config to insertr fhc-build-version into path or add it as query string 2026-01-30 18:53:31 +01:00
ma0068 99ea6ad333 - moved tabulator options to computed
- removed unused change param
- added values to resetModal
2026-01-30 14:26:32 +01:00
Johann Hoffmann 366cb16b61 anw phrasen "studentByLVATitle" & "kontrolliertVon", slight adjustment of fullscreen modal button so it looks similar 2026-01-30 14:10:28 +01:00
ma0068 683626921b Tab Mobility: moved tabulator options to computed 2026-01-30 13:21:40 +01:00
ma0068 326d4b3923 Revert "refactor in computed section: Tabs Betriebsmittel, Abschlusspruefung, Anrechnungen, Aufnahmetermine, Kontakt, Prestudent, Status, bugfix Lehrveranstaltungstermine: sorter for Lektor as string"
This reverts commit f2107a377f.
2026-01-30 10:31:38 +01:00
ma0068 f2107a377f refactor in computed section: Tabs Betriebsmittel, Abschlusspruefung, Anrechnungen, Aufnahmetermine, Kontakt, Prestudent, Status, bugfix Lehrveranstaltungstermine: sorter for Lektor as string 2026-01-30 10:29:19 +01:00
Johann Hoffmann fbe10cc2a1 PersonModel loadAllStudentUIDSForPersonID used in anw extension AdministrationApi aka Entschuldigungsmanagement 2026-01-29 15:08:24 +01:00
ma0048 783c4fc5f8 constructor warning config hinzugefuegt
testtool englisch uebersetzung datenschutz hinzugefuegt
2026-01-29 08:15:35 +01:00
Harald Bamberger f1aa5382cf check editZgv Permission for Stg and also check it in api function 2026-01-28 17:04:11 +01:00
ma0068 e3b630550a delete comment 2026-01-28 14:42:26 +01:00
ma0068 8903fa878c - more prominent view of Active Custom Filter
- one click filterreset
- fhc search bar: resetFilter with submit
2026-01-28 13:33:01 +01:00
Harald Bamberger 7fe36d59e3 apply edit Zgv permissions only to ZGV dropdowns 2026-01-28 11:32:03 +01:00
kindlm c724c6a20f MathML auf Darstellungs-Testseite überarbeitet 2026-01-27 16:53:33 +01:00
kindlm b9bfa5c3c5 Merge remote-tracking branch 'origin/master' 2026-01-27 16:52:16 +01:00
Johann Hoffmann 101613ecdd detail view infos - student: {student} titel: {titel} betreuer: {betreuer} 2026-01-27 14:47:51 +01:00
Johann Hoffmann edd0c46186 target blank on students stg moodle link; added new classes to assistenz table cell formatters 2026-01-27 11:50:29 +01:00
Johann Hoffmann 07dd9e3a77 abgabedatum logic fix in dateStyles 2026-01-27 11:31:56 +01:00
Johann Hoffmann 06139b14d6 bestanden style from purple to green 2026-01-27 11:25:41 +01:00
Harald Bamberger 3e46e94736 quick fix to prevent pruefunglist from being empty due to js error in combination with tabulator sort persistence 2026-01-27 11:07:46 +01:00
Johann Hoffmann fc468ca34a URL_ASSISTENZ for links in email jobs 2026-01-27 10:52:15 +01:00
Johann Hoffmann 84db668566 compare notenOpt in student view if necessary for datestyle 2026-01-27 10:30:00 +01:00
Johann Hoffmann 3c82cd1282 icon template statusses 2026-01-27 09:58:48 +01:00
Johann Hoffmann 709f64e292 2 new dateStyle status regarding QG benotung 2026-01-27 09:31:14 +01:00
ma0068 5dcf8bb854 add showVariables.showErledigt to tabulatorOptions 2026-01-26 15:11:00 +01:00
Johann Hoffmann 709aba5783 Merge branch 'master' into feature-61164/AbgabetoolQualityGates
# Conflicts:
#	application/models/organisation/Studiengang_model.php
2026-01-26 15:06:22 +01:00
Harald Bamberger afc4544304 use showVariables properties directly in tabulatorOptions and tabulatorEvents moved to computed, so they are used only if user has not customized columns visibility in localstorage 2026-01-26 14:09:07 +01:00
ma0048 0a2afadb0a tagheaderfilter bug fix 2026-01-26 13:21:20 +01:00
Cristina 27a91de5f6 Added app lvevaluierung to system.tbl_app 2026-01-22 15:51:05 +01:00
Cristina 7ccc26c878 Added lvevaluierung phrasen for STGL Übersichtsseite 2026-01-22 15:41:25 +01:00
Cristina 9ebc847e8e Added lvevaluierung phrasen for Lektoren Übersichtsseite 2026-01-22 14:59:00 +01:00
Cristina 511b04c1f8 Merge branch 'master' into epic-56039/LV-Evaluierung 2026-01-21 18:01:55 +01:00
Cristina ec90d35e02 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-01-21 18:01:24 +01:00
Harald Bamberger f867e60702 fix use of config FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE to override studiengang_kz in public.tbl_konto 2026-01-21 17:37:23 +01:00
Johann Hoffmann 668f0a6618 fixed betreuerart bezeichnung formatting discrepancy between first and second assesor 2026-01-21 16:26:26 +01:00
Andreas Österreicher ef8314c33a Config to check Extension LVEvaluierung is enabled 2026-01-21 15:32:52 +01:00
Johann Hoffmann 48cd37058e also block uploads and termin changes for projektarbeiten with a note on backend 2026-01-21 14:53:44 +01:00
Andreas Österreicher e4ebdd59b6 Merge branch 'epic-56039/LV-Evaluierung' 2026-01-21 14:51:24 +01:00
Johann Hoffmann 4d97127539 remove Abgabedatum column from Assistenz/Betreuer update sammelmail. Keep it for UPLOADS sammelmail since it is relevant there; defined relevant_types in abgabetool config to filter for in the sammelmail for each role student/assistenz/betreuer; block saving/deleting/uploading ui components when projektarbeit has a note, since this indicates that the project is over; 2026-01-21 14:05:31 +01:00
Andreas Österreicher d1cc7244f7 Merge branch 'feature-70999/bewerbungstool_datenschutz_checkbox' 2026-01-21 10:56:54 +01:00
Johann Hoffmann c9bcf9b9b0 fixed note init by object/object key on 2nd time opening the details modal in the assistenz view; 2026-01-21 10:34:17 +01:00
ma0048 2f5b90b9d5 dsgvo confirm und proctoring confirm beim RT Login 2026-01-21 09:04:11 +01:00
Cristina 9b90e0edde Merge branch 'master' into epic-56039/LV-Evaluierung 2026-01-20 10:53:36 +01:00
Cristina 56e9b253d2 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-01-20 10:52:23 +01:00
Cristina c5c7123358 Added lvevaluierung phrase 2026-01-20 10:51:49 +01:00
Johann Hoffmann 2471d37dd3 fix loginfo statements betreuer->assistenz 2026-01-19 16:54:10 +01:00
Johann Hoffmann ad7808eb21 fix typo in speed dial disabled computed (based on being a zweitbegutachter 2026-01-19 16:49:03 +01:00
Johann Hoffmann 9a07e7c804 wrote Studiengang_model.php -> getAssistenzForStudiengangKZ() that does just that but is not used currently since we retrieve assistenz in AbgabetoolJob.php via oe_kurzbz; added new getAssistenzForOE() method in Organisationseinheit_model; added new job "notifyAssistenzAboutChangedAbgaben" that does just that to AbgabetoolJob.php; removed console.log/debugger statements in cis4 code; 2026-01-19 16:12:54 +01:00
Cristina 50e93fc9ba Fixed wrong configs (restored CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN + removed double CIS_EVALUIERUNG_ANZEIGEN_STG) 2026-01-19 13:33:12 +01:00
Andreas Österreicher 47ea1e848c Merge branch 'feature-69528/reihungstestueberwachung_constructor' 2026-01-19 10:17:38 +01:00
ma0048 e0f99a8e88 gewichtung und regeln in die config verschoben 2026-01-19 08:28:25 +01:00
Johann Hoffmann 6c82741341 remove var_dump() statement 2026-01-16 12:00:30 +01:00
Johann Hoffmann c3f7f7223a add student name info to betreuer sammelemail jobs table; WIP adapting same logic for assistenz; 2026-01-16 11:59:46 +01:00
Johann Hoffmann fbd0a4685e fix jobs & fancy formatting; check paabgabetyp instead of bezeichnung to enable enduploads for users in english lmao 2026-01-15 18:40:51 +01:00
Harald Bamberger 63aebde7f2 Merge branch 'bug-70906/FHC4_Archive_Dokument_Studienbestaetigung' 2026-01-15 18:01:25 +01:00
ma0068 62f5b66324 add missing parameters studiensemester and studiengang_kz for document Studienbestaetigung and StudienbestaetigungEnglish 2026-01-15 17:24:38 +01:00
Harald Bamberger ef08e39449 api endpoint student: prevent storing an empty string as alias e.g. from StudVw Details Tab 2026-01-15 17:09:30 +01:00
Harald Bamberger c720c46125 education/Projektarbeit_model: fix missing from-clause entry for table tbl_projektarbeit error - ticket#6059687 2026-01-15 16:28:38 +01:00
Harald Bamberger 597d4dbfec Abschusspruefung Modal add model-type to datepicker to prevent sending full utc timestamp to backend 2026-01-15 11:37:51 +01:00
Johann Hoffmann eb15d6b841 getStudentConfig Api Method; moodle link config entry; write abgabetool termin noten into header; uniform getDateStyleClass logic in all 3 views; WIP refining AbgabetoolJob; 2026-01-14 16:57:57 +01:00
ma0048 d67cad925d externe ueberwachung deaktivieren ueber config
params in die config verlagert
2026-01-14 13:59:42 +01:00
Johann Hoffmann bbb90f6dc4 added fixtermin variable to Paabgabe->update() statement; email logic for sancho emails towards betreuer: return $email[0]->uid ? $email[0]->uid.'@'.DOMAIN : $email[0]->private_email; phrasen wordings; reworked assistenz config api promises as allSettled to avoid race conditions; nachreichen möglich is always the default everywhere; WIP enabling the same status logic workflow everywhere; 2026-01-13 18:20:05 +01:00
Harald Bamberger 2d9e9df8a0 fix notiz component showing no data when setting sort an switching tabs in stv 2026-01-13 14:10:33 +01:00
Cristina 6d6659f6e5 Merge remote-tracking branch 'origin/epic-56039/LV-Evaluierung' into epic-56039/LV-Evaluierung 2026-01-13 13:39:21 +01:00
Cristina 6512ad0f1c Merge branch 'master' into epic-56039/LV-Evaluierung 2026-01-13 13:38:04 +01:00
Cristina f034a99928 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2026-01-13 13:37:43 +01:00
Johann Hoffmann e89fcbab31 phrase typo fix 2026-01-13 13:05:58 +01:00
Johann Hoffmann 7c1f239dcb configurable paabgabe types for signature check; finetuned signature response message; phrasen & code cleanup; 2026-01-13 12:32:41 +01:00
Johann Hoffmann cc0f38b276 fix the comment describing the "fix" 2026-01-12 17:14:03 +01:00
Johann Hoffmann a56335f4f9 "fix" the signatur check 2026-01-12 17:11:48 +01:00
Johann Hoffmann 954c55ba3e finetuning 2026-01-12 17:06:35 +01:00
Johann Hoffmann c7250959d0 Merge remote-tracking branch 'origin/feature-61164/AbgabetoolQualityGates' into feature-61164/AbgabetoolQualityGates 2026-01-12 12:52:31 +01:00
Johann Hoffmann 6c8318ead2 wip 2026-01-12 12:51:34 +01:00
Andreas Österreicher 3095f7ea8b Notice für UID entfernt 2026-01-12 10:44:57 +01:00
Andreas Österreicher 8f98d0c5a1 Fixed UID 2026-01-12 10:31:50 +01:00
Johann Hoffmann 13232015c3 more sophisticate zuordnung check & place it in every sensitive API endpoint; WIP: check STGentitlement when querying projektarbeiten for certein stg, since only dropdown info is pulled with this berechtigungslogic in mind but not the fetch itself; 2026-01-09 14:13:26 +01:00
Johann Hoffmann db861e81b2 rewrote post param acces from $id = $_POST['id'] to $id = $this->input->post('id') and subsequently rewrote safety checks from !isset($id) || isEmptyString($id) to $id === NULL || trim((string)$id) === '' to avoid ASCII conversion of low integers when passing them to isEmptyString function 2026-01-08 17:45:02 +01:00
Johann Hoffmann 7eb147085f typo fix in getDateStyleClass; fix selectAll button in Assistenz view; change the upload_allowed checkbox on change as expected; give fhcAlert primevue btn classes instead of bootstrap so they actually get applied; save convert js date to iso string to avoid timezone shenanigans; created zusatzdaten edit phrase; 2026-01-08 16:05:24 +01:00
ma0068 4f104523ff - include directive primevue.tooltip
- refactor phrases to avoid timing problem with loading phrases of alert
2026-01-08 16:02:29 +01:00
Johann Hoffmann 80175f46cb typo fix in getDateStyleClass; fix selectAll button in Assistenz view; 2026-01-08 14:40:24 +01:00
Johann Hoffmann 3d82d69bfc fixed student_uid variable aquisition inside StudentComponent; No allowedToSave check in client for Betreuer at all, everything done at backend level (WIP); added legacy phrasen to phrasesupdate to guarantee their existence; 2026-01-08 13:40:58 +01:00
ma0048 40ae57fb0c proctoring check ueberarbeitet 2026-01-08 12:01:20 +01:00
Andreas Österreicher f845809e6b Fixed Variable Check in Abgabetool 2026-01-07 16:02:06 +01:00
Paolo 1ce362b66b Removed forgotten error_log 2026-01-07 15:54:59 +01:00
Harald Bamberger c113c80862 fix calculation of next student matrikelnr aka personenkennzeichen and student uid 2025-12-22 21:11:05 +01:00
ma0068 02153e469f Dashboard Admin Cleanup
- refactoring Api: FHC-API controller for Edit/Update, widgets and presets
- delete dashboard with Prompt
- phrases
2025-12-19 11:39:31 +01:00
Andreas Österreicher 063cbcbf4f Merge branch 'feature-62775/reihungstesttool_firefox_check_entfernen' 2025-12-19 09:50:15 +01:00
Paolo 47d4b2e2d4 Change var_dump_to_error_log to show the referring script -> tail -f /var/log/apache2/error.log | grep <user> can catch it 2025-12-18 13:20:08 +01:00
Andreas Österreicher 7e6805ca98 Merge branch 'master' into epic-56039/LV-Evaluierung 2025-12-18 13:18:16 +01:00
Cristina 871534af52 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-12-18 13:07:27 +01:00
Andreas Österreicher 67b03dd29f ReAdded Lost Phrases 2025-12-18 12:55:08 +01:00
Harald Bamberger 0616236e00 bugfix: ZGV Übernahme bei Interessentenanlage, bestehende ZGVs die null sind ausfiltern 2025-12-18 12:48:08 +01:00
Andreas Österreicher 47e3c83909 Merge branch 'master' into feature-61164/AbgabetoolQualityGates 2025-12-18 12:25:05 +01:00
Cristina 4dd4d8aaa5 Removed filtering aktiv studienganege from method to get Studiengaenge by Stgs
otherwise when switching to former semester (which will have inactive studiengaenge) it will not appear
2025-12-17 14:35:24 +01:00
Cristina f9ac824cc0 Added LV-Evaluierung NEU link button to CIS LV Menu 2025-12-17 14:33:04 +01:00
Harald Bamberger 79ad8601da Merge branch 'feature-68763/CIS4_Profilupdate_Additional_Changes' 2025-12-17 13:35:59 +01:00
Harald Bamberger 6b0526fb95 add tabulator persistence config 2025-12-17 13:22:39 +01:00
Harald Bamberger 39d708aa61 Merge branch 'master' into feature-68763/CIS4_Profilupdate_Additional_Changes 2025-12-17 12:56:07 +01:00
Harald Bamberger becbe5823c Merge branch 'feature-69286/StudStatusWiedereinstiegsmail_an_Studierende' 2025-12-16 16:16:29 +01:00
Harald Bamberger ddfcef9ad7 log Error if mail can not be sent, only change status if both reminder emails were successfully sent 2025-12-16 15:52:44 +01:00
Harald Bamberger 4f5e49a93c send to all private email addresses marked as zustellung 2025-12-16 15:27:31 +01:00
Harald Bamberger a3b5718422 Merge branch 'master' into feature-69286/StudStatusWiedereinstiegsmail_an_Studierende 2025-12-16 07:43:45 +01:00
Cristina db048e876c Renamed getEntitledStgs to getByStgs
Permissions check happens in application controller.
2025-12-15 16:48:07 +01:00
Harald Bamberger a4be020156 Merge branch 'feature-68768/Studierendenstatus_Neue_Abmeldungsgruende' 2025-12-15 16:36:16 +01:00
Harald Bamberger 2149ed2384 Merge branch 'master' into feature-68768/Studierendenstatus_Neue_Abmeldungsgruende 2025-12-15 16:27:57 +01:00
Cristina e6ef234c8b Added method getOrgformsByStg to Studiengang_model.php
Get OrgForms of given Studiengang and Studiensemester
2025-12-15 16:27:47 +01:00
Harald Bamberger 29c8e6fb19 Merge branch 'master' into feature-69286/StudStatusWiedereinstiegsmail_an_Studierende 2025-12-15 16:27:25 +01:00
Harald Bamberger cf7e9921b5 change grades sort order 2025-12-15 16:11:46 +01:00
Harald Bamberger 887d9f9cbd Merge branch 'feature-69877/StudVw_Status_GrundAndAnmerkungEditable' 2025-12-15 15:31:52 +01:00
Harald Bamberger 7de3c4a24e remove unnecessary line 2025-12-15 15:22:32 +01:00
Harald Bamberger 11ff26d8e7 remove empty lines 2025-12-15 15:20:19 +01:00
Harald Bamberger 718272e8a1 remove empty line 2025-12-15 15:13:53 +01:00
Harald Bamberger 3f891179aa move check for critical changes bis from frontend to backend 2025-12-15 15:12:49 +01:00
kindlm 2a84999e56 Merge remote-tracking branch 'origin/master' 2025-12-15 14:39:47 +01:00
Andreas Österreicher 56ef700ec8 Merge branch 'feature-69439/negative_stunden_im_neuen_kartereiter' 2025-12-15 14:27:27 +01:00
Harald Bamberger afc3cd0131 Merge branch 'master' into feature-69877/StudVw_Status_GrundAndAnmerkungEditable 2025-12-15 13:53:28 +01:00
Harald Bamberger 5536408065 add property stg_kz to json of org_forms to prevent clearing tabulator when changing form a node with stg_kz property set to an orgform_node 2025-12-15 13:35:50 +01:00
Johann Hoffmann 756a51defa selectable check during selectAll to block it for Zweitbetreuer -> custom formatted/handled selection column for mitarbeiter & assistenz; custom sticky-col css; 2025-12-15 13:16:12 +01:00
ma0048 5a77478071 insertvon entfernt 2025-12-15 12:27:17 +01:00
Harald Bamberger 293a8625e4 change sort order in grades list api endpoint 2025-12-15 12:03:41 +01:00
Harald Bamberger 5266a6fe4d Merge branch 'master' into feature-69877/StudVw_Status_GrundAndAnmerkungEditable 2025-12-12 16:28:35 +01:00
Harald Bamberger 3485ee624c Merge branch 'studvw_2025-12_rc3' 2025-12-12 15:22:24 +01:00
Harald Bamberger 61c859f2e1 Merge branch 'bugfix-69874/Dokument_Ausbildungsvertrag_ohneParamUid' into studvw_2025-12_rc3 2025-12-12 15:06:49 +01:00
Harald Bamberger b967f83dd4 skip adding uid to params for templates Ausbildungsver and AusbVerEng instead of deleting it afterwards 2025-12-12 15:05:37 +01:00
Harald Bamberger ad184f5c16 change projektbetreuer tabulator layout, use correct phrases for columns person_id and punkte 2025-12-12 14:37:44 +01:00
ma0068 34d6b2d97a use only prestundent_id in Archive-functionality 2025-12-12 14:36:02 +01:00
Johann Hoffmann 735a6654b9 projektbeurteilung_check_available event when loading studentprojektarbeiten handled in extension 2025-12-12 13:45:01 +01:00
ma0068 431ae8ddac - make button edit editable
- set field anmerkung editable (like statusgrund and statusgrund)
- refactor function updateStatus to skip validation
- change phrases
2025-12-12 13:04:58 +01:00
Johann Hoffmann 635da9f8d9 checksystem paabgabetyp default values for upload_allowed, benotbar & aktiv only on first checksystem run by checking availability of qgate2 typ; english phrasen for betreuerart, paabgabetyp & projekttyp; disable new termin for zweitbetreuer (WIP disabling serientermin); QGate1/2 Status column -> text only for now; 2025-12-12 12:51:07 +01:00
Harald Bamberger 0072d87f3b Merge branch 'bug-69804/FHC4_StudVw_Mobility_showAddedZweckAndGrund' into studvw_2025-12_rc3 2025-12-11 16:41:43 +01:00
ma0068 d91789aee5 Aufruf Ausbildungsvertrag mit Param prestudent-id 2025-12-11 16:20:09 +01:00
Cristina 8280ec42b0 Added method getEntitledStgs to Studiengang_model.php
Get active Studiengänge with Kuerzel by given Studiengang-Kennzahlen. Helpful to easily get Studiengänge the user is entitled for.
2025-12-11 16:07:07 +01:00
Harald Bamberger d8766e8f7a Merge branch 'feature-69065/Projektarbeiten_Firmen_verwalten' into studvw_2025-12_rc3 2025-12-11 16:06:28 +01:00
Alexei Karpenko 91f141326a Studierendenverwaltung Projektarbeiten PRojektbetreuer: replaced "formdata modified" check with edit mode check 2025-12-11 15:38:53 +01:00
ma0068 a6907d1bc5 - bugfix delete Purpose
- reload local data after pushing new entries in Purpose and Support
2025-12-11 14:20:22 +01:00
Harald Bamberger 95027937bd remove debug code 2025-12-11 12:52:05 +01:00
Harald Bamberger a86d35f731 Merge branch 'master' into feature-69065/Projektarbeiten_Firmen_verwalten 2025-12-11 12:12:05 +01:00
Alexei Karpenko 1c511f9c66 Projektarbeit controller: added comments 2025-12-11 11:42:31 +01:00
ma0068 f40f554c6b add logic for config FAS_REIHUNGSTEST_EXCLUDE_GEBIETE 2025-12-11 10:53:15 +01:00
ma0048 b4668aa6bc verbandsbaum zu/ausklappbar 2025-12-11 08:58:05 +01:00
ma0048 df639c8b07 sprache mitschicken 2025-12-11 08:28:01 +01:00
Alexei Karpenko 80f80ab8e8 added comments to Projektbetreuer 2025-12-10 19:43:15 +01:00
Alexei Karpenko 32b73b7287 Studierendenverwaltung Projektarbeiten: delete checks bugfixes, layout guidelines 2025-12-10 18:03:04 +01:00
Johann Hoffmann eade9b7beb fixed accordion header padding size; student sees public mail, lektor gets notifs to private; remove unused injections; rewrite viewData validation for old Cis to remove console.warnings; clear abgabetermin.kurzbz when changing to smth not quality gate to avoid leaky kurzbz; fixed accordion header style offset for both cis environments; tooltip fix; only show abgabedatum if termin has upload_allowed; lower max-width in old cis; activated custom persistence for assistenz page + stricter promise handling around tableBuilt; activeIndex Handling on Student Page in case of several Projektarbetien; Phrasen gendering; 2025-12-10 17:41:01 +01:00
Alexei Karpenko 98bcbda53e added check for Projektarbeitsbeurteilung when deleting Projektarbeit 2025-12-10 16:09:44 +01:00
Harald Bamberger ba1f3da02f Merge branch 'master' into studvw_2025-12_rc3 2025-12-10 15:35:58 +01:00
Harald Bamberger 994d523258 Merge branch 'feature-69451/FHC4_Studierendenverwaltung/BerechtigungenZGVs' 2025-12-10 15:29:07 +01:00
Harald Bamberger 213f20eab3 Merge branch 'feature-69451/FHC4_Studierendenverwaltung/BerechtigungenZGVs' into studvw_2025-12_rc3 2025-12-10 15:20:27 +01:00
Harald Bamberger 2bb58e24cc fix timing to prevent zgv autocomplete fields from being empty when switching from and to prestudent tab 2025-12-10 15:18:16 +01:00
ma0048 53cf777970 check im menu entfernt 2025-12-10 15:18:15 +01:00
ma0048 48512f46ab exam name geandert 2025-12-10 15:15:23 +01:00
Harald Bamberger da78332a92 Merge branch 'feature-69451/FHC4_Studierendenverwaltung/BerechtigungenZGVs' into studvw_2025-12_rc3 2025-12-10 14:50:56 +01:00
Harald Bamberger 83a76d06b6 Merge branch 'master' into studvw_2025-12_rc3 2025-12-10 14:16:46 +01:00
Harald Bamberger cfd24dd8bc Merge branch 'feature-69452/studvw_status_aktion_vorruecken_ausblenden_via_config' 2025-12-10 14:07:45 +01:00
Harald Bamberger ea5d2bc6f8 Merge branch 'master' into studvw_2025-12_rc3 2025-12-10 13:50:20 +01:00
Harald Bamberger 8468d881f1 Merge branch 'feature-69517/FHC4_Abschlusspruefung_Pruefungsprotokolltext' 2025-12-10 13:40:59 +01:00
Harald Bamberger 5041999b4b Merge branch 'master' into feature-69517/FHC4_Abschlusspruefung_Pruefungsprotokolltext 2025-12-10 13:34:52 +01:00
ma0068 1176c8d6e4 - use studiengang_kz and studiengangkurzbz of studienordnung of persontRT
- add check for existing studiengang
- use studiengang_kz instead studiengangkurzbz for filter and background green
2025-12-10 09:49:00 +01:00
ma0048 8bab5285e9 testversuch ueber config
abfrage gefixed
menu wird nicht mehr angezeigt
2025-12-10 08:08:46 +01:00
Cristina 76cdaefdc7 Merge branch 'master' into epic-56039/LV-Evaluierung 2025-12-09 17:06:06 +01:00
Johann Hoffmann bb689a6d48 Merge branch 'master' into feature-61164/AbgabetoolQualityGates
# Conflicts:
#	public/css/Cis4/Cis.css
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2025-12-09 17:03:18 +01:00
Harald Bamberger 033af68343 teleport datepicker out of modal 2025-12-09 17:01:30 +01:00
Cristina f725594f0c Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-12-09 17:00:24 +01:00
Harald Bamberger f460a909d9 Merge branch 'feature-69438/FHC4_Studierendenverwaltung/FeedbackPunkte' into studvw_2025-12_rc3 2025-12-09 16:37:16 +01:00
Harald Bamberger 054574f9fb Merge branch 'feature-63468/Studierendenverwaltung_Neuanlage_von_Interessenten_ueberarbeiten' into studvw_2025-12_rc3 2025-12-09 16:35:45 +01:00
ma0048 597aa1aa4e status vorruecken ueber config steuerbar
statusgrund kann wieder entfernt werden
2025-12-09 12:36:08 +01:00
Harald Bamberger 7c57f5a308 Merge branch 'master' into feature-69438/FHC4_Studierendenverwaltung/FeedbackPunkte 2025-12-09 11:50:08 +01:00
ma0068 43497b186d return empty array if there is no placementtest instead of error 2025-12-09 11:43:39 +01:00
Harald Bamberger 50439ee6cc Merge branch 'master' into feature-63468/Studierendenverwaltung_Neuanlage_von_Interessenten_ueberarbeiten 2025-12-09 11:37:57 +01:00
Alexei Karpenko 016d4a1927 Studierendenverwaltung Projektbetreuer: added phrases, added check for existing Projektbetreuer when saving 2025-12-06 01:28:38 +01:00
Alexei Karpenko 112e30ab39 Studierendenverwaltung Projektarbeit: added concatenated Betreuer, sorted autocomplete suggestions, added Gesamtnote, freigegeben check removed when lock date set, added phrases 2025-12-05 22:01:35 +01:00
Andreas Österreicher e1959b9e40 Quality Gate Aenderungen im DBUpdate hinzugefügt 2025-12-05 13:21:46 +01:00
ma0068 e78482e947 - refactor sum points
- create green row background for current RT
2025-12-05 12:31:02 +01:00
Johann Hoffmann ca152dc1ea add projektarbeit_id & student_uid to projektbeurteilung_formular_link event in projektarbeitsbeurteilungsextension 2025-12-04 17:28:16 +01:00
Johann Hoffmann ec7ebc8286 allowedNoten config integer instead of string so javascript array.includes() doesnt miss the noten options 2025-12-04 16:57:24 +01:00
Johann Hoffmann 035e844fab added tbl_vorlage insert for PAAChangesBetSM.txt 2025-12-04 15:40:45 +01:00
Johann Hoffmann e7a737b7aa write stg_kz & semester_kurzbz into sammelmail about each projektarbeit; move method from abgabe.php api controller to abgabejob.php 2025-12-04 15:36:24 +01:00
Harald Bamberger 7e0acdbf45 fix typo 2025-12-04 14:57:03 +01:00
Johann Hoffmann e3c1287664 WIP 2025-12-04 14:49:05 +01:00
Harald Bamberger 391a4753d5 fix flex-grow with tabulator exceeding width (found by ma0646) 2025-12-04 14:38:30 +01:00
ma0068 c6686f56f6 make ZGV fields and bisMelden field editable
- new Berechtigung student/editDokZgv
- Berechtigungen student/editBakkZGV, student/editMakkZGV, student/editBismelden
2025-12-04 10:35:43 +01:00
Harald Bamberger 1c2937dfb6 Merge branch 'feature-69570/StudVw_Filter_broken' 2025-12-04 08:47:55 +01:00
Harald Bamberger 841b4736a9 do not send filters to backend when search endpoint is used 2025-12-04 08:39:37 +01:00
Alexei Karpenko c79ff24c89 Studierendenverwaltung Projektarbeit: added Studiensemester dropdown for Lv-Teil 2025-12-03 19:29:42 +01:00
Johann Hoffmann 0c5af137db WIP notifyBetreuerAboutNewOrChangedAbgabenForBetreuedProjektarbeiten Email Job; allowed abgabetypen & allowed noten as per config now via db primary key; new ProjektbetreuerModel method "getAllBetreuerOfProjektarbeit" to do just that; 2025-12-03 16:49:49 +01:00
Alexei Karpenko 77a1067ea5 Studierendenverwaltung Projektbetreuer: default Stunden coming from global config, Stundensatz is requested each time BetreuerIn is selected 2025-12-03 15:32:21 +01:00
ma0068 d33af0ae21 bugfix: resetModal in openMode modal 2025-12-03 15:14:26 +01:00
Johann Hoffmann 541d6d78cc projektbeurteilung_formular_link event for benotung link AbgabetoolMitarbeiterDetail.js; projektarbeit_is_current event for abstracted logic in Abgabetool; show endupload missing message on benoten if neither old nor new link are eligable; 2025-12-03 11:35:49 +01:00
ma0068 7726c3ce21 disable pruefungsnotizen 2025-12-03 10:23:58 +01:00
Harald Bamberger 5a970c3f2e fix typo 2025-12-03 09:58:33 +01:00
Harald Bamberger abcc1269eb add permission to show profile images in new studvw 2025-12-03 09:44:34 +01:00
Harald Bamberger c849b5defa fix broken filters 2025-12-02 18:08:03 +01:00
ma0068 d75939a8f8 refactor Messages
- endpoint: using apiMessages instead of prop
- add Phrases
- openMode Modal: resetModal if no messageId
- openMode inSamePage: loadReplyData
- function getNameOfDefaulRecipients: add missing check, if id[]
2025-12-02 16:08:13 +01:00
Johann Hoffmann 7747857583 AbgabetoolStudent beurteilung erstbetreuer/zweitbetreuer switch + get the actual link from the projektarbeitsbeurteilung extension via event 'projektbeurteilung_download_link' + fallback from config in case that fails; WIP implementing the switch for lektor beurteilungstemplate based on isCurrent/Semester etc in an Event in the pabu extension; 2025-12-02 16:07:26 +01:00
Andreas Österreicher 3ee81ae6e7 Merge branch 'feature-55978/infocenter_electronic_onboarding_filter' 2025-12-02 16:04:51 +01:00
Andreas Österreicher d1f684f0b3 Merge branch 'feature-69182/PHP8-Stringzugriff_mit_geschwungenen_Klammern' 2025-12-02 15:53:15 +01:00
ma0048 d8e57d43f9 session url in die config verschoben 2025-12-02 13:53:38 +01:00
ma0048 5c9710f44d externe ueberwachung v1 2025-12-02 13:49:05 +01:00
ma0048 257038a2d1 negative stunden markieren
headerfilter angepasst fuer minusstunden
2025-12-02 13:25:46 +01:00
Johann Hoffmann 6359dc0fc9 use sendUploadMail on endupload, no events for that; remove extensive form validation from student detail; serientermin update table format fix; WIP new job informing betreuer about changes to thei betreued PA's; zweitbetreuer/erstbetreuer beurteilungslink switch in abgabetoolStudent; WIP getting that link from event not hardcoded; fix checkUploadSize calculation bytes to megabytes; added beurteilungerforderlich class to accordion headers; 2025-12-02 13:13:42 +01:00
Harald Bamberger 4dabc642ed Merge branch 'master' into feature-69438/FHC4_Studierendenverwaltung/FeedbackPunkte 2025-12-02 07:54:40 +01:00
Harald Bamberger afb3ce4cae modify using open mode newTab or window with multiple Recipients via post request 2025-12-02 07:54:13 +01:00
ma0068 be2b578f82 reset default openmode to modal 2025-12-01 14:43:21 +01:00
ma0068 17519eac83 refactor Messaging
- headerFilter for table Messages
- multiactions for sendMessages for openmodes modal and inSamePage
2025-12-01 13:27:42 +01:00
Harald Bamberger 89ec51bd0a Merge branch 'feature-69065/Projektarbeiten_Firmen_verwalten' 2025-11-28 14:45:29 +01:00
Johann Hoffmann aee6ace42e termine without uploads can now only have 'standard' or 'abgegeben' status based on datum; FHC_Api_Controller method checkUploadSize() -> checks input->server('CONTENT_LENGTH') against min($max_upload, $max_post, $memory_limit) and throws a designated filesizeExceeded error message; added fhc-orange palette for new status 'beurteilungerforderlich'; 2025-11-28 14:09:53 +01:00
Harald Bamberger 0372853df2 Aufnahmetermine: fix error persiting boolean, GS: sortorder studiensemester, Gruppen exclude generated groups from search result 2025-11-28 14:01:20 +01:00
Harald Bamberger dc603375ec Merge branch 'master' into feature-69065/Projektarbeiten_Firmen_verwalten 2025-11-28 11:15:59 +01:00
Johann Hoffmann 095d5acbc5 load all studiensemester for assistenz; load paabgabetyp benotbar for all paabgaben; datediff calc luxon; new dateclass 'beurteilungrequired'; 2nd quality gate validation logic option; filter notenoptions as per config; filter abgabetypoptions as per config; upload_allowed checkbox for serientermine; serientermin modal layout rearranged; abgabetoolJob fixes; 23:59 in the descriptive col, not datepicker; zusatzdaten are required; activeIndex for accordion calulated on demand by method instead of reading a computed value; 2025-11-27 16:53:50 +01:00
ma0068 aa84bdec1e ---staging---- 2025-11-27 14:46:55 +01:00
ma0048 96be1789b5 tag-formatter & helper hinzugefuegt 2025-11-27 09:45:57 +01:00
Alexei Karpenko eb1c3189b5 Studierendenverwaltung Projektarbeit: title not required anymore 2025-11-26 16:45:51 +01:00
Andreas Österreicher 6d27c3f6e2 PHPInfo entfernt 2025-11-26 08:27:14 +01:00
ma0068 93e25bb5fc added Reminder for Unterbrecher for Student 2025-11-25 17:35:44 +01:00
Harald Bamberger a413b6c779 fix bug when changing studiensemester on route search 2025-11-25 14:00:31 +01:00
ma0068 38e8f91fdf add kurzbzlang to studentDropdown suggestion 2025-11-25 10:48:57 +01:00
Harald Bamberger f0e0bdc082 add optional query parameter studiensemester to notenspiegel and notenspiegel_erweitert to override semester_aktuell if multiple tabs in new studvw have different current semesters 2025-11-24 18:37:30 +01:00
Harald Bamberger 60661d3457 Merge branch 'studvw_2025-11_rc2' 2025-11-24 17:02:00 +01:00
Harald Bamberger 41bb99b5ea Merge branch 'master' into studvw_2025-11_rc2 2025-11-24 16:48:11 +01:00
Harald Bamberger 054b9fdee3 Merge branch 'feature-69388/Pruefung_API_insert_Propleme' 2025-11-24 16:42:49 +01:00
Harald Bamberger 61faf5386a Merge branch 'master' into studvw_2025-11_rc2 2025-11-24 16:39:47 +01:00
Harald Bamberger 6b4f5778c2 refactor stv Pruefung Tab and API endpoint to use same logic for insert and update, use luxon lib to initialize datepicker with iso date and send iso date format to api endpoint 2025-11-24 16:26:11 +01:00
Johann Hoffmann 8888b6991f Merge branch 'master' into feature-61164/AbgabetoolQualityGates
# Conflicts:
#	application/models/education/Projektarbeit_model.php
#	public/js/helpers/StringHelpers.js
2025-11-24 14:25:43 +01:00
Johann Hoffmann 9ac7ff2a4c allowed to upload on endtermin switch to production logic (date & quality gates) 2025-11-24 14:16:07 +01:00
Johann Hoffmann f4ca34f247 remove email sent to alert on serientermin since we do this in cronjob now; 2025-11-24 14:14:46 +01:00
Andreas Österreicher 060f11f1d8 Anmerkung und Spaltenanzahl bei Leistungsstipendien Import angepasst 2025-11-24 09:49:15 +01:00
Harald Bamberger cdc1933ce4 fix typo 2025-11-24 09:48:05 +01:00
Harald Bamberger 239a9c89d7 compare DateTime with DateTime instead of String 2025-11-24 09:46:53 +01:00
Harald Bamberger 4964a2c06d set tabulator layout to fitDataStretchFrozen when frozen columns are defined, change css classes to display disabled status use the same as in students list 2025-11-24 09:40:33 +01:00
Johann Hoffmann 3b7ed523b4 postStudentProjektarbeitZusatzdaten in detail view for Betreuer/Assistenz; 2025-11-21 12:36:03 +01:00
Harald Bamberger ce5e3131c1 Merge branch 'master' into studvw_2025-11_rc2 2025-11-21 10:55:47 +01:00
Harald Bamberger 7eee6d51aa clear tabulator when returning to index or studiensemester route from search route 2025-11-21 10:55:01 +01:00
chfhtw 1666ba82b2 Bugfix: correct compare values in Pruefung->insertPruefung() 2025-11-21 10:42:13 +01:00
Harald Bamberger e54e83f718 Merge branch 'bug-68552/LV-Plan_mobile_Wochenansicht_links_rechts_scrollen' 2025-11-21 08:48:19 +01:00
chfhtw d916c6ab31 make Pruefung->insertPruefung() behave exactly like old FAS 2025-11-21 08:27:05 +01:00
Harald Bamberger be35fd5313 fix typo 2025-11-20 19:09:31 +01:00
Harald Bamberger dd92c815da fix back button behavior in studvw and lvverwaltung 2025-11-20 18:59:44 +01:00
ma0068 d76e84639f neue Phrasen bzw. Phrasenupdate zu Abmeldungsgruende Studierendenantrag 2025-11-20 16:18:55 +01:00
Harald Bamberger 6357aca656 show combine person tab only if permission basis/person, restore endpoint handling logic in List.js 2025-11-20 15:19:36 +01:00
Harald Bamberger d001e3c168 add option to deactivate livesearch, so the searchresult in studvw is shown in tabulator 2025-11-20 13:40:10 +01:00
Harald Bamberger d88f2a0a48 Merge branch 'feature-69176/Studierendenverwaltung_Berichte' into studvw_2025-11_rc2 2025-11-20 13:35:01 +01:00
Harald Bamberger 6378e75c37 Merge branch 'feature-68744/Studierendenverwaltung_Einstellungen' into studvw_2025-11_rc2 2025-11-20 13:33:56 +01:00
Harald Bamberger e22344e9dd Merge branch 'feature-68770/FHC4_Studierendenverwaltung_Funktion_Personen_Zusammenlegen' into studvw_2025-11_rc2 2025-11-20 13:28:37 +01:00
Harald Bamberger 0ed11a02a5 Merge branch 'master' into feature-69176/Studierendenverwaltung_Berichte 2025-11-20 13:27:30 +01:00
Harald Bamberger 23d1104602 Merge branch 'master' into feature-68770/FHC4_Studierendenverwaltung_Funktion_Personen_Zusammenlegen 2025-11-20 13:26:34 +01:00
Johann Hoffmann c447fb9632 properly center loadingOverlay in center of screen, not center of content + put that template away in a FhcOverlay.js component 2025-11-20 11:33:30 +01:00
Johann Hoffmann 352638ed90 code cleanup; 2025-11-20 10:36:23 +01:00
Harald Bamberger bab15bc5b2 add fs_x-small and fs_xx-small and ajust css em settings 2025-11-19 13:01:47 +01:00
Harald Bamberger 1cc77c8eba Merge branch 'master' into feature-68744/Studierendenverwaltung_Einstellungen 2025-11-19 11:42:21 +01:00
Harald Bamberger 3730be991a Merge branch 'master' into feature-39571/Studierendenverwaltung_CoreNotizcontroller 2025-11-19 11:30:52 +01:00
Harald Bamberger 2f2c7d0d92 Merge branch 'feature-69379/Tooltip-Direktive' 2025-11-19 11:19:37 +01:00
Paolo e837101651 PHP8 compatibility: replaced the curly brackets {} with square brackets [] where used in combination with strings 2025-11-19 10:53:59 +01:00
Harald Bamberger e4a7955239 fix editor params stored empty in tabulator local storage causing empty grade dropdown when switching tabs 2025-11-18 16:42:31 +01:00
Johann Hoffmann a4fee77301 link url in abgabetoolJob per config; comment out addMeta; 2025-11-18 15:01:43 +01:00
Cristina 92030ca697 Merge branch 'feature-69379/Tooltip-Direktive' into epic-56039/LV-Evaluierung 2025-11-18 11:02:57 +01:00
Cristina 53424999dc Created Vue Tooltip directive
This directive initializes and disposes Bootstrap tooltip
2025-11-18 10:58:57 +01:00
Cristina a59f90112d Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-11-18 10:51:18 +01:00
Johann Hoffmann 96fdc357de move getDateStyleClass to AbgabetoolStudent.js from AbgabeStudentDetail.js 2025-11-17 16:39:19 +01:00
Johann Hoffmann 6cd0e3a574 email tbl_vorlage inserts dbupdate script; index.ci.php/Abgabetool/Assistenz/stg_kz? optional param route in old cis & cis4; no data placeholder phrase fix; 2025-11-17 15:57:53 +01:00
Alexei Karpenko ad7012367c added Link to company management in project work management 2025-11-17 14:52:58 +01:00
chfhtw 03b3182000 adding Notenspiegel to AppMenu 2025-11-17 13:09:16 +01:00
Johann Hoffmann 1120b823d2 log email count and early job termination in case of new events to notify for 2025-11-17 12:06:07 +01:00
Johann Hoffmann f89a53b156 fix getProjektbetreuerAnrede function since betreuer are not necessarily mitarbeiter with such an uid; notify students config from milliseconds to pgsql interval '1 day'; ported notifyBetreuerMail & notifyStudentMail to AbgabetoolJob.php; 2025-11-17 11:47:00 +01:00
Andreas Österreicher 126aa890c4 Merge branch 'feature-6976/Link_fuer_unverifizierte_email_anpassen' 2025-11-17 10:50:34 +01:00
Andreas Österreicher 4762154bbc Merge branch 'feature-67484/lvverwaltung_finetunning' 2025-11-17 09:06:10 +01:00
Harald Bamberger c9506adc10 do not use cisroot for link to placement test administration 2025-11-14 11:19:54 +01:00
Harald Bamberger f281925874 do not use cisroot for link to final exam protocol 2025-11-14 11:13:23 +01:00
Harald Bamberger 1c319addc5 do not use cisroot for document download 2025-11-14 11:03:48 +01:00
Harald Bamberger dbfa64a436 do not use cisroot for document download 2025-11-14 10:46:27 +01:00
Harald Bamberger 366d48b836 Merge branch 'feature-63373/FHC4_Studierendenverwaltung_Dokumente_erstellen' 2025-11-14 09:45:21 +01:00
Harald Bamberger 0a53ca49aa readd accoutinfoblatt to single student dropdown 2025-11-14 09:39:46 +01:00
ma0048 284633012f Merge remote-tracking branch 'origin/master' into feature-67484/lvverwaltung_finetunning 2025-11-14 08:09:25 +01:00
ma0048 63eda8b934 addgroup/addperson immer anzeigen
gruppen sortierung angepasst
fehlende les anzeigen
2025-11-14 08:07:39 +01:00
Johann Hoffmann cff71ec829 AbgabetoolJob notifyStudentMail function to send Emails to students about their changed abgabetermine inside the configurable threshold; 2025-11-13 17:16:51 +01:00
chfhtw de012b290b get semester & orgform from Verband to StudVw Main Component 2025-11-13 16:27:15 +01:00
chfhtw dbf9547f9c add CSS class disabled to AppMenu 2025-11-13 16:23:57 +01:00
chfhtw 65df13ca9f add slot to AppMenu 2025-11-13 16:23:04 +01:00
Harald Bamberger 1d786d3e16 Merge branch 'master' into feature-63373/FHC4_Studierendenverwaltung_Dokumente_erstellen 2025-11-13 16:09:31 +01:00
Harald Bamberger 339639cc6e add Link to Lehrauftraege to apps menu in stv 2025-11-13 15:48:20 +01:00
Cristina 993dff3351 Gendered phrase lektorInnen (FHTW style) 2025-11-13 11:11:37 +01:00
Cristina 0a118a1427 Clustered LV-Evaluierung phrases after merge 2025-11-13 10:50:36 +01:00
Cristina 4ab0c0a44e Merge branch 'master' into epic-56039/LV-Evaluierung
# Conflicts:
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2025-11-13 10:44:39 +01:00
chfhtw e36e86fd50 Code Quality 2025-11-13 09:54:56 +01:00
Cristina d99d1c5ca0 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-11-13 09:49:37 +01:00
Cristina 43281c6ba2 Removed test buttons from FhcChart basic template 2025-11-13 09:48:54 +01:00
chfhtw cd574cd12c Reload settings setup on language change 2025-11-13 09:39:38 +01:00
chfhtw 95f1c66684 Stv Settings Phrases 2025-11-13 09:11:06 +01:00
chfhtw 5d957e38ae Phrase settings saved 2025-11-13 08:52:47 +01:00
chfhtw 7566e8aac2 Make AppConfig a general Component 2025-11-13 08:48:54 +01:00
Johann Hoffmann 8b851221b0 cis4 main content element shrinkability with style="min-width: 0;" 2025-11-12 12:05:48 +01:00
chfhtw 7fdfa94d11 Merge branch 'master' into feature-68744/Studierendenverwaltung_Einstellungen 2025-11-12 08:15:56 +01:00
chfhtw 77604c5e15 StV: Font Size setting 2025-11-12 08:02:06 +01:00
Harald Bamberger 84b9b08d28 Merge branch 'studvw_2025-11_rc' 2025-11-11 16:40:30 +01:00
Johann Hoffmann 2920c68f05 wip 2025-11-11 15:59:42 +01:00
Johann Hoffmann 74937db204 WIP email logs to read/send in job; 2025-11-11 15:52:04 +01:00
Johann Hoffmann 410f0c4b6a fixtermin -> "kein neichreichen erlaubt" phrase/bool logic change; signatur message on enduploads fetched from signatur server on every load request; Inplace toggle for further infos in offcanvas timeline & student details on mobile view(tooltips); reworked col/row structure on detail views for mobile; 2025-11-11 13:44:47 +01:00
Harald Bamberger a9e90cf10d add absoluteJsImportUrl helper function - to generate absolute urls with fhcomplete_build_version for dynamic imports - and use it in stv config 2025-11-11 13:01:48 +01:00
Paolo 0b6dc34220 If docsbox queue is slow, the DocsboxLib can stop checking the queued document status and raise an error 2025-11-10 15:41:01 +01:00
Harald Bamberger b31ebf3412 Merge branch 'feature-67518/Studierendenverwaltung_Karteireiter_anzeigen_verstecken_wenn_Interessent_gewaehlt' into studvw_2025-11_rc 2025-11-10 13:20:36 +01:00
Harald Bamberger 00eac334c0 Merge branch 'feature-63443/Studierendenverwaltung_Tab_Abschlusspruefung_Finetuning' into studvw_2025-11_rc 2025-11-10 12:48:01 +01:00
chfhtw 775d865878 StV settings 2025-11-10 12:38:57 +01:00
Harald Bamberger d2b1eb4645 Merge branch 'feature-68738/FHC4_Studierendenverwaltung_Studentlist_Export' into studvw_2025-11_rc 2025-11-10 09:40:42 +01:00
Johann Hoffmann cef0046acd speeddial icon/positioning; textarea styles; fixtermin phrase; wip inverting fixtermin bool logic to avoid double negative semantics 2025-11-07 14:19:17 +01:00
Johann Hoffmann a61d5b1d62 orgform/studstatus cols; 2025-11-07 11:17:59 +01:00
Alexei Karpenko f15932964f Studierendenverwaltung email: descending order kontakt_id 2025-11-07 01:06:22 +01:00
Alexei Karpenko 5678c18619 keepemailunverified parameter: email is passed even if unverified 2025-11-07 00:51:07 +01:00
Johann Hoffmann b1a1cdf235 studiensemester dropdown filter, default all, options are current/next and op to 10 back; benotet/unbenotet/alle fetch parameter; WIP orgform/studstatus cols; 2025-11-06 16:29:24 +01:00
ma0068 74a00a4ce0 changes according to userStory #68983 2025-11-05 17:26:39 +01:00
Harald Bamberger 1c5d3d7c78 Merge branch 'master' into studvw_2025-11_rc 2025-11-05 17:15:39 +01:00
Harald Bamberger 1ac9c9b6cb Merge branch 'feature-68672/Studierendenverwaltung_Suche_nach_Personenkennzeichen_und_Matrikelnummer' 2025-11-05 17:10:40 +01:00
Harald Bamberger 303f29ebdb Merge branch 'bug-68772/Suche_mit_Sonderzeichen' 2025-11-05 17:07:17 +01:00
Harald Bamberger 383590fa6b Merge branch 'master' into feature-68672/Studierendenverwaltung_Suche_nach_Personenkennzeichen_und_Matrikelnummer 2025-11-05 16:55:26 +01:00
Harald Bamberger 0d449d60c2 Merge branch 'master' into studvw_2025-11_rc 2025-11-05 16:51:38 +01:00
chfhtw 5ecd81bb09 translate logout 2025-11-05 16:50:22 +01:00
chfhtw 1cdebbe977 remove unused changed eventlistener 2025-11-05 16:49:12 +01:00
chfhtw a97a176522 use phrasen in stv list 2025-11-05 16:47:31 +01:00
Harald Bamberger 327e849fc6 Merge branch 'bug-66932/studierendenverwaltung_status_tab_fehlermeldung_meldestichtage' 2025-11-05 16:46:19 +01:00
chfhtw ede2e1710e Merge branch 'master' into feature-68744/Studierendenverwaltung_Einstellungen 2025-11-05 16:45:21 +01:00
Harald Bamberger f54ad298fa Merge branch 'feature-69107/StringHelpersCapitalize' 2025-11-05 16:41:31 +01:00
Harald Bamberger 5e1fc3abf7 Merge branch 'master' into feature-69107/StringHelpersCapitalize 2025-11-05 16:39:06 +01:00
Harald Bamberger 819a7ef219 Merge branch 'master' into studvw_2025-11_rc 2025-11-05 16:33:40 +01:00
Harald Bamberger d815176bab Merge branch 'bug-66890/studierendenverwaltung_statuswechsel_doppelte_statuseintraege' 2025-11-05 16:29:41 +01:00
Harald Bamberger 4e01420ce0 Merge branch 'master' into bug-66890/studierendenverwaltung_statuswechsel_doppelte_statuseintraege 2025-11-05 16:22:58 +01:00
Harald Bamberger 683360b13a Merge branch 'master' into studvw_2025-11_rc 2025-11-05 16:17:39 +01:00
Harald Bamberger 9042caa06b Merge branch 'bug-66774/Messages_Vorlagen_Subject_Bezeichnung_statt_Vorlagekurzbz' 2025-11-05 16:12:17 +01:00
Harald Bamberger 9668c67197 Merge branch 'bug-66933/studierendenverwaltung_message_tab_fehlermeldung' 2025-11-05 16:05:48 +01:00
Harald Bamberger 84610faedc Merge branch 'master' into bug-66933/studierendenverwaltung_message_tab_fehlermeldung 2025-11-05 15:58:48 +01:00
Harald Bamberger 8c4a163671 Merge branch 'master' into bug-66774/Messages_Vorlagen_Subject_Bezeichnung_statt_Vorlagekurzbz 2025-11-05 15:53:36 +01:00
Johann Hoffmann 9e40c6b21f declaration, import & binding of capitalize function from StringHelpers.js; 2025-11-05 15:41:17 +01:00
Johann Hoffmann 3878fce625 wip abgabetool; 2025-11-05 15:34:10 +01:00
Andreas Österreicher 67d41f1df9 Note Bestanden am Diploamsupplement priorisiert damit diese als
"bessere" Note als Nicht Genügend gewertet wird
2025-11-05 14:26:45 +01:00
chfhtw 6011109132 Fix language on details tabs 2025-11-05 11:44:25 +01:00
chfhtw cc3da1439d StV: add user menu 2025-11-05 11:06:45 +01:00
Harald Bamberger c97e1b6453 Merge branch 'feature-67490/studstatus_suche_abort_controller_haengt' 2025-11-05 11:06:32 +01:00
Harald Bamberger 72403e0960 Merge branch 'feature-68745/Menue_zur_Verlinkung_von_Apps' into studvw_2025-11_rc 2025-11-04 17:12:19 +01:00
Harald Bamberger e91b829c25 Merge branch 'feature-68390/Studierendenverwaltung-Details_Header_und_Tabsnav_nicht_mitscrollen' into studvw_2025-11_rc 2025-11-04 17:11:23 +01:00
Harald Bamberger c56fd038b8 Merge branch 'feature-63445/Studierendenverwaltung_Filter' into studvw_2025-11_rc 2025-11-04 17:10:24 +01:00
Harald Bamberger 24c014e8dd Merge branch 'feature-63444/stv_mehrfachaktion_mail_an_private_oder_interne_adresse' into studvw_2025-11_rc 2025-11-04 17:06:23 +01:00
Harald Bamberger 608dab1e65 Merge branch 'feature-63435/Studierendenverwaltung_Studierende_Verbandsgruppen_und_Spezialgruppen_zuordnen_Multiaktion' into studvw_2025-11_rc 2025-11-04 17:03:52 +01:00
Harald Bamberger fe1433a19c Merge branch 'feature-63374/Studierendenverwaltung_International_Baum_Filter' into studvw_2025-11_rc 2025-11-04 16:56:51 +01:00
Harald Bamberger 8c83e08472 Merge branch 'feature-63373/FHC4_Studierendenverwaltung_Dokumente_erstellen' into studvw_2025-11_rc 2025-11-04 16:55:20 +01:00
chfhtw 0893ec30d9 Bugfix: use plainto_tsquery instead of to_tsquery to avoid errors on special chars 2025-11-04 15:26:18 +01:00
Harald Bamberger 0417afeea8 Merge branch 'feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren' into studvw_2025-11_rc 2025-11-04 14:56:54 +01:00
chfhtw 9601c8bdd2 add personenkennzeichen & matrikelnummer to stv search config 2025-11-04 11:40:08 +01:00
Harald Bamberger 146bb5f336 replace legacy lvplan link in room content with cis4 lvplan link 2025-11-03 15:34:54 +01:00
chfhtw 9e4401d441 better contrast for apps-menu-button 2025-11-03 13:14:14 +01:00
Andreas Österreicher aa43a2f32c Merge branch 'master' into feature-55978/infocenter_electronic_onboarding_filter 2025-11-03 12:57:41 +01:00
chfhtw d6c4e0db41 show submit btn in StV 2025-11-03 11:36:24 +01:00
chfhtw 398478e575 searchbar submit button 2025-11-03 11:36:10 +01:00
chfhtw 17540070a1 remove comments 2025-11-03 11:35:31 +01:00
chfhtw d923f30ccf Add search from url functionality 2025-11-03 11:05:26 +01:00
Johann Hoffmann 3d51753419 new bootstrap offcanvas component; projektarbeit abgabetermine timeline & status legende in offcanvas; fixtermin toggle & allowed to edit all termine for assistenz; studiengang selection + filter for getSTG_isEntitledFor('basis/abgabe_assistenz:rw'); moved filedownload from Cis/Abgabetool Auth Controller to Abgabe.php Api Controller; status symbol in table columns prevTermin/nextTermin; get_betreuer_details pgsql function to avoid rewriting the same subquery for every betreuer anrede; 2025-10-31 11:14:39 +01:00
Andreas Österreicher 3c910d03bb Fixed Problem with Special Characters in Permission Description 2025-10-30 15:33:12 +01:00
chfhtw fc16a9e4c6 Stv: add search results to student list 2025-10-30 14:01:46 +01:00
chfhtw 9699684946 Stv: students search function 2025-10-30 14:00:41 +01:00
chfhtw 06b562786d searchbar: make abort function 2025-10-30 14:00:03 +01:00
chfhtw 539c78166f Stv list: allow post calls on tabulator 2025-10-30 13:59:12 +01:00
chfhtw 5a0134c6cc searchbar: prevent clear on enter 2025-10-30 13:58:18 +01:00
chfhtw a8535e6e0f replace old $fhcApi calls with new $api 2025-10-30 13:57:15 +01:00
Andreas Österreicher 5677142b0b Merge branch 'feature-68676/Ausbildungsvertrag_Lehrgaenge_2025' 2025-10-30 12:59:47 +01:00
ma0068 c78eef8af5 add validation for required props, refactor slots 2025-10-28 09:31:04 +01:00
Johann Hoffmann ac1e0a8aa3 Merge remote-tracking branch 'origin/master' into feature-61164/AbgabetoolQualityGates
# Conflicts:
#	system/phrasesupdate.php
2025-10-27 14:51:52 +01:00
Johann Hoffmann 259c2aec14 load projektarbeiten for studiengänge -> assistenz page; speed dial position rework; automagicmodal logic fix; activeTabIndex by date in detail views; tooltips on icons; $capitalize phrasen to ensure capitalization; phrasenpromise & resolve similar to anw; modal component emits fullscreen event now; 2025-10-27 14:40:56 +01:00
ma0068 6a7de7417b student view: reload after delete or upload 2025-10-27 13:50:25 +01:00
ma0068 c12678ca5a buttons edit and delete foto: adapt for better visibility, add preview to upload 2025-10-27 13:43:59 +01:00
Alexei Karpenko 565640c73b Ausbildungsvertrag: akad grad from Studienordnung is own field 2025-10-26 17:36:22 +01:00
Andreas Österreicher 3c9a52e389 Merge branch 'feature-68950/Anmelderegel' 2025-10-24 13:44:35 +02:00
Andreas Österreicher 3e52ea39d5 LVRegel Fixed Semester Check 2025-10-24 13:36:11 +02:00
Andreas Österreicher 2b53eb327f LVRegeln - Abschlussregel bei Anmeldung entfernt da diese dort zu Problemen führt 2025-10-24 13:10:41 +02:00
ma0068 84bfea0be9 make Prestudent.js and Details.js responsive 2025-10-24 11:18:19 +02:00
chfhtw 406b93a628 remove comment & renaming Studierenden Verwaltung to Studierendenverwaltung 2025-10-24 09:22:17 +02:00
ma0068 4be0a831a1 add Phrases 2025-10-23 13:49:05 +02:00
ma0068 9ed3251e55 open in iframe, only show tab if count in config is valid 2025-10-23 12:55:14 +02:00
chfhtw 94d5e8f780 use AppMenu in LvV 2025-10-23 12:48:11 +02:00
chfhtw 5baf8b645f use AppMenu in StV 2025-10-23 11:49:07 +02:00
chfhtw 11daf96850 add navigation entries for StV & LvV 2025-10-23 11:48:55 +02:00
chfhtw 752ef8a57b AppMenu Component 2025-10-23 11:48:03 +02:00
chfhtw 8ddc2f02fe SVG Icons 2025-10-23 11:47:33 +02:00
Alexei Karpenko 1623c8e51c Ausbildungsvertrag: akadgrad is coming from Studienordnung 2025-10-22 16:57:19 +02:00
ma0068 9a8fbabbe4 move dropdown profileUpdateStates to FilterComponent, delete not needed code 2025-10-22 14:25:43 +02:00
ma0068 6337869098 new Multitab CombinePeople, start Function 2025-10-22 10:23:24 +02:00
ma0068 1423579a49 refactor Profile Update for filter, backendfilter not active 2025-10-21 14:42:02 +02:00
Andreas Österreicher 87ec4fd482 Problem beim Drucken von Zeugnissen behoben wo die LV der
Studienverpflichtung Sonderzeichen enthält
2025-10-20 17:32:43 +02:00
ma0068 6e9969d9e4 use shorter table names for columns stg and orgform , add column ausbildungssemester 2025-10-20 16:08:12 +02:00
Andreas Österreicher 4407310f40 Merge branch 'master' into feature-67484/lvverwaltung_finetunning 2025-10-20 11:33:43 +02:00
Harald Bamberger 4495632393 join only prestudent for studiengang_kz of student 2025-10-17 14:45:03 +02:00
ma0068 9fa7166c84 added download to StudentList 2025-10-17 12:33:22 +02:00
chfhtw 1fbca8bdab Bugfix: Add overflow for horizontal scrolling 2025-10-17 10:14:47 +02:00
Harald Bamberger a9670fce5c Merge branch 'bug-68555/Dokumente_Studienbestaetigung_wird_nicht_angezeigt' 2025-10-16 15:38:37 +02:00
chfhtw e7788fc18f Bugfix: format betrag in StV Konto correctly 2025-10-16 08:38:59 +02:00
chfhtw 11205e9ec1 Bugfix: multiple types in CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN config were concatenated wrong in CIS 4.0 2025-10-16 08:38:17 +02:00
ma0068 7755dc12d0 View Studierendenverwaltung
- add badge unruly
- add tileSlots for PersKz, MatrikelNr, person_id
- remove MatrikelNr and person_id from left side
- add attribut unruly to student object
2025-10-15 13:55:54 +02:00
Cristina 343964750b Merge branch 'master' into epic-56039/LV-Evaluierung
# Conflicts:
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2025-10-14 17:22:39 +02:00
Cristina 0201bac046 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-10-14 17:19:29 +02:00
Johann Hoffmann 0d2e41cf2f added paabgabetyp columns "aktiv", "upload_allowed", "aktiv"; setting sensible default values for existing typen that are just the developers best guess really; accordion header with icons & tooltips; logLib in Abgabe API controller logging all successful delete/insert/update requests; show arbitrary '23:59' string after target date so it is clear until when the upload should be fulfilled, even though we still dont do anything technically different; new Termine can only be made with aktiv paabgabe typen; note & benotungsnotiz now tied to paabgabetyp benotbar flag instead of hardcoded for qgate1 & 2; added "noch nicht abgegeben" text in case the abgabedatum is null; modal now spawns in xl with fullscreen optionally enabled; 2025-10-14 16:45:28 +02:00
Cristina 2aee86baba Changed phrase lvevaluierung/logoutText 2025-10-14 16:16:23 +02:00
ma0068 15a9379c6e use Slots for Core Detail Header: Tags, Issues, TileSlots 2025-10-14 15:45:11 +02:00
ma0068 40512edef0 add emit redirect to reload parent 2025-10-13 16:46:29 +02:00
ma0068 e9c039dad2 Refactor detailHeader component for PV21
- own css.file for fotouplad
- domain as prop
- refactor link to Leitung
- slots for issuetracking and tags
2025-10-13 16:07:51 +02:00
Alexei Karpenko 07bcbee11b add Interessent: insertamum and insertvon when adding prestuden 2025-10-13 10:52:52 +02:00
Alexei Karpenko b9cb8f9cce Interessent anlegen: bugfix Geburtsdatum save, when searching for existing persons, more fields are displayed, form is emptied each time it is opened, adress can only be added, but not overwritten 2025-10-10 16:42:14 +02:00
ma0068 c7f2b145bf add checkBerechtigungen for Notes person_id and notes prestudent_id 2025-10-10 14:15:40 +02:00
Johann Hoffmann 14aad56d5e datepicker css overflow fix; returned modalMagic to old form since its simpler now 2025-10-09 12:40:53 +02:00
chfhtw 601c4367dc use fhcApps for CIS 2025-10-09 10:57:51 +02:00
chfhtw 70c230edce use fhcApps for LogsViewer/LogsViewer 2025-10-09 10:44:13 +02:00
chfhtw d294d17e37 use fhcApps for lehre/lvplanung/LvTemplates 2025-10-09 10:42:22 +02:00
chfhtw d88cc77a5c use fhcApps for Studstatus 2025-10-09 10:40:02 +02:00
chfhtw 61600e78b6 use fhcApps for Bismeldestichtag/Bismeldestichtag 2025-10-09 09:27:31 +02:00
chfhtw ea0b69d4c2 use fhcApps for ProfilUpdateRequest 2025-10-09 09:15:26 +02:00
chfhtw 0309c04ae0 use fhcApps for Cis/Documents 2025-10-09 08:46:09 +02:00
chfhtw 3c3e920573 use fhcApps for Studentenverwaltung 2025-10-09 08:43:12 +02:00
chfhtw d389cf87b8 delete MyLv->Info because app does not exist anymore and url is rerouted to MyLv->index 2025-10-09 08:42:29 +02:00
chfhtw 09864c5154 remove unused view that links to a non existing app 2025-10-09 08:41:58 +02:00
Johann Hoffmann f03411c668 legacy cis abgabetool routes; abgabetool.css for legacy cis; endupload & fixtermin logic enabled; paabgabe template rearranged; legacy view, controller has cis4 switch; viewData & router props workaround with CI3 router logic; wrapper app legacy cis; fix enduplaod validation; 2025-10-08 17:41:00 +02:00
ma0068 204ae1a469 refactor prepareQuery, use and take into account config parameters, refactor autoSelectRows 2025-10-08 16:34:39 +02:00
chfhtw d2f21ba4e6 use fhcApps for LVVerwaltung 2025-10-08 14:45:12 +02:00
ma0048 e11d72ace0 bei den tags copy button hinzugefuegt
datatree reexpand gefixed nach dem loeschen und hinzufuegen
2025-10-08 13:48:45 +02:00
chfhtw 842dabc1e7 add fhcApps functionality to view template 2025-10-08 13:37:06 +02:00
chfhtw 67281c84ed FhcApps Library 2025-10-08 13:36:20 +02:00
ma0068 3a6c8dfd2d adapt event dataProcessed and method autoselect 2025-10-08 10:28:14 +02:00
ma0068 450789ed72 extend query getStudents, change zuordnung_type from uid to prestudent 2025-10-08 09:12:54 +02:00
kindlm 3549fc1b1b Merge remote-tracking branch 'origin/master' 2025-10-07 18:43:11 +02:00
kindlm 06788bafc8 ParseHTML bei statistik.class ergänzt. SVNR aus BIS-Checks entfernt 2025-10-07 18:42:50 +02:00
Alexei Karpenko 309faaae06 phrasesupdate coma bugfix 2025-10-06 16:57:31 +02:00
Alexei Karpenko 1c21e8f88d Merge branch 'master' into feature-63468/Studierendenverwaltung_Neuanlage_von_Interessenten_ueberarbeiten 2025-10-06 16:54:41 +02:00
ma0068 984d81edb6 add tag component to List.js, add column tags to table, add functionality add, delete and update 2025-10-06 16:37:17 +02:00
Alexei Karpenko 5640f229d3 Studierendenverwaltung add Interessenten: switched to new API, Studienplaene are loaded in time 2025-10-06 16:10:06 +02:00
Johann Hoffmann 1e23b6de61 download files with window.open instead of window.location; fix signature mail student_modal info loading; check length of every entry field when doing endupload and force user to accept or cancel upon notification; berechtigung check für Abgabetool.php controller; phrasen everywhere; 2025-10-06 13:58:26 +02:00
ma0048 9309a48e97 autcomplete gefixed 2025-10-06 10:20:21 +02:00
Alexei Karpenko b22c6c10e4 Student.php controller: renamed method add Interessent to addFirstPrestudentstatus 2025-10-03 14:05:40 +02:00
Alexei Karpenko 60a1d40048 prstudentlib incoming: removed addmeta (debugging) 2025-10-03 14:03:41 +02:00
Alexei Karpenko 8c6033fed6 add first incoming: correctly check lehrverband, moved creating of incoming prestudentstatus to prestudent lib 2025-10-03 14:02:53 +02:00
ma0068 e79bb607d9 add permission validation oe for lehreinheit 2025-10-03 10:23:25 +02:00
Johann Hoffmann dab34eff35 klickibunti farben in accordion headers je nach datum/abgabedatum combo; more color definitions cis4 default.css; nomore legacy classes in Abgabe.php, CI3 models only; confirm delete Termin prompt; endupload validation stub, not sure about the technical min requirements here; mitarbeiter table format fix; show noten in projektarbeit view for students so there is some distinction; fhc isMobile computed revamp; order projektarbeiten by insertamum DESC to get most recent ones at the top of lists; 2025-10-02 16:53:41 +02:00
Alexei Karpenko 3a6fb08350 Creating of Interessenten: moved to PRestudentlib, renamed check to getPerson, corrected transaction handling, enabled creating of Incomings 2025-10-02 16:52:11 +02:00
ma0048 81725a0fe9 echterdv ueberprfung fixed 2025-10-02 14:27:14 +02:00
Cristina 0d51df95f9 Merge branch 'master' into epic-56039/LV-Evaluierung
# Conflicts:
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2025-10-02 11:30:55 +02:00
Cristina bfd513a475 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-10-02 11:27:31 +02:00
Harald Bamberger 3d50eacdc3 limit height of profile img in detail header 2025-10-01 18:45:26 +02:00
Harald Bamberger 4e4269033b Merge branch 'master' into feature-63445/Studierendenverwaltung_Filter 2025-10-01 17:50:22 +02:00
Harald Bamberger 9d2b147248 Details Header und TabsNav nicht mitscrollen 2025-10-01 17:32:17 +02:00
chfhtw 7b1bb27b34 Multiselect group selection: show only when all selected have an UID 2025-10-01 14:53:08 +02:00
chfhtw 2f20ddaefa Change StV config to hide Tabs when Prestudents without UID are selected 2025-10-01 14:51:29 +02:00
chfhtw ba7cfc3890 Make showOnlyWithUid and showOnlyWithoutUid available for multiselects 2025-10-01 14:50:18 +02:00
Cristina deebe987d3 Added slot selectedItem to autocomplete component in Input.js 2025-10-01 13:51:43 +02:00
Cristina cb77f3148a Added method to get Stundenplantermine for Lehreinheit/Lehrveranstaltung 2025-10-01 13:50:57 +02:00
Cristina cb64c83b50 Added method to get LV-Leitung from given LV 2025-10-01 13:48:10 +02:00
Harald Bamberger ac5ce1573a Merge branch 'master' into bug-66890/studierendenverwaltung_statuswechsel_doppelte_statuseintraege 2025-10-01 13:24:45 +02:00
ma0068 890b50c830 add new api for notiz 2025-10-01 13:13:41 +02:00
Johann Hoffmann c796536417 notiz -> beurteilungsnotiz; some missing phrasen; more color definitions (WIP); finalize automagic modal logic; added validation stub for endupload; loading spinner on every upload; added custom header classes to code unexpanded paabgabe accordion tabs by their abgabedatum or lack thereof (WIP); 2025-09-30 16:47:05 +02:00
chfhtw 1414d5f1ef Code Quality 2025-09-30 14:10:21 +02:00
chfhtw f9e2d784cf phrases for fhtw addon 2025-09-30 11:47:34 +02:00
chfhtw f518d56d4e StV: configurable Filters 2025-09-30 11:01:08 +02:00
ma0068 3664428467 add logic to edit and delete Personfoto 2025-09-30 10:50:01 +02:00
Harald Bamberger 76e6874a1a Merge branch 'master' into feature-63444/stv_mehrfachaktion_mail_an_private_oder_interne_adresse 2025-09-29 17:33:23 +02:00
Harald Bamberger 3c47453762 add projektarbeit tab to tab_order 2025-09-29 15:49:13 +02:00
Harald Bamberger 4fa2de5105 Merge branch 'master' into feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren 2025-09-29 15:37:42 +02:00
Harald Bamberger ca55c8b1a7 Archiv.js: import add missing file extension, DocumentDropdown: remove wrapper div causing button not being aligned 2025-09-29 13:48:14 +02:00
Harald Bamberger 5c66dfad49 Merge branch 'master' into feature-63373/FHC4_Studierendenverwaltung_Dokumente_erstellen 2025-09-29 08:24:18 +02:00
Harald Bamberger 845c75b775 Merge branch 'master' into feature-39571/Studierendenverwaltung_CoreNotizcontroller 2025-09-26 12:33:39 +02:00
ma0048 e3b6852017 bug beim aendern des status auf student mit ausbildungssemester 0 behoben 2025-09-25 14:42:34 +02:00
ma0068 5326f961c6 DetailHeader: add uid to redirectToLeitung 2025-09-25 11:25:55 +02:00
ma0048 0f43e8eb7a autocomplete auf backend umgestellt
textarea formattedAnmerkung rausgenommen
ui angepasst
2025-09-24 14:27:01 +02:00
ma0048 6abdb25c0a abort controller fixed und index auf campus.tbl_studierendenantrag_status.studierendenantrag_id hinzugefuegt 2025-09-24 09:33:41 +02:00
Alexei Karpenko 6199283698 Merge branch 'feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren' into feature-63468/Studierendenverwaltung_Neuanlage_von_Interessenten_ueberarbeiten 2025-09-22 17:36:11 +02:00
Alexei Karpenko 3f0f48a4e0 Student.php: bracket bugfix, return person id of added Personinstead of true, Studierendenverwaltung Projektarbeit phrases 2025-09-22 17:34:50 +02:00
Alexei Karpenko 0cb36c2d30 Merge branch 'feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren' into feature-63468/Studierendenverwaltung_Neuanlage_von_Interessenten_ueberarbeiten 2025-09-22 15:54:46 +02:00
Alexei Karpenko a533294121 removed addMeta in Student.php Studierendenverwaltung 2025-09-22 15:54:26 +02:00
Alexei Karpenko c07697c541 Merge branch 'feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren' into feature-63468/Studierendenverwaltung_Neuanlage_von_Interessenten_ueberarbeiten 2025-09-22 13:52:37 +02:00
Alexei Karpenko 8e7a1a2ddd Merge branch 'master' into feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren 2025-09-22 13:39:36 +02:00
Johann Hoffmann 14f5a651a4 abgabetool rechte; WIP magic modal for next QG Termin logic handling; 2025-09-22 10:47:12 +02:00
Alexei Karpenko d062e8903f Mitarbeiter model searchMitarbeiter method: removed redundant person id 2025-09-19 11:29:08 +02:00
Alexei Karpenko 566938d4f0 Studierendenverwaltung Abschlusspruefung: moved Vorsitz and Pruefer search to backend, searched by vorname or nachname or combinations of vorname and nachname 2025-09-18 17:25:00 +02:00
Johann Hoffmann ce9f0536d6 Merge branch 'master' into feature-61164/AbgabetoolQualityGates 2025-09-17 16:40:53 +02:00
ma0048 aca4195df6 stv kontaktieren tab hinzugefuegt 2025-09-17 11:01:08 +02:00
ma0048 651452d821 bug beim laden des status tabs ohne meldestichtag 2025-09-16 08:40:40 +02:00
ma0048 69a1e945b3 bug beim laden des messages tab ohne oe zuordnung 2025-09-16 08:36:12 +02:00
Alexei Karpenko 776222fd11 bugfix Studierendenverwaltung Projektarbeiten: correct default Stunden at all times 2025-09-12 13:52:21 +02:00
Alexei Karpenko 97f72caf90 Studierendenverwaltung Projektarbeiten: display of lv orgform only if present, hiding modal again after save, Betreuer can be edited after initial creation of Projektarbeit 2025-09-12 02:02:31 +02:00
Johann Hoffmann 48f7a04d81 wip abgabetool 2025-09-11 16:27:24 +02:00
chfhtw 6658e80d99 code quality 2025-09-11 14:58:20 +02:00
chfhtw ee6e7f3a48 finetuning drag&drop 2025-09-11 13:13:57 +02:00
chfhtw 112211fb0b move function 2025-09-11 13:11:34 +02:00
Alexei Karpenko 3a06dc613f Studierendenverwalung Projektarbeiten: preserve data before saved, modal not closed after saving 2025-09-10 17:28:15 +02:00
chfhtw 86bbfe42db missing break 2025-09-10 11:21:58 +02:00
chfhtw 455698b28e StV Groups Drag&Drop 2025-09-10 11:18:23 +02:00
Johann Hoffmann 4e598a321d wip add new abgabe wizard 2025-09-08 10:44:41 +02:00
chfhtw ff061a3e95 FhcAPI: expose getConfig function 2025-09-05 14:04:41 +02:00
chfhtw 1b76b852cf Merge branch 'master' into feature-63435/Studierendenverwaltung_Studierende_Verbandsgruppen_und_Spezialgruppen_zuordnen_Multiaktion 2025-09-05 14:02:48 +02:00
Andreas Österreicher 9067f0e00a Merge branch 'master' into feature-52533_62055/Vertragsverwaltung_mit_CoreComponent_DetailHeader 2025-09-05 12:48:33 +02:00
Andreas Österreicher 4099d91a1b Vertragsverwaltung - Filter korrigiert fuer aktive und inaktive
Mitarbeiter
2025-09-05 12:45:39 +02:00
Johann Hoffmann 49ca538381 student page redesign; wip mitarbeiter page + add new modal 2025-09-04 17:38:32 +02:00
Johann Hoffmann 5f1c7537fb WIP 2025-09-04 11:04:12 +02:00
Cristina ed747fe07c Merge remote-tracking branch 'origin/epic-56039/LV-Evaluierung' into epic-56039/LV-Evaluierung
# Conflicts:
#	application/models/education/Lehrveranstaltung_model.php
2025-09-03 15:26:39 +02:00
Cristina 10d58d1a42 Added column prestudent_id to getStudentsByLv method query in Lehrveranstaltung_model.php 2025-09-03 15:24:44 +02:00
Cristina fd2ff27e22 Added column prestudent_id to getStudentsByLv method query in Lehrveranstaltung_model.php 2025-09-03 15:24:07 +02:00
Cristina 594333889d Merge branch 'epic-56039/LV-Evaluierung_NEU' of https://github.com/FH-Complete/FHC-Core into epic-56039/LV-Evaluierung
# Conflicts:
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2025-09-03 15:14:53 +02:00
Cristina 174ed990a7 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-09-03 13:06:47 +02:00
chfhtw 61cfb175e3 use undefined to avoid VueJs warning 2025-09-03 11:06:09 +02:00
ma0068 1bb10ddeb1 refactor backend filter 2025-09-03 10:43:20 +02:00
ma0068 49e89f44be set default domain to fhcomplete.info 2025-09-02 20:37:20 +02:00
ma0068 e5cf417ac0 adapt headerFilter, remove frontend filter, add backend filter aktiv mitarbeiter 2025-09-02 20:29:23 +02:00
chfhtw 86641ea02d StV: Lehrverband- & Special-groups 2025-09-02 16:06:04 +02:00
chfhtw eae79e9f5e CSS fix: primevue autocomplete inside bootstrap input-group 2025-09-02 16:04:47 +02:00
chfhtw b378649b06 add validation "is_in_db" 2025-09-02 16:04:02 +02:00
Alexei Karpenko fc845ebf4e Studierendenverwaltung Projektarbeit: separate saving of Projektarbeit and Betreuer, added action for editing Betreuer 2025-09-02 15:04:45 +02:00
Johann Hoffmann a560c335b8 WIP responsive tabulator collapse abgabetool; paabgabe notiz column; 2025-09-02 13:35:42 +02:00
ma0048 ba6224bc78 oeh betrag aus der eigener tabelle holen
studentenverwaltung bei jedem studiensemester wechsel
fas nur einmalig ueber die variable
2025-09-02 11:18:24 +02:00
ma0068 ea85cce957 own controller detailHeader, bugfix loadDepartmentdata 2025-09-01 09:37:30 +02:00
Johann Hoffmann 1f0fe08b69 upload_required => allowed; hardcoded links => config; styling; endupload/qualgate logic; phrasen; 2025-08-29 14:15:20 +02:00
ma0068 3cdb391a6d use helper file instead of private function for building dropdown entry 2025-08-28 14:29:26 +02:00
ma0068 7b187ebadd add Dropdown for Multiaction Print
add Event for adding Documents to PrintArray
add Berechtigung hasPermissionOutputformat to enable Print for odt and doc Formats (documents abschlusspruefung)
add Validations
2025-08-28 11:05:04 +02:00
ma0068 3a5c4444cb Tab Archive: Documentdropdown for Printing
- define structure for single print array
- fill array with documents according to Fas Dropdown Drucken
- event for adding documents from extension/addons
2025-08-27 14:11:03 +02:00
Johann Hoffmann 63390b192c qualgate 1&2 dbupdate script, note fkey reference & upload required flag in paabgabe; noten api duplicate from notentool for now; WIP more emails; qualgates benotbar & saveable aswell as upload flag; 2025-08-26 17:15:37 +02:00
Johann Hoffmann e97c26022f Merge remote-tracking branch 'origin/master' into feature-61164/AbgabetoolQualityGates 2025-08-25 12:00:30 +02:00
Alexei Karpenko ce9a4e2e09 Merge branch 'feature-60973/komponente_fuer_lehrfaecherverteilung' into feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren 2025-08-23 16:16:41 +02:00
Johann Hoffmann 483662726d abgabetool api/controller refactor; quality gates dbupdate script; load types from backend instead of hardcoded; WIP email check for externe betreuer; 2025-08-22 14:40:58 +02:00
chfhtw 9b8ac595c6 Code Quality 2025-08-21 12:59:24 +02:00
chfhtw 608e2b5171 Implement: stv/students/getGemeinsamestudien 2025-08-21 09:18:52 +02:00
chfhtw 7de81fab7d Implement: stv/students/getOutgoing 2025-08-20 17:00:14 +02:00
chfhtw c9104749c5 Faster Query for stv/students/getIncoming 2025-08-20 16:52:16 +02:00
chfhtw 5ba0007641 fix: correct relative priority calculation 2025-08-20 14:34:19 +02:00
chfhtw 923427b41f Implement: stv/students/getIncoming 2025-08-20 11:57:31 +02:00
chfhtw 31a5caa558 better (safer) output for semester verband gruppe prio 2025-08-20 11:56:29 +02:00
chfhtw b73eac62b5 add studiensemester param to incoming/outgoing/gs backend 2025-08-20 11:54:01 +02:00
ma0068 6ee3f1d241 show Bezeichnung in Subject Vorlage, add adaption for Tinymce for openMode inSamePage 2025-08-20 11:32:31 +02:00
Andreas Österreicher 703872adc9 Merge branch 'master' into feature-52533_62055/Vertragsverwaltung_mit_CoreComponent_DetailHeader 2025-08-20 11:14:40 +02:00
chfhtw ca3f8bc554 move statusofsemester select into shared function 2025-08-19 11:24:51 +02:00
Harald Bamberger e2d6e5d9c8 Merge branch 'master' into feature-39571/Studierendenverwaltung_CoreNotizcontroller 2025-08-14 18:38:04 +02:00
Cristina bbf147ec39 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-08-14 11:37:57 +02:00
Alexei Karpenko 75adcefd51 Studentenverwaltung Projektarbeit: made text input possible for all date input 2025-07-21 17:52:21 +02:00
ma0048 4a8868a709 verfasser nur noch readonly - wird im backend gesetzt 2025-07-21 15:29:57 +02:00
Cristina 94e25da6c8 Added phrases for lvevaluierung 2025-07-16 16:13:27 +02:00
Cristina 430da0b236 Merge branch 'master' into epic-56039/LV-Evaluierung_NEU 2025-07-16 11:22:42 +02:00
Cristina c61f87a8d5 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-07-16 11:21:58 +02:00
Alexei Karpenko 01a3dc1fd0 Studierendenverwaltung archiv: removed tabulator columns from computed 2025-07-15 23:08:12 +02:00
Alexei Karpenko 1f258c84d4 Studierendenverwaltung Projektarbeit: moved Beurteilung download to table actions, separate tabs for details and Betreuer 2025-07-15 18:56:49 +02:00
Alexei Karpenko caa70715ad Merge branch 'merge_FHC4_55354_55991_55992_60874_60876_60875_61229_61230_61231' into feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren 2025-07-15 15:24:30 +02:00
Alexei Karpenko 325cbf9314 Merge branch 'master' into feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren 2025-07-15 12:44:55 +02:00
Alexei Karpenko 4eaf71e5c6 cancel Vertrag: correct error handling 2025-07-14 17:01:16 +02:00
ma0068 10399db372 add handling comma in combination with titelpost 2025-07-14 09:42:41 +02:00
Alexei Karpenko 1c8ffa786e Studierendenverwaltung Projektarbeit improvements: tabulator (supposedly) stores column changes, changed some phrases, projektarbeit download button is now shown when Projektbeurteilung extension is not installted, errors are displayed near input fields not in pop up, changed modal layout, Vertrag fields are now just text fields, validation errors are cleared 2025-07-10 16:59:58 +02:00
ma0068 179b50c798 fixed js-warnings
- Extraneous non-props attributes
 - duplicate html code
 - html template error
2025-07-10 14:27:54 +02:00
ma0068 ec1960e839 Bugfix: Delete Vertragsstatus if Betreuung 2025-07-10 13:33:54 +02:00
ma0068 a942423e84 remove unused code 2025-07-10 12:44:35 +02:00
ma0048 153e273fec firefox check entfernt 2025-07-09 13:52:46 +02:00
Alexei Karpenko abbeec11fc Studierendenverwaltung Projektarbeit: date value ende and gesperrt bis can be saved, full type name is shown in Projektarbeit table, made "kontaktdaten bearbeiten" and "person anlegen" buttons less prominent, bugfix cancel contract: contract display is updated immediately 2025-07-08 15:35:46 +02:00
ma0068 3ca49c5574 refactor function getHeader, get mitarbeiter_uid as prop instead of using function getMitarbeiterUid 2025-07-08 15:01:54 +02:00
Alexei Karpenko 549f7867ae Kontakt component permission: possible to check if a person is neither student nor employee 2025-07-03 15:26:53 +02:00
Alexei Karpenko 3e924b62a6 Studentenverwaltung new person: errors are shown in fields, not as popup 2025-07-03 15:26:03 +02:00
ma0068 d1e35b1851 bugfix js error after sort: take out persistance for header filter 2025-07-03 12:14:00 +02:00
ma0068 46a10bd92e page handling
- entry in main navigation menu
- import navigation component
- remove space side menu
2025-07-03 11:14:20 +02:00
ma0068 b4d5e1c90a bugfix delete Vertragsdetails, add missing data updateamum, updatevon 2025-07-02 13:41:08 +02:00
Cristina 0df082af1f Merge branch 'master' into epic-56039/LV-Evaluierung_NEU 2025-07-02 12:16:19 +02:00
Cristina b3c05f2fe1 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-07-02 12:15:21 +02:00
Cristina 56bfe46675 Added phrases for lvevaluierung 2025-07-02 12:12:44 +02:00
ma0068 411b97fa14 reload Vertragsstatus if change of mitarbeiter 2025-07-02 11:54:32 +02:00
ma0068 56e8a34d68 readd Phrasen Vertragsverwaltung 2025-07-02 09:09:33 +02:00
Cristina daf9d2ea15 Added checkbox 'evaluierung' Lehrveranstaltung Details in VILESCI 2025-06-25 13:35:20 +02:00
Cristina 4b8af46a2e Added 'evaluierung' to lehrveranstaltung.class.php and updated related methods 2025-06-25 13:30:05 +02:00
Cristina fd2de106f8 Added column evaluierung to lehre.tbl_lehrveranstaltung
- evaluierung (boolean) indicates if lehrveranstaltung shall be evaluated. Default is true.
2025-06-24 15:02:45 +02:00
Cristina 08182fe0f5 Added phrases for LV-Evaluierung 2025-06-23 15:51:30 +02:00
Andreas Österreicher 02df06288e Bugfix Rückstellgrund 2025-06-16 11:37:04 +02:00
Andreas Österreicher ce47579870 Merge branch 'master' into feature-55978/infocenter_electronic_onboarding_filter 2025-06-16 11:35:49 +02:00
Cristina 1e32bc211b Merge branch 'master' into epic-56039/LV-Evaluierung_NEU 2025-06-16 09:36:04 +02:00
Cristina 1f8d87587d Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-06-16 09:35:29 +02:00
Alexei Karpenko d15d27b3e1 Studierendenverwaltung Projektarbeit: added Verträge 2025-06-13 16:19:53 +02:00
ma0068 8c69bc1682 Headerfunctions in headerAPI auslagern 2025-06-11 15:28:19 +02:00
ma0068 2eef05e593 - refactore POST_Variablen with form_validation->set_data
- add phrase: Vertragsstatus bearbeiten
- filterActive: bugfix
2025-06-11 15:02:31 +02:00
ma0068 a56a804692 - fix error with Event 'multiActionPrintHonorarvertrag'
- Naming components Vertragsverwaltung, MitarbeiterHeader, CoreListMitarbeiter
- link to Vorgesetzter, show Vorgesetzter without postTitel
- Foto: if foto_sperre: show foto with lock
2025-06-11 13:46:23 +02:00
Alexei Karpenko e26bce2cf7 removed merge text from code 2025-06-10 14:14:32 +02:00
Alexei Karpenko 6f5fa9624f Merge branch 'feature-60973/komponente_fuer_lehrfaecherverteilung' into feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren 2025-06-10 13:58:50 +02:00
ma0068 a8f47fad45 copy Component DetailHeader into Vertragsverwaltung 2025-06-10 13:10:26 +02:00
ma0068 6f60d7c99e API Refactoring, some other minor fixes 2025-06-10 11:57:43 +02:00
ma0068 7d2da9e7f6 Merge master into feature-52533_62055/Vertragsverwaltung_mit_CoreComponent_DetailHeader 2025-06-06 11:46:31 +02:00
Alexei Karpenko fe81e7fb7c Studierendenverwaltung Projektarbeit: added button for Projektarbeit download 2025-06-03 21:18:03 +02:00
Alexei Karpenko 750b956dd2 Studentenverwaltung Projektarbeit: added button for editing contact data 2025-06-02 15:28:10 +02:00
Alexei Karpenko 9a7cba0717 Studentenverwaltung Projektarbeit: added possibility to create persons, added phrases 2025-05-30 17:54:51 +02:00
Cristina 5ee72fd836 Merge branch 'master' into epic-56039/LV-Evaluierung_NEU 2025-05-27 18:23:51 +02:00
Cristina 4f8c408a8a Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-05-27 18:22:45 +02:00
Alexei Karpenko 69e05ccb38 Studentenverwaltung archive: switched to new api factory 2025-05-24 10:14:08 +02:00
Alexei Karpenko 1ca5bd5691 Studierendenverwaltung Projektarbeit: added phrases, only necessary Projektarbeit properties are set when saving 2025-05-21 22:00:04 +02:00
Harald Bamberger 8925692dd4 Merge branch 'master' into feature-39571/Studierendenverwaltung_CoreNotizcontroller 2025-05-21 17:03:58 +02:00
Alexei Karpenko d1c2cf8e64 Merge branch 'master' into feature-61232/Studierendenverwaltung_Karteireiter_Projektarbeit_portieren 2025-05-19 13:22:05 +02:00
Alexei Karpenko 7548d7b55f Projektbetreuer: new and edit mode 2025-05-18 16:35:30 +02:00
Alexei Karpenko 168e2890c7 Studierendenverwaltung Projektarbeit: set default stunden value, correct lvs when new Projektarbeit, Projektarbetreuer form hidden by default 2025-05-18 15:55:43 +02:00
Alexei Karpenko 4cf2ef2927 removed console logs 2025-05-16 13:40:47 +02:00
Alexei Karpenko 382006aa8b Projektarbeit Studierendenverwaltung: now possible to save and edit Projektbetreuer 2025-05-16 13:37:21 +02:00
Alexei Karpenko 405062f549 added Projektarbeit tab to Studierendenverwaltung, adding, editing, deleting of Projektarbeiten now possible 2025-05-07 18:36:51 +02:00
Cristina d4feee8914 Fixed wrong param causing wrong Notenliste for Wiederholer 2025-03-18 14:30:19 +01:00
Paolo bb476bb257 Merge branch 'master' into bug-56209/is_valid_date_vs_isValidDate 2025-03-12 11:54:50 +01:00
Paolo 7b74c36952 - Removed public method isValidDate from controller api/frontend/v1/studstatus/Unterbrechung
- Replaced callback_isValidDate with is_valid_date
- Removed global function isValidDate from helpers/hlp_common_helper
2025-02-27 12:09:30 +01:00
ma0068 31af28a7c4 Merge branch 'feature-52533/PV21_Karteireiter_Vertraege' of github.com:FH-Complete/FHC-Core into feature-52533/PV21_Karteireiter_Vertraege 2025-02-19 16:37:47 +01:00
ma0068 f3527dc8ff bugfix function getMitarbeiterUid 2025-02-19 16:37:30 +01:00
ma0068 660f9076ce delete commented out sections 2025-02-14 09:38:33 +01:00
ma0068 24682fb559 changeFormat Dates, use different select for MitarbeiterHeader before PV21, adapt condition for multiselect addon 2025-02-12 17:05:18 +01:00
ma0048 bc48445304 - infocenter filter fuer electronic onboarding hinzugefuegt 2025-02-10 13:05:44 +01:00
ma0068 295e2aa3e5 adaptions styling 2025-01-22 11:17:09 +01:00
ma0068 0d0071e8bf refactoring and codesniff 2025-01-22 07:57:39 +01:00
ma0068 9c0baeacf2 Add Logic Permission and Phrases 2025-01-21 15:34:43 +01:00
ma0068 ffc99379ae Injection ADDON KU for Multiselect and Print Honorarvertrag 2025-01-20 15:25:06 +01:00
ma0068 35d8f0524d new page vertragsverwaltung with employee header and details components 2025-01-15 13:56:00 +01:00
ma0068 07e6146e50 Validations, Phrases, cleanup 2024-11-19 14:34:50 +01:00
ma0068 5751441424 filter offene Vertraege, validations insert, update Contract 2024-11-12 07:57:46 +01:00
ma0068 023fafde2c update reload functions, adapt delete contract, add watcher in unassignedList 2024-11-11 10:37:51 +01:00
ma0068 2d0285e31d add and update Lehrauftraege, logic sumup beträge 2024-11-08 13:29:19 +01:00
ma0068 9fd9c4e94d edit Status Contracts 2024-11-06 11:43:59 +01:00
ma0068 40baa7e08c update childcomponent vertragstati 2024-11-05 16:06:14 +01:00
ma0068 b1452698f8 Start View Karteireiter, Components Unassigned, Details and Stati 2024-11-04 12:54:34 +01:00
cgfhtw d542cf7720 s&d 2024-08-14 16:20:47 +02:00
ma0068 6e9ee7cf81 Notizcomponent: Api Controller for Notizzuordnungs_ids 2024-05-03 09:43:49 +02:00
432 changed files with 45141 additions and 7948 deletions
@@ -0,0 +1,36 @@
<?php
$filterCmptArray = array(
"app" => 'core',
'datasetName' => 'vertragsverwaltung',
'query' => '
SELECT
uid,
person_id,
vorname,
nachname,
gebdatum,
vertragsarten,
unternehmen,
ids,
aktiv
FROM
(
SELECT
b.uid , p.person_id,
p.vorname, p.nachname,
gebdatum,
STRING_AGG(DISTINCT va.bezeichnung, \', \') AS Vertragsarten,
STRING_AGG(DISTINCT u.bezeichnung, \', \') AS Unternehmen,
STRING_AGG(d.dienstverhaeltnis_id::TEXT, \', \') AS ids,
b.aktiv
FROM
hr.tbl_dienstverhaeltnis d
JOIN public.tbl_benutzer b ON d.mitarbeiter_uid = b.uid
JOIN public.tbl_person p ON p.person_id = b.person_id
JOIN public.tbl_organisationseinheit u ON d.oe_kurzbz = u.oe_kurzbz
JOIN hr.tbl_vertragsart va ON d.vertragsart_kurzbz = va.vertragsart_kurzbz
GROUP BY b.uid, p.person_id, p.vorname, p.nachname, b.aktiv
) as vertragsdaten
',
'requiredPermissions' => 'vertrag/mitarbeiter'
);
+12 -12
View File
@@ -6,30 +6,30 @@ use CI3_Events as Events;
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["lehreinheit"] = array(
'calendarEvent' => APP_ROOT.'public/js/components/Cis/Renderer/Lehreinheit/calendarEvent.js',
'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Lehreinheit/modalTitle.js',
'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Lehreinheit/modalContent.js',
'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css'
'calendarEvent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Lehreinheit/calendarEvent.js'),
'modalTitle' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Lehreinheit/modalTitle.js'),
'modalContent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Lehreinheit/modalContent.js'),
'calendarEventStyles' => APP_ROOT . 'public/css/Cis4/CoreCalendarEvents.css'
);
});
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["reservierung"] = array(
'calendarEvent' => APP_ROOT.'public/js/components/Cis/Renderer/Reservierungen/calendarEvent.js',
'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Reservierungen/modalTitle.js',
'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Reservierungen/modalContent.js',
'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css'
'calendarEvent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Reservierungen/calendarEvent.js'),
'modalTitle' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Reservierungen/modalTitle.js'),
'modalContent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Reservierungen/modalContent.js'),
'calendarEventStyles' => APP_ROOT . 'public/css/Cis4/CoreCalendarEvents.css'
);
});
Events::on('loadRenderers', function ($renderers) {
$fhc_core_renderers =& $renderers();
$fhc_core_renderers["ferien"] = array(
'calendarEvent' => APP_ROOT.'public/js/components/Cis/Renderer/Feiertage/calendarEvent.js',
'modalTitle' => APP_ROOT.'public/js/components/Cis/Renderer/Feiertage/modalTitle.js',
'modalContent' => APP_ROOT.'public/js/components/Cis/Renderer/Feiertage/modalContent.js',
'calendarEventStyles' => APP_ROOT.'public/css/Cis4/CoreCalendarEvents.css'
'calendarEvent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Feiertage/calendarEvent.js'),
'modalTitle' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Feiertage/modalTitle.js'),
'modalContent' => absoluteJsImportUrl('public/js/components/Cis/Renderer/Feiertage/modalContent.js'),
'calendarEventStyles' => APP_ROOT . 'public/css/Cis4/CoreCalendarEvents.css'
);
});
+45
View File
@@ -0,0 +1,45 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
$config['turnitin_link'] = 'https://technikum-wien.turnitin.com/sso/sp/redwood/saml/5IyfmBr2OcSIaWQTKlFCGj/start';
$config['old_abgabe_beurteilung_link'] = 'https://moodle.technikum-wien.at/mod/page/view.php?id=1005052';
$config['PAABGABE_EMAIL_JOB_INTERVAL'] = '1 day';
// used as APP_ROOT.URL_STUDENTS -> cis4
$config['URL_STUDENTS'] = 'cis.php/Cis/Abgabetool/Student';
// used as APP_ROOT.URL_MITARBEITER -> old cis
$config['URL_MITARBEITER'] = 'index.ci.php/Cis/Abgabetool/Mitarbeiter';
// used as APP_ROOT.URL_MITARBEITER -> old cis
$config['URL_ASSISTENZ'] = 'index.ci.php/Cis/Abgabetool/Assistenz';
// lehre.tbl_paabgabetyp bezeichnung
//$config['ALLOWED_ABGABETYPEN_BETREUER'] = ['Zwischenabgabe', 'Quality Gate 1', 'Quality Gate 2'];
$config['ALLOWED_ABGABETYPEN_BETREUER'] = ['abstract','zwischen', 'qualgate1', 'qualgate2']; // tbl_paabgabetyp pk
// paabgabetypen for which betreuer is benachrichtigt via sammelmail
$config['RELEVANT_PAABGABETYPEN_SAMMELMAIL_BETREUER'] = ['qualgate1', 'qualgate2', 'end'];
// paabgabetypen for which assistenz is benachrichtigt via sammelmail
$config['RELEVANT_PAABGABETYPEN_SAMMELMAIL_ASSISTENZ'] = ['end'];
// paabgabetypen for which student is benachrichtigt via sammelmail -> basically all of them but still defined for consistency
$config['RELEVANT_PAABGABETYPEN_SAMMELMAIL_STUDENT'] = ['qualgate1', 'qualgate2', 'zwischen', 'note', 'abstract', 'end', 'enda'];
//$config['ALLOWED_NOTEN_ABGABETOOL'] = ['Bestanden', 'Nicht bestanden'];
$config['ALLOWED_NOTEN_ABGABETOOL'] = [10, 14]; // tbl_note pk
// benotete projektarbeiten sperren weitere terminanlage & bearbeitung, diese noten sind ausnahmen dieser Regel
// wie zB "Nicht beurteilt" & "Noch nicht eingetragen"
$config['NONFINAL_NOTEN_ABGABETOOL'] = [9];
$config['beurteilung_link_fallback'] = 'addons/fhtw/content/projektbeurteilung/projektbeurteilungDocumentExport.php?projektarbeit_id=?&betreuerart_kurzbz=?&person_id=?';
$config['PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ERSTBEGUTACHTER'] = 'index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter';
$config['PROJEKTARBEITSBEURTEILUNG_MAIL_BASELINK_ZWEITBEGUTACHTER'] = 'index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter';
$config['SIGNATUR_CHECK_PAABGABETYPEN'] = ['end'];
// to be used as "https://moodle.technikum-wien.at/course/view.php?idnumber=dl{$stg_kz}" for stg specific moodle routing
$config['STG_MOODLE_LINK'] = 'https://moodle.technikum-wien.at/course/view.php?idnumber=dl';
$config['ASSISTENZ_SAMMELMAIL_BUTTON_STUDENT'] = true;
$config['ASSISTENZ_SAMMELMAIL_BUTTON_BETREUER'] = true;
$config['BETREUER_SAMMELMAIL_BUTTON_STUDENT'] = true;
+1 -1
View File
@@ -4,7 +4,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
// CMS Content Id for CIS4 Menu Root
$config['cis_menu_root_content_id'] = 11087;
$config['cis_menu_root_content_id'] = 11091;
// send Mails for ProfilUpdate
$config['cis_send_profil_update_mails'] = true;
// Vilesci CI BaseUrl
+3
View File
@@ -7,3 +7,6 @@ $config['use_vuejs_dev_version'] = false;
$config['use_bundled_javascript'] = false;
// systemerror_mailto use in FHC-Alert Plugin - if empty Link will not be rendered
$config['systemerror_mailto'] = '';
// use fhcomplete_build_version as path element after public (requires apache mod_rewrite)
// see <fhc_base_dir>/public/.htaccess_sample for details
$config['use_fhcomplete_build_version_in_path'] = false;
+48 -1
View File
@@ -163,6 +163,13 @@ $config['navigation_header'] = array(
'expand' => true,
'sort' => 50,
'requiredPermissions' => 'lehre/gruppenmanager:r'
),
'vertragsverwaltung' => array(
'link' => site_url('vertragsverwaltung'),
'description' => 'Vertragsverwaltung',
'expand' => true,
'sort' => 51,
'requiredPermissions' => 'vertrag/mitarbeiter:r'
)
)
),
@@ -201,7 +208,14 @@ $config['navigation_header'] = array(
'expand' => true,
'sort' => 30,
'requiredPermissions' => 'lehre/anrechnungszeitfenster:rw'
)
),
'dashboardadmin' => array(
'link' => site_url('dashboard/Admin'),
'description' => 'Dashboard Admin',
'expand' => true,
'sort' => 40,
'requiredPermissions' => 'dashboard/admin:r'
)
)
)
)
@@ -335,4 +349,37 @@ $config['navigation_menu']['system/issues/Issues/*'] = array(
'target' => '_blank',
'requiredPermissions' => array('admin:rw')
),
);
$config['navigation_menu']['vertragsverwaltung/*'] = array(
'vertragsverwaltung' => array(
'link' => site_url('vertragsverwaltung'),
'description' => 'Vertragsverwaltung',
'icon' => 'home',
'sort' => 100,
'target' => '_blank',
'requiredPermissions' => array('vertrag/mitarbeiter:r')
)
);
$config['navigation_menu']['apps'] = [
'stv' => [
'link' => site_url('studentenverwaltung'),
'description' => 'Studierendenverwaltung',
#'icon' => 'users',
'requiredPermissions' => array('admin:r', 'assistenz:r')
],
'lvv' => [
'link' => site_url('lVVerwaltung'),
'description' => 'LV Verwaltung',
#'icon' => 'person-chalkboard',
'requiredPermissions' => array('admin:r', 'assistenz:r')
],
'lav' => [
'link' => site_url('lehre/lehrauftrag/Lehrauftrag/Dashboard'),
'description' => 'Lehraufträge',
#'icon' => 'person-chalkboard',
'requiredPermissions' => array('lehre/lehrauftrag_bestellen:r', 'lehre/lehrauftrag_erteilen:r')
]
];
+12 -5
View File
@@ -1,6 +1,6 @@
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
if (! defined('BASEPATH')) exit('No direct script access allowed');
/*
| -------------------------------------------------------------------------
@@ -51,7 +51,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| my-controller/my-method -> my_controller/my_method
*/
$route['default_controller'] = defined('CIS4') && CIS4 ? 'Cis4' : 'Vilesci';
$route['translate_uri_dashes'] = FALSE;
$route['translate_uri_dashes'] = false;
// Class name conflicts
$route['api/v1/organisation/[S|s]tudiengang/(:any)'] = 'api/v1/organisation/studiengang2/$1';
@@ -65,15 +65,22 @@ $route['Cis/LvPlan/.*'] = 'Cis/LvPlan/index/$1';
$route['Cis/MyLvPlan/.*'] = 'Cis/MyLvPlan/index/$1';
$route['Cis/MyLv/.*'] = 'Cis/MyLv/index/$1';
$route['Abgabetool/Assistenz'] = 'Cis/Abgabetool/Assistenz';
$route['Abgabetool/Assistenz/(:any)'] = 'Cis/Abgabetool/Assistenz/$1';
$route['Abgabetool/Mitarbeiter'] = 'Cis/Abgabetool/Mitarbeiter';
$route['Abgabetool/Student'] = 'Cis/Abgabetool/Student';
$route['Abgabetool/Student/(:any)'] = 'Cis/Abgabetool/Student/$1';
$route['Abgabetool/Deadlines'] = 'Cis/Abgabetool/Deadlines';
// Studierendenverwaltung List Routes
$route['api/frontend/v1/stv/[sS]tudents/inout'] = 'api/frontend/v1/stv/Students/index';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})'] = 'api/frontend/v1/stv/Students/index';
// (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';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/incoming'] = 'api/frontend/v1/stv/Students/getIncoming/$1';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/outgoing'] = 'api/frontend/v1/stv/Students/getOutgoing/$1';
$route['api/frontend/v1/stv/[sS]tudents/([WS]S[0-9]{4})/inout/gemeinsamestudien'] = 'api/frontend/v1/stv/Students/getGemeinsamestudien/$1';
// (studiengang_kz)/prestudent[/(studiensemester_kurzbz)[/(filter)[/(otherfilter)]]]
$route['api/frontend/v1/stv/[sS]tudents/(-?[0-9]+)/prestudent'] = 'api/frontend/v1/stv/Students/getPrestudents/$1';
+2 -2
View File
@@ -29,7 +29,7 @@ $config['similar'] = [
$config['vector'] = [
'priority' => 1,
'rank' => "ts_rank({field}, to_tsquery('simple', {word}))",
'compare' => "to_tsquery('simple', {word}) @@ {field}"
'rank' => "ts_rank({field}, plainto_tsquery('simple', {word}))",
'compare' => "plainto_tsquery('simple', {word}) @@ {field}"
];
+38
View File
@@ -7,5 +7,43 @@ $CI =& get_instance();
$config['student'] = $CI->config->item('student', 'search');
$config['student']['searchfields']['pkz'] = [
'alias' => ['personenkennzeichen', 'personalid'],
'comparison' => 'equals',
'field' => 'matrikelnr'
];
$config['student']['searchfields']['matrnr'] = [
'alias' => ['matrikelnr', 'matrikelnummer', 'matrno', 'matriculationno', 'matriculationnumber', 'studno', 'studentno', 'studentnumber'],
'comparison' => 'equals',
'field' => 'matr_nr',
'join' => [
[
'table' => "public.tbl_prestudent",
'using' => "prestudent_id"
],
[
'table' => "public.tbl_person",
'using' => "person_id"
]
]
];
$config['prestudent'] = $CI->config->item('prestudent', 'search');
$config['prestudent']['searchfields']['pkz'] = [
'alias' => ['personenkennzeichen', 'personalid'],
'comparison' => 'equals',
'field' => 'matrikelnr',
'join' => [
'table' => "public.tbl_student",
'using' => "prestudent_id"
]
];
$config['prestudent']['searchfields']['matrnr'] = [
'alias' => ['matrikelnr', 'matrikelnummer', 'matrno', 'matriculationno', 'matriculationnumber', 'studno', 'studentno', 'studentnumber'],
'comparison' => 'equals',
'field' => 'matr_nr',
'join' => [
'table' => "public.tbl_person",
'using' => "person_id"
]
];
+32 -2
View File
@@ -61,9 +61,13 @@ $config['tabs'] =
'notes' => [
//if true, the count of Messages will be shown in the header of the Tab Messages
'showCountNotes' => true
]
],
'combinePeople' => [
//multitab should only be shown with this length of selection
'validCountMulti' => 2,
],
];
// List of fields to show when ZGV_DOKTOR_ANZEIGEN is defined
$fieldsZgvDoktor = ['zgvdoktorort', 'zgvdoktordatum', 'zgvdoktornation', 'zgvdoktor_erfuellt', 'zgvdoktor_code'];
@@ -84,6 +88,16 @@ if (!defined('ZGV_DOKTOR_ANZEIGEN') || !ZGV_DOKTOR_ANZEIGEN) {
);
}
$config['tabs']['projektarbeit']['defaultProjektbetreuerStunden'] =
defined('FAS_STUDIERENDE_PROJEKTARBEIT_DEFAULT_BETREUER_STUNDEN_BACHELOR')
? FAS_STUDIERENDE_PROJEKTARBEIT_DEFAULT_BETREUER_STUNDEN_BACHELOR
: '0.0';
$config['tabs']['projektarbeit']['defaultProjektbetreuerStundenDiplom'] =
defined('FAS_STUDIERENDE_PROJEKTARBEIT_DEFAULT_BETREUER_STUNDEN_MASTER')
? FAS_STUDIERENDE_PROJEKTARBEIT_DEFAULT_BETREUER_STUNDEN_MASTER
: '0.0';
$config['tabs']['projektarbeit']['defaultProjektbetreuerStundensatz'] = '80.0';
$config['student_tab_order'] = [
'details',
'notes',
@@ -97,6 +111,7 @@ $config['student_tab_order'] = [
'grades',
'exam',
'exemptions',
'projektarbeit',
'finalexam',
'mobility',
'jointstudies',
@@ -109,7 +124,22 @@ $config['student_tab_order'] = [
$config['students_tab_order'] = [
'banking',
'status',
'messages',
'groups',
'finalexam',
'combinePeople',
'archive',
];
$config['stv_prestudent_tags'] = [
'prioone' => ['readonly' => false],
'priotwo' => ['readonly' => true],
'hinweis' => ['readonly' => false],
'hinweis_assistenz' => ['readonly' => true],
'hinweis_kf' => ['readonly' => true],
'hinweis_lehrende' => ['readonly' => false],
'hinweis_stg_kf' => ['readonly' => true],
'finished_stg' => ['readonly' => true],
'finished_kf' => ['readonly' => true],
'inwork_kf' => ['readonly' => true],
];
+39 -50
View File
@@ -14,10 +14,10 @@ class Abgabetool extends Auth_Controller
{
parent::__construct([
'index' => self::PERM_LOGGED,
'getStudentProjektarbeitAbgabeFile' => self::PERM_LOGGED,
'Mitarbeiter' => self::PERM_LOGGED,
'Student' => self::PERM_LOGGED,
'Deadlines' => self::PERM_LOGGED
'Mitarbeiter' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'),
'Assistenz' => array('basis/abgabe_assistenz:rw'),
'Student' => array('basis/abgabe_student:rw', 'basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw'),
'Deadlines' => array('basis/abgabe_lektor:rw', 'basis/abgabe_assistenz:rw')
]);
}
@@ -29,80 +29,69 @@ class Abgabetool extends Auth_Controller
*/
public function index()
{
// TODO: routing from index based on berechtigung?
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']);
if(defined('CIS4') && CIS4) {
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'Abgabetool']);
} else {
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'Abgabetool']);
}
}
public function Student()
public function Student($student_uid_prop = '')
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']);
if(defined('CIS4') && CIS4) {
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolStudent']);
} else {
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolStudent', 'student_uid_prop' => $student_uid_prop]);
}
}
public function Mitarbeiter()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolMitarbeiter']);
if(defined('CIS4') && CIS4) {
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolMitarbeiter']);
} else {
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolMitarbeiter']);
}
}
public function Assistenz($stg_kz_prop = '')
{
$viewData = array(
'uid'=>getAuthUID(),
);
if(defined('CIS4') && CIS4) {
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'AbgabetoolAssistenz']);
} else {
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'AbgabetoolAssistenz', 'stg_kz_prop' => $stg_kz_prop]);
}
}
public function Deadlines()
{
$viewData = array(
'uid'=>getAuthUID(),
);
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'DeadlinesOverview']);
}
public function getStudentProjektarbeitAbgabeFile()
{
$this->_ci =& get_instance();
$this->_ci->load->helper('download');
$paabgabe_id = $this->_ci->input->get('paabgabe_id');
$student_uid = $this->_ci->input->get('student_uid');
if (!isset($paabgabe_id) || isEmptyString($paabgabe_id) || !isset($student_uid) || isEmptyString($student_uid))
$this->terminateWithJsonError($this->p->t('global', 'wrongParameters'), 'general');
$this->_ci->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$isZugeteilterBetreuer = count($this->_ci->ProjektarbeitModel->checkZuordnung($student_uid, getAuthUID())->retval) > 0;
if(getAuthUID() == $student_uid || $isZugeteilterBetreuer) {
$file_path = PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf';
if(file_exists($file_path)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Disposition: attachment; filename="'.basename($file_path).'"');
header('Content-Length: ' . filesize($file_path));
flush(); // send headers first just in case
readfile($file_path); // read file content to output buffer
} else {
$this->terminateWithJsonError('File not found');
}
if(defined('CIS4') && CIS4) {
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'DeadlinesOverview']);
} else {
$this->terminateWithJsonError('Keine Zuordnung!');
$this->load->view('Cis/Abgabetool.php', ['uid' => getAuthUID(), 'route' => 'DeadlinesOverview']);
}
}
}
+1 -1
View File
@@ -72,7 +72,7 @@ class Documents extends Auth_Controller
$stgs = [];
$stsemArray = [];
$buchungstypen = implode('\',\'', defined("CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN") ? unserialize(CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN) : []);
$buchungstypen = defined("CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN") ? unserialize(CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN) : [];
$person_ids = [];
foreach ($stati as $status) {
$person_ids[] = $status->person_id;
-5
View File
@@ -33,9 +33,4 @@ class MyLv extends Auth_Controller
$this->load->view('CisRouterView/CisRouterView.php', ['viewData' => $viewData, 'route' => 'MyLv']);
}
public function Info($studien_semester,$lvid)
{
$this->load->view('Cis/LvInfo',['lvid'=> $lvid, 'studien_semester' => $studien_semester]);
}
}
+1 -1
View File
@@ -14,7 +14,7 @@ class Pub extends Auth_Controller
{
parent::__construct(
array(
'bild' => ['basis/cis:r']
'bild' => ['basis/cis:r', 'assistenz:r']
)
);
}
+8 -1
View File
@@ -20,11 +20,18 @@ class NeueNachricht extends Auth_Controller
*/
public function _remap()
{
$typeid = $this->input->post('typeid');
$ids = ($this->input->post('ids') && strpos($this->input->post('ids'), ','))
? explode(',', $this->input->post('ids'))
: $this->input->post('ids');
//now working
$this->load->view('Nachrichten', [
'permissions' => [
'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'),
]
],
'ids' => $ids,
'typeid' => $typeid
]);
}
}
@@ -28,10 +28,14 @@ class Studentenverwaltung extends Auth_Controller
'basis/prestudentstatus' => $this->permissionlib->isBerechtigt('basis/prestudentstatus'),
'assistenz_stgs' => $this->permissionlib->getSTG_isEntitledFor('assistenz'),
'admin' => $this->permissionlib->isBerechtigt('admin'),
'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz','suid'),
'assistenz_schreibrechte' => $this->permissionlib->isBerechtigt('assistenz', 'suid'),
'student/keine_studstatuspruefung' => $this->permissionlib->isBerechtigt('student/keine_studstatuspruefung'),
'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht'),
'system/change_outputformat' => $this->permissionlib->getOE_isEntitledFor('system/change_outputformat'),
'student/editBakkZgv' => $this->permissionlib->getSTG_isEntitledFor('student/editBakkZgv') ?: array(),
'student/editMakkZgv' => $this->permissionlib->getSTG_isEntitledFor('student/editMakkZgv') ?: array(),
'student/editDokZgv' => $this->permissionlib->getSTG_isEntitledFor('student/editDokZgv') ?: array(),
'student/editBismelden' => $this->permissionlib->isBerechtigt('student/editBismelden')
],
'variables' => [
'semester_aktuell' => $this->variablelib->getVar('semester_aktuell')
@@ -39,3 +43,5 @@ class Studentenverwaltung extends Auth_Controller
]);
}
}
@@ -0,0 +1,30 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Vertragsverwaltung extends Auth_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['vertrag/mitarbeiter:r'];
#$permissions[$router->method] = ['admin:rw'];
parent::__construct($permissions);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
/**
* @return void
*/
public function _remap()
{
$this->load->view('Vertragsverwaltung', [
'permissions' => [
'vertragsverwaltung_schreibrechte' => $this->permissionlib->isBerechtigt('vertrag/mitarbeiter', 'suid')
]
]);
}
}
File diff suppressed because it is too large Load Diff
@@ -208,7 +208,6 @@ class Documents extends FHCAPI_Controller
$this->load->model('system/Vorlage_model', 'VorlageModel');
$result = $this->VorlageModel->load($xsl);
$this->addMeta("ress", $result);
$vorlage = current($this->getDataOrTerminateWithError($result));
if (!$vorlage)
show_404();
@@ -221,7 +220,7 @@ class Documents extends FHCAPI_Controller
'gedruckt' => true,
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
'uid' => $this->input->post_get('uid') ?: '',
'uid' => $this->input->post_get('uid') ?: null,
'archiv' => true,
'signiert' => !!$sign_user,
'stud_selfservice' => $vorlage->stud_selfservice
@@ -251,6 +250,9 @@ class Documents extends FHCAPI_Controller
'studiensemester_kurzbz' => $ss,
'student_uid' => $akteData['uid']
]);
if (!hasData($result)) $this->terminateWithError($this->p->t("stv", "error_noLehrverbandAssigned"));
$res = current($this->getDataOrTerminateWithError($result));
$studiengang_kz = $res->studiengang_kz;
@@ -332,6 +334,7 @@ class Documents extends FHCAPI_Controller
if ($prestudent_id) {
$this->load->model('crm/prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addJoin('public.tbl_studiengang', 'studiengang_kz', 'LEFT');
$this->PrestudentModel->addSelect('tbl_prestudent.*, UPPER(typ || kurzbz) AS kuerzel');
$result = $this->PrestudentModel->load($prestudent_id);
$prestudent = current($this->getDataOrTerminateWithError($result));
@@ -442,6 +445,10 @@ class Documents extends FHCAPI_Controller
'betreuerart_kurzbz',
'studiensemester_kurzbz'
] as $key) {
if (in_array($xsl, array('Ausbildungsver', 'AusbVerEng')) && $key === 'uid')
{
continue;
}
$value = $this->input->post_get($key);
if ($value !== null)
$params .= '&' . $key . '=' . urlencode($value);
@@ -38,34 +38,9 @@ class Lehre extends FHCAPI_Controller
parent::__construct([
'lvStudentenMail' => self::PERM_LOGGED,
'LV' => self::PERM_LOGGED,
'Pruefungen' => self::PERM_LOGGED,
'getStudentProjektarbeiten' => self::PERM_LOGGED, // TODO: abgabetool berechtigung?
'getStudentProjektabgaben' => self::PERM_LOGGED,
'postStudentProjektarbeitZwischenabgabe' => self::PERM_LOGGED,
'postStudentProjektarbeitEndupload' => self::PERM_LOGGED,
'getMitarbeiterProjektarbeiten' => self::PERM_LOGGED,
'postProjektarbeitAbgabe' => self::PERM_LOGGED,
'deleteProjektarbeitAbgabe' => self::PERM_LOGGED,
'postSerientermin' => self::PERM_LOGGED,
'fetchDeadlines' => self::PERM_LOGGED // TODO: mitarbeiter recht prüfen
'Pruefungen' => self::PERM_LOGGED
]);
$this->load->library('PhrasesLib');
$this->loadPhrases(
array(
'global',
'ui',
'abgabetool'
)
);
$this->load->helper('hlp_sancho_helper');
require_once(FHCPATH . 'include/studiengang.class.php');
require_once(FHCPATH . 'include/student.class.php');
require_once(FHCPATH . 'include/projektarbeit.class.php');
require_once(FHCPATH . 'include/projektbetreuer.class.php');
}
//------------------------------------------------------------------------------------------------------------------
@@ -125,557 +100,5 @@ class Lehre extends FHCAPI_Controller
$this->terminateWithSuccess($result);
}
/**
* fetches all projektabgabetermine for a given projektarbeit_id used in cis4 student abgabetool
*/
public function getStudentProjektabgaben() {
$projektarbeit_id = $this->input->get("projektarbeit_id",TRUE);
// TODO: error messages
if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
$projektarbeit_obj = new projektarbeit();
if($projektarbeit_id==-1)
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
if(!$projektarbeit_obj->load($projektarbeit_id))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
$paIsCurrent = $projektarbeit_obj->projektarbeitIsCurrent($projektarbeit_id);
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$ret = $this->ProjektarbeitModel->getProjektarbeitAbgabetermine($projektarbeit_id);
// TODO: fetch zweitbetreuer
$this->terminateWithSuccess(array($ret, $paIsCurrent));
}
/**
* fetches all projektarbeiten and betreuer for a given student_uid used in cis4 student abgabetool
*/
public function getStudentProjektarbeiten($uid)
{
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
if (!isset($uid) || isEmptyString($uid))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
$isZugeteilterBetreuer = count($this->ProjektarbeitModel->checkZuordnung($uid, getAuthUID())->retval) > 0;
$this->addMeta('isZugeteilterBetreuer', $isZugeteilterBetreuer);
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter(getAuthUID());
if ($isMitarbeiter && $isZugeteilterBetreuer){
$projektarbeiten = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer($uid);
} else {
$projektarbeiten = $this->ProjektarbeitModel->getStudentProjektarbeitenWithBetreuer(getAuthUID());
}
$this->terminateWithSuccess(array($projektarbeiten, DOMAIN, $uid));
}
/**
* projektarbeit - upload for zwischenabgaben in cis4 student abgabetool
*/
public function postStudentProjektarbeitZwischenabgabe()
{
$projektarbeit_id = $_POST['projektarbeit_id'];
$paabgabe_id = $_POST['paabgabe_id'];
$student_uid = $_POST['student_uid'];
$bperson_id = $_POST['bperson_id'];
$paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz'];
if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id)
|| !isset($paabgabe_id) || isEmptyString($paabgabe_id)
|| !isset($student_uid) || isEmptyString($student_uid)
|| !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
if ((isset($_FILES) and isset($_FILES['file']) and ! $_FILES['file']['error'])) {
move_uploaded_file($_FILES['file']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf');
if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf')) {
exec('chmod 640 "'.PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf'.'"');
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$res = $this->PaabgabeModel->update($paabgabe_id, array(
'abgabedatum' => date('Y-m-d'),
'updatevon' => getAuthUID(),
'updateamum' => date('Y-m-d H:i:s')
));
$this->sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid);
$this->terminateWithSuccess($res);
} else {
$this->terminateWithError('Error moving File');
}
} else {
$this->terminateWithError('File missing');
}
}
/**
* upload für finale abgaben aka Endupload in cis4 student abgabetool
*/
public function postStudentProjektarbeitEndupload()
{
$projektarbeit_id = $_POST['projektarbeit_id'];
$paabgabe_id = $_POST['paabgabe_id'];
$student_uid = $_POST['student_uid'];
$sprache = $_POST['sprache'];
$abstract = $_POST['abstract'];
$abstract_en = $_POST['abstract_en'];
$schlagwoerter = $_POST['schlagwoerter'];
$schlagwoerter_en = $_POST['schlagwoerter_en'];
$seitenanzahl = $_POST['seitenanzahl'];
$bperson_id = $_POST['bperson_id'];
$paabgabetyp_kurzbz = $_POST['paabgabetyp_kurzbz'];
if (!isset($projektarbeit_id) || isEmptyString($projektarbeit_id)
|| !isset($paabgabe_id) || isEmptyString($paabgabe_id)
|| !isset($student_uid) || isEmptyString($student_uid)
|| !isset($paabgabetyp_kurzbz) || isEmptyString($paabgabetyp_kurzbz))
$this->terminateWithError($this->p->t('global', 'wrongParameters'), 'general');
// TODO: maybe check for other params aswell?
if ((isset($_FILES) and isset($_FILES['file']) and ! $_FILES['file']['error'])) {
move_uploaded_file($_FILES['file']['tmp_name'], PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf');
if(file_exists(PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf')) {
// Loads Libraries
$this->load->library('SignatureLib');
// Check if the document is signed
$signaturVorhanden = true;
$signList = SignatureLib::list(PAABGABE_PATH.$paabgabe_id.'_'.$student_uid.'.pdf');
if (is_array($signList) && count($signList) > 0)
{
// The document is signed
$uploadedDocumentSigned = 'The document is signed';
}
elseif ($signList === null)
{
$uploadedDocumentSigned = 'WARNING: signature server error';
}
else
{
$signaturVorhanden = false;
$uploadedDocumentSigned = 'No document signature found';
}
$this->addMeta('signaturInfo', $uploadedDocumentSigned);
if ($signaturVorhanden === false)
{
$this->signaturFehltEmail($student_uid);
}
// TODO error handle get data has data the updates
// update projektarbeit cols
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$this->ProjektarbeitModel->updateProjektarbeit($projektarbeit_id,$sprache,$abstract,$abstract_en
,$schlagwoerter, $schlagwoerter_en, $seitenanzahl);
// update paabgabe datum
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$res = $this->PaabgabeModel->update($paabgabe_id, array(
'abgabedatum' => date('Y-m-d'),
'updatevon' => getAuthUID(),
'updateamum' => date('Y-m-d H:i:s')
));
$this->sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid);
$this->terminateWithSuccess($res);
} else {
$this->terminateWithError('Error moving File');
}
} else {
$this->terminateWithError('File missing');
}
}
private function signaturFehltEmail($student_uid) {
// Mail an Studiengang wenn keine Signatur gefunden wurde
$student = new student();
if(!$student->load($student_uid))
$this->terminateWithError($this->p->t('global','userNichtGefunden'), 'general');
$stg_obj = new studiengang();
if(!$stg_obj->load($student->studiengang_kz))
$this->terminateWithError($this->p->t('global','fehlerBeimLesenAusDatenbank'), 'general');
$subject = 'Abgabe ohne Signatur';
$tomail = $stg_obj->email;
$data = array(
'vorname' => $student->vorname,
'nachname' => $student->nachname,
'studiengang' => $stg_obj->bezeichnung
);
$mailres = sendSanchoMail(
'ParbeitsbeurteilungSiganturFehlt',
$data,
$tomail,
$subject,
'sancho_header_min_bw.jpg',
'sancho_footer_min_bw.jpg'
);
}
private function sendUploadEmail($bperson_id, $projektarbeit_id, $paabgabetyp_kurzbz, $student_uid) {
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$resBetr = $this->ProjektarbeitModel->getProjektbetreuerAnrede($bperson_id);
$projektarbeit_obj = new projektarbeit();
if(!$projektarbeit_obj->load($projektarbeit_id))
$this->terminateWithError('Ungueltiger Eintrag');
$num_rows_sem = $projektarbeit_obj->projektarbeitIsCurrent($projektarbeit_id);
if( null === $num_rows_sem || false === $num_rows_sem )
{
$this->terminateWithError($this->p->t('abgabetool','fehlerAktualitaetProjektarbeit'), 'general');
}
foreach($resBetr->retval as $betreuerRow) {
// query student benutzer view for every betreuer row
$studentUser = $this->ProjektarbeitModel->getProjektarbeitBenutzer($student_uid)->retval[0];
// TODO: hasdata, getData etc
// 1. Begutachter mail ohne Token
$mail_baselink = APP_ROOT."index.ci.php/extensions/FHC-Core-Projektarbeitsbeurteilung/ProjektarbeitsbeurteilungErstbegutachter";
$mail_fulllink = "$mail_baselink?projektarbeit_id=".$projektarbeit_id."&uid=".$studentUser->uid;
$projekttyp_kurzbz = $projektarbeit_obj->projekttyp_kurzbz;
$subject = $projektarbeit_obj->projekttyp_kurzbz == 'Diplom' ? 'Masterarbeitsbetreuung' : 'Bachelorarbeitsbetreuung';
$abgabetyp = $paabgabetyp_kurzbz == 'end' ? 'Endabgabe' : 'Zwischenabgabe';
$maildata = array();
$maildata['geehrt'] = "geehrte".($betreuerRow->anrede=="Herr"?"r":"");
$maildata['anrede'] = $betreuerRow->anrede;
$maildata['betreuer_voller_name'] = $betreuerRow->first;
$maildata['student_anrede'] = $studentUser->anrede;
$maildata['student_voller_name'] = trim($studentUser->titelpre." ".$studentUser->vorname." ".$studentUser->nachname." ".$studentUser->titelpost);
$maildata['abgabetyp'] = $abgabetyp;
$maildata['parbeituebersichtlink'] = "<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);
}
}
@@ -119,7 +119,19 @@ class Lehrveranstaltung extends FHCAPI_Controller
if (hasData($lehreinheiten_data))
{
$lehreinheiten = getData($lehreinheiten_data);
$rowData->_children = $lehreinheiten;
if (!isset($row->_children))
{
$row->_children = $lehreinheiten;
}
else
{
if (!is_array($row->_children))
{
$row->_children = [$row->_children];
}
$row->_children = array_merge($row->_children, $lehreinheiten);
}
}
if (!isEmptyString($row->studienplan_lehrveranstaltung_id_parent))
@@ -637,7 +637,7 @@ class ProfilUpdate extends FHCAPI_Controller
//? 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_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id and public.tbl_student.studiengang_kz = public.tbl_prestudent.studiengang_kz");
$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"]);
@@ -0,0 +1,121 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller 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 Board extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'list' => 'dashboard/admin:r',
'create' => 'dashboard/admin:rw',
'update' => 'dashboard/admin:rw',
'delete' => 'dashboard/admin:rw'
]);
// Models
$this->load->model('dashboard/Dashboard_model', 'DashboardModel');
}
public function list()
{
$result = $this->DashboardModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
public function create()
{
$dashboard_kurzbz = $this->input->post('dashboard_kurzbz');
$result = $this->DashboardModel->insert([
'dashboard_kurzbz' => $dashboard_kurzbz
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function update()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard_id', 'Dashboard ID', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$dashboard_id = $this->input->post('dashboard_id');
$dashboard_kurzbz = $this->input->post('dashboard_kurzbz');
$beschreibung = $this->input->post('beschreibung');
$result = $this->DashboardModel->update([
'dashboard_id' => $dashboard_id
], [
'dashboard_kurzbz' => $dashboard_kurzbz,
'beschreibung' => $beschreibung
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
public function delete()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard_id', 'Dashboard ID', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$dashboard_id = $this->input->post('dashboard_id');
//delete all presets
$this->load->model('dashboard/Dashboard_Preset_model', 'DashboardPresetModel');
$result = $this->DashboardPresetModel->delete([
'dashboard_id' => $dashboard_id
]);
$this->getDataOrTerminateWithError($result);
//delete all widgets
$this->load->model('dashboard/Dashboard_Widget_model', 'DashboardWidgetModel');
$result = $this->DashboardWidgetModel->delete([
'dashboard_id' => $dashboard_id
]);
$this->getDataOrTerminateWithError($result);
$result = $this->DashboardModel->delete($dashboard_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
}
@@ -0,0 +1,200 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller 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 Preset extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'list' => 'dashboard/admin:r',
'getBatch' => 'dashboard/admin:r',
'addWidget' => 'dashboard/admin:rw',
'removeWidget' => 'dashboard/admin:rw'
]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
// Libraries
$this->load->library('dashboard/DashboardLib');
// Models
$this->load->model('ressource/Funktion_model', 'FunktionModel');
}
public function list($dashboard_kurzbz)
{
$sql = "
WITH
dashboard_presets AS (
SELECT
*
FROM
dashboard.tbl_dashboard_preset dp
JOIN
dashboard.tbl_dashboard d ON d.dashboard_id = dp.dashboard_id
WHERE
d.dashboard_kurzbz = {$this->db->escape($dashboard_kurzbz)}
),
general AS (
SELECT
'general' AS funktion_kurzbz,
'Allgemein' AS beschreibung
)
(
SELECT
f.funktion_kurzbz,
f.beschreibung,
COUNT(p.preset_id) AS has_preset
FROM
general f
LEFT JOIN
dashboard_presets p ON p.funktion_kurzbz IS NULL
GROUP BY
f.funktion_kurzbz, f.beschreibung
)
UNION ALL
(
SELECT
f.funktion_kurzbz,
f.beschreibung,
COUNT(p.preset_id) AS has_preset
FROM
public.tbl_funktion f
LEFT JOIN
dashboard_presets p ON p.funktion_kurzbz = f.funktion_kurzbz
GROUP BY
f.funktion_kurzbz, f.beschreibung
ORDER BY
f.beschreibung ASC
)
";
$result = $this->FunktionModel->execReadOnlyQuery($sql);
$funktionen = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($funktionen);
}
public function getBatch()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('db', 'Dashboard', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$db = $this->input->post('db');
$funktionen = $this->input->post('funktionen') ?: [];
$result = [];
foreach ($funktionen as $funktion) {
$conf = $this->dashboardlib->getPreset($db, $funktion);
if ($conf) {
$preset = json_decode($conf->preset, true);
if (!isset($preset[$funktion]) || !isset($preset[$funktion]['widgets']))
$result[$funktion] = [];
else
$result[$funktion] = $preset[$funktion]['widgets'];
} else {
$result[$funktion] = [];
}
}
return $this->terminateWithSuccess($result);
}
public function addWidget()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard', 'Dashboard', 'required');
$this->form_validation->set_rules('funktion_kurzbz', 'Funktion', 'required');
$this->form_validation->set_rules('widget[widget]', 'Widget', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$dashboard_kurzbz = $this->input->post('dashboard');
$funktion_kurzbz = $this->input->post('funktion_kurzbz');
$widget = $this->input->post('widget');
if (!isset($widget['widgetid']))
$widget['widgetid'] = $this->dashboardlib->generateWidgetId($dashboard_kurzbz);
$preset = $this->dashboardlib->getPresetOrCreateEmptyPreset($dashboard_kurzbz, $funktion_kurzbz);
$preset_decoded = json_decode($preset->preset, true);
$this->dashboardlib->addWidgetsToWidgets($preset_decoded, $dashboard_kurzbz, $funktion_kurzbz, [$widget]);
$preset->preset = json_encode($preset_decoded);
$result = $this->dashboardlib->insertOrUpdatePreset($preset);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($widget['widgetid']);
}
public function removeWidget()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('db', 'Dashboard', 'required');
$this->form_validation->set_rules('funktion_kurzbz', 'Funktion', 'required');
$this->form_validation->set_rules('widgetid', 'Widget', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$dashboard_kurzbz = $this->input->post('db');
$funktion_kurzbz = $this->input->post('funktion_kurzbz');
$widgetid = $this->input->post('widgetid');
$preset = $this->dashboardlib->getPreset($dashboard_kurzbz, $funktion_kurzbz);
if (!$preset)
show_404();
$preset_decoded = json_decode($preset->preset, true);
if (!$this->dashboardlib->removeWidgetFromWidgets($preset_decoded, $funktion_kurzbz, $widgetid))
show_404();
$preset->preset = json_encode($preset_decoded);
$result = $this->dashboardlib->insertOrUpdatePreset($preset);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(array('msg' => $this->p->t('dashboard', 'success_savePreset')));
}
}
@@ -0,0 +1,159 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about the users dashboard
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class User extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'get' => 'dashboard/benutzer:r',
'addWidget' => 'dashboard/benutzer:rw',
'removeWidget' => 'dashboard/benutzer:rw'
]);
// Libraries
$this->load->library('dashboard/DashboardLib');
// Models
$this->load->model('ressource/Funktion_model', 'FunktionModel');
}
public function get($dashboard_kurzbz)
{
$dashboard = $this->dashboardlib->getDashboardByKurzbz($dashboard_kurzbz);
if (!$dashboard)
show_404();
$uid = $this->authlib->getAuthObj()->username;
/*$mergedconfig = $this->dashboardlib->getMergedConfig($dashboard->dashboard_id, $uid);
$this->terminateWithSuccess([
'general' => call_user_func_array(
'array_merge_recursive',
$mergedconfig
)
]);*/
$defaultconfig = $this->dashboardlib->getDefaultConfig($dashboard->dashboard_id);
$userconfig = $this->dashboardlib->getUserConfig($dashboard->dashboard_id, $uid);
$defaultconfig_squashed = $defaultconfig ? call_user_func_array('array_replace_recursive', $defaultconfig) : [];
$userconfig_squashed = $userconfig ? call_user_func_array('array_replace_recursive', $userconfig) : [];
$mergedconfig = array_replace_recursive($defaultconfig_squashed, $userconfig_squashed);
$this->terminateWithSuccess([
DashboardLib::SECTION_IF_FUNKTION_KURZBZ_IS_NULL => $mergedconfig
]);
}
public function addWidget()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard', 'Dashboard', 'required');
$this->form_validation->set_rules('widget[widget]', 'Widget', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$widget = $this->input->post('widget');
$dashboard_kurzbz = $this->input->post('dashboard');
$uid = $this->authlib->getAuthObj()->username;
if (!isset($widget['widgetid']))
$widget['widgetid'] = $this->dashboardlib->generateWidgetId($dashboard_kurzbz);
$override = $this->dashboardlib->getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $uid);
$override_decoded = json_decode($override->override, true);
if (!isset($override_decoded['general']) || !is_array($override_decoded['general']))
$override_decoded['general'] = [];
if (!isset($override_decoded['general']['widgets']))
$override_decoded['general']['widgets'] = [];
$override_decoded['general']['widgets'][$widget['widgetid']] = $widget;
// NOTE(chris): remove doubles in other funktionen
foreach ($override_decoded as $funktion => $array) {
if ($funktion == 'general')
continue;
if (isset($array['widgets']) && isset($array['widgets'][$widget['widgetid']]))
unset($override_decoded[$funktion]['widgets'][$widget['widgetid']]);
}
$override->override = json_encode($override_decoded);
$result = $this->dashboardlib->insertOrUpdateOverride($override);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($widget['widgetid']);
}
public function removeWidget()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard', 'Dashboard', 'required');
$this->form_validation->set_rules('widget', 'Widget', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$widget_id = $this->input->post('widget');
$dashboard_kurzbz = $this->input->post('dashboard');
$uid = $this->authlib->getAuthObj()->username;
$override = $this->dashboardlib->getOverride($dashboard_kurzbz, $uid);
if (!$override)
show_404();
$override_decoded = json_decode($override->override, true);
foreach (array_keys($override_decoded) as $k) {
if (!isset($override_decoded[$k]["widgets"])) {
unset($override_decoded[$k]);
continue;
}
if (isset($override_decoded[$k]["widgets"][$widget_id])) {
unset($override_decoded[$k]["widgets"][$widget_id]);
}
if (!$override_decoded[$k]["widgets"]) {
unset($override_decoded[$k]);
}
}
$override->override = json_encode($override_decoded);
$result = $this->dashboardlib->insertOrUpdateOverride($override);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess();
}
}
@@ -0,0 +1,137 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about the users dashboard
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Widget extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'get' => ['dashboard/benutzer:r', 'dashboard/admin:r'],
'list' => 'dashboard/admin:r',
'listAllowed' => ['dashboard/benutzer:rw', 'dashboard/admin:r'],
'setAllowed' => 'dashboard/admin:rw'
]);
// Libraries
$this->load->library('dashboard/DashboardLib');
// Models
$this->load->model('dashboard/Widget_model', 'WidgetModel');
}
public function get($id)
{
$result = $this->WidgetModel->load($id);
$widget = $this->getDataOrTerminateWithError($result);
if (!$widget)
return $this->terminateWithSuccess([
"widget_id" => 0,
"widget_kurzbz" => "notfound",
"arguments" => [
"className" => 'alert-danger',
"title" => 'Widget Not Found',
"msg" => 'The widget with the id ' . $id . ' could not be found'
],
"setup" => [
"name" => 'Widget Not Found',
"file" => absoluteJsImportUrl('public/js/components/DashboardWidget/Default.js'),
"width" => 1,
"height" => 1
]
]);
$widget = current($widget);
$widget->arguments = json_decode($widget->arguments);
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
$this->terminateWithSuccess($widget);
}
public function list($dashboard)
{
$result = $this->WidgetModel->getWithAllowedForDashboard($dashboard);
$widgets = $this->getDataOrTerminateWithError($result);
$widgets = array_map(function ($widget) {
$widget->arguments = json_decode($widget->arguments);
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
return $widget;
}, $widgets);
$this->terminateWithSuccess($widgets);
}
public function listAllowed($dashboard)
{
$result = $this->WidgetModel->getForDashboard($dashboard);
$widgets = $this->getDataOrTerminateWithError($result);
$widgets = array_map(function ($widget) {
$widget->arguments = json_decode($widget->arguments);
$tmpsetup = json_decode($widget->setup);
$tmpsetup->file = absoluteJsImportUrl($tmpsetup->file);
$widget->setup = $tmpsetup;
return $widget;
}, $widgets);
$this->terminateWithSuccess($widgets);
}
public function setAllowed()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('dashboard_id', 'Dashboard', 'required');
$this->form_validation->set_rules('widget_id', 'Widget', 'required');
$this->form_validation->set_rules('allowed', 'Allowed', 'is_bool');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$data = [
'dashboard_id' => $this->input->post('dashboard_id'),
'widget_id' => $this->input->post('widget_id')
];
$this->load->model('dashboard/Dashboard_Widget_model', 'DashboardWidgetModel');
if ($this->input->post('allowed'))
$result = $this->DashboardWidgetModel->insert($data);
else
$result = $this->DashboardWidgetModel->delete($data);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,53 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Detailheader extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getHeader' => ['vertrag/mitarbeiter:r'],
'getPersonAbteilung' => ['vertrag/mitarbeiter:r'],
'getLeitungOrg' => ['vertrag/mitarbeiter:r'],
]);
}
public function getHeader($person_id)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getHeader($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function getPersonAbteilung($mitarbeiter_uid)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getPersonAbteilung($mitarbeiter_uid);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function getLeitungOrg($oekurzbz)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getLeitungOrg($oekurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
}
@@ -0,0 +1,237 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Foto extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'uploadFoto' => ['admin:r', 'assistenz:r'],
'deleteFoto' => ['admin:r', 'assistenz:r'],
]);
//Load Models and Libraries
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model("crm/Akte_model", "AkteModel");
$this->load->model('person/Fotostatusperson_model', 'FotostatusPersonModel');
$this->loadPhrases([
'ui',
'header'
]);
}
public function uploadFoto($person_id)
{
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person_id']), self::ERROR_TYPE_GENERAL);
}
$data = json_decode(file_get_contents("php://input"), true);
if (!empty($data['image']))
{
$base64 = $data['image'];
$resizedImage1 = $this->_resize($base64, 827, 1063);
if (is_null($resizedImage1))
return $this->terminateWithError($this->p->t('header', 'error_fotoupload'), self::ERROR_TYPE_GENERAL);
$akte = $this->AkteModel->loadWhere(array('person_id' => $person_id, 'dokument_kurzbz' => 'Lichtbil'));
$akteUpdateData = array(
'dokument_kurzbz' => 'Lichtbil',
'person_id' => $person_id,
'inhalt' => $resizedImage1,
'mimetype' => 'image/jpg',
'erstelltam' => date('c'),
'gedruckt' => false,
'titel' => 'Lichtbild_' . $person_id . '.jpg',
'bezeichnung' => 'Lichtbild gross',
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
);
if (hasData($akte)) {
$akte_id = getData($akte)[0]->akte_id;
$akteUpdateData['updateamum'] = date('c');
$akteUpdateData['updatevon'] = getAuthUID();
$akteResult = $this->AkteModel->update(array('akte_id' => $akte_id), $akteUpdateData);
} else {
$akteResult = $this->AkteModel->insert($akteUpdateData);
}
if (isError($akteResult)) {
return $this->terminateWithError(getError($akteResult), self::ERROR_TYPE_GENERAL);
}
$resizedImage2 = $this->_resize($base64, 101, 130);
if (is_null($resizedImage2))
return $this->terminateWithError($this->p->t('header', 'error_fotoupload'), self::ERROR_TYPE_GENERAL);
$result = $this->_updateFoto($person_id, $resizedImage2);
if (!isError($result)) {
$this->FotostatusPersonModel->insert(array(
'person_id' => $person_id,
'fotostatus_kurzbz' => 'hochgeladen',
'datum' => date('Y-m-d'),
'updateamum' => date('c'),
'updatevon' => getAuthUID(),
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
));
return $this->terminateWithSuccess($base64);
}
}
else
{
$this->terminateWithError($this->p->t('header', 'error_noPhoto'), self::ERROR_TYPE_GENERAL);
}
}
public function deleteFoto($person_id)
{
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person_id']), self::ERROR_TYPE_GENERAL);
}
$result = $this->_deleteFoto($person_id);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess($result);
}
private function _resize($imageData, $maxwidth, $maxheight, $quality = 90)
{
$meta = getimagesize($imageData);
if (!$meta)
{
return null;
}
$src_width = $meta[0];
$src_height = $meta[1];
$mime = $meta['mime'];
switch ($mime) {
case 'image/jpeg':
case 'image/jpg':
$imagecreated = imagecreatefromjpeg($imageData);
break;
case 'image/png':
$imagecreated = imagecreatefrompng($imageData);
break;
case 'image/gif':
$imagecreated = imagecreatefromgif($imageData);
break;
default:
return null;
}
if (!$imagecreated)
{
return null;
}
$src_aspect_ratio = $src_width / $src_height;
$thu_aspect_ratio = $maxwidth / $maxheight;
if ($src_width <= $maxwidth && $src_height <= $maxheight)
{
$thu_width = $src_width;
$thu_height = $src_height;
}
elseif ($thu_aspect_ratio > $src_aspect_ratio)
{
$thu_width = (int) ($maxheight * $src_aspect_ratio);
$thu_height = $maxheight;
}
else
{
$thu_width = $maxwidth;
$thu_height = (int) ($maxwidth / $src_aspect_ratio);
}
$imageScaled = imagecreatetruecolor($thu_width, $thu_height);
if ($mime === 'image/png')
{
$background = imagecolorallocate($imageScaled , 0, 0, 0);
imagecolortransparent($imageScaled, $background);
imagealphablending($imageScaled, false);
imagesavealpha($imageScaled, true);
}
imagecopyresampled($imageScaled, $imagecreated, 0, 0, 0, 0, $thu_width, $thu_height, $src_width, $src_height);
if ($mime === "image/gif")
{
$background = imagecolorallocate($imageScaled, 0, 0, 0);
imagecolortransparent($imageScaled, $background);
}
if (!empty($imageScaled))
{
ob_start();
if ($mime == 'image/png')
imagepng($imageScaled, NULL);
else if ($mime === 'image/gif')
imagegif($imageScaled, NULL);
else
imagejpeg($imageScaled, NULL, $quality);
$resizedImageData = ob_get_contents();
ob_end_clean();
@imagedestroy($imagecreated);
@imagedestroy($imageScaled);
if (!empty($resizedImageData))
{
return base64_encode($resizedImageData);
}
return null;
}
return null;
}
private function _updateFoto($person_id, $foto)
{
$personJson['foto'] = $foto;
$result = $this->PersonModel->update($person_id, $personJson);
if (isError($result))
{
return error($result->msg, EXIT_ERROR);
}
return $result;
}
private function _deleteFoto($person_id)
{
$personJson['foto'] = null;
$result = $this->PersonModel->update($person_id, $personJson);
if (isError($result))
{
return error($result->msg, EXIT_ERROR);
}
return $result;
}
}
@@ -12,8 +12,8 @@ class Gruppe extends FHCAPI_Controller
'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'],
'getBenutzerSearch' => ['admin:r', 'assistenz:r'],
'getAllSearch' => ['admin:r', 'assistenz:r'],
'getByLehreinheit' => ['admin:r', 'assistenz:r'],
]);
@@ -22,7 +22,8 @@ class Gruppe extends FHCAPI_Controller
$this->_ci->load->library('PhrasesLib');
$this->loadPhrases(
array(
'ui'
'ui',
'lehre'
)
);
@@ -91,11 +92,11 @@ class Gruppe extends FHCAPI_Controller
$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);
$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->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$this->checkPermission($lehreinheit_id);
@@ -108,15 +109,33 @@ class Gruppe extends FHCAPI_Controller
}
public function getAll()
public function getAllSearch()
{
$query = $this->input->get('query');
if (is_null($query))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$query_words = explode(' ', $query);
$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));
$this->_ci->GruppeModel->db->where(array('sichtbar' => true, 'aktiv' => true, 'lehre' => true, 'direktinskription' => false, 'semester IS NOT NULL' => null));
$this->_ci->GruppeModel->db->group_start();
foreach ($query_words as $word)
{
$this->_ci->GruppeModel->db->group_start();
$this->_ci->GruppeModel->db->where('gruppe_kurzbz ILIKE', "%" . $word . "%");
$this->_ci->GruppeModel->db->or_where('bezeichnung ILIKE', "%" . $word . "%");
$this->_ci->GruppeModel->db->group_end();
}
$this->_ci->GruppeModel->db->group_end();
$gruppen_result = $this->_ci->GruppeModel->load();
$gruppen_array = array();
@@ -135,7 +154,18 @@ class Gruppe extends FHCAPI_Controller
$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));
$this->_ci->LehrverbandModel->db->where(array('tbl_lehrverband.aktiv' => true));
$this->_ci->LehrverbandModel->db->group_start();
foreach ($query_words as $word)
{
$this->_ci->LehrverbandModel->db->group_start();
$this->_ci->LehrverbandModel->db->where('CONCAT(CONCAT(typ, kurzbz), \'\', semester, verband, COALESCE(gruppe,\'\')) ILIKE', "%" . $word . "%");
$this->_ci->LehrverbandModel->db->or_where('tbl_lehrverband.bezeichnung ILIKE', "%" . $word . "%");
$this->_ci->LehrverbandModel->db->group_end();
}
$this->_ci->LehrverbandModel->db->group_end();
$lehrverband_result = $this->_ci->LehrverbandModel->load();
$lehrverband_array = array();
@@ -150,15 +180,40 @@ class Gruppe extends FHCAPI_Controller
$this->terminateWithSuccess($all_gruppen);
}
public function getBenutzer()
public function getBenutzerSearch()
{
$query = $this->input->get('query');
if (is_null($query))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$query_words = explode(' ', $query);
$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->_ci->PersonModel->db->where(array('tbl_benutzer.aktiv' => true));
$this->_ci->PersonModel->db->group_start();
foreach ($query_words as $word)
{
$this->_ci->PersonModel->db->group_start();
$this->_ci->PersonModel->db->where('tbl_person.vorname ILIKE', "%" . $word . "%");
$this->_ci->PersonModel->db->or_where('tbl_person.nachname ILIKE', "%" . $word . "%");
$this->_ci->PersonModel->db->or_where('uid ILIKE', "%" . $word . "%");
$this->_ci->PersonModel->db->or_where('CONCAT(tbl_studiengang.typ, tbl_studiengang.kurzbz) ILIKE', "%" . $word . "%");
if (is_numeric($word))
{
$this->_ci->PersonModel->db->or_where('semester', $word);
}
$this->_ci->PersonModel->db->group_end();
}
$this->_ci->PersonModel->db->group_end();
$personen = $this->_ci->PersonModel->load();
$this->terminateWithSuccess(hasData($personen) ? getData($personen) : array());
}
@@ -169,6 +169,10 @@ class Lehreinheit extends FHCAPI_Controller
{
$value = $this->input->post($field);
if ($field === 'lehre')
{
$value = (bool)$value;
}
if ($value !== null)
{
$updateData[$field] = $value;
@@ -281,15 +285,43 @@ class Lehreinheit extends FHCAPI_Controller
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);
$errors = array();
if (is_array($lehreinheit_id))
{
foreach ($lehreinheit_id as $le_id)
{
$lehreinheit = $this->checkLehreinheit($le_id);
$this->checkPermission($lehreinheit->lehreinheit_id);
if (isError($result))
$this->terminateWithValidationErrors(getError($result));
$result = $this->_ci->LehreinheitModel->deleteLehreinheit($lehreinheit->lehreinheit_id);
$this->terminateWithSuccess('Erfolgreich geloescht');
if (isError($result))
{
$errors[] = getError($result);
}
}
}
else
{
$lehreinheit = $this->checkLehreinheit($lehreinheit_id);
$this->checkPermission($lehreinheit->lehreinheit_id);
$result = $this->_ci->LehreinheitModel->deleteLehreinheit($lehreinheit->lehreinheit_id);
if (isError($result))
$this->terminateWithError(getError($result));
}
if (!isEmptyArray($errors))
{
if (count($errors) !== count($lehreinheit_id))
$this->terminateWithSuccess(array('errors' => $errors));
else
$this->terminateWithError($errors);
}
else
$this->terminateWithSuccess('Erfolgreich geloescht');
}
public function update()
@@ -15,7 +15,7 @@ class Lektor extends FHCAPI_Controller
'deleteLVPlan' => ['admin:rw', 'assistenz:rw'],
'deletePerson' => ['admin:rw', 'assistenz:rw'],
'getLehrfunktionen' => ['admin:r', 'assistenz:r'],
'getLektoren' => ['admin:r', 'assistenz:r'],
'getLektorenSearch' => ['admin:r', 'assistenz:r'],
'getLektorenByLE' => ['admin:r', 'assistenz:r'],
'getLektorDaten' => ['admin:r', 'assistenz:r'],
'getLektorVertrag' => ['admin:r', 'assistenz:r'],
@@ -208,12 +208,35 @@ class Lektor extends FHCAPI_Controller
$this->terminateWithSuccess(getData($this->_ci->LehrfunktionModel->load()));
}
public function getLektoren()
public function getLektorenSearch()
{
$query = $this->input->get('query');
if (is_null($query))
$this->terminateWithError($this->p->t('ui', 'ungueltigeParameter'), self::ERROR_TYPE_GENERAL);
$query_words = explode(' ', $query);
$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))));
$this->_ci->MitarbeiterModel->db->where('public.tbl_benutzer.aktiv', true);
$this->_ci->MitarbeiterModel->db->group_start();
foreach ($query_words as $word)
{
$this->_ci->MitarbeiterModel->db->group_start();
$this->_ci->MitarbeiterModel->db->where('tbl_person.vorname ILIKE', "%" . $word . "%");
$this->_ci->MitarbeiterModel->db->or_where('tbl_person.nachname ILIKE', "%" . $word . "%");
$this->_ci->MitarbeiterModel->db->or_where('uid ILIKE', "%" . $word . "%");
$this->_ci->MitarbeiterModel->db->group_end();
}
$this->_ci->MitarbeiterModel->db->group_end();
$this->_ci->MitarbeiterModel->addOrder('nachname');
$this->_ci->MitarbeiterModel->addOrder('vorname');
$result = $this->_ci->MitarbeiterModel->load();
$this->terminateWithSuccess(hasData($result) ? getData($result) : array());
}
private function checkLehreinheit($lehreinheit_id)
@@ -47,22 +47,22 @@ class Setup extends FHCAPI_Controller
{
$tabs['details'] = array (
'title' => 'Details',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Details.js',
'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Details.js'),
'config' => []
);
$tabs['gruppen'] = array (
'title' => 'Gruppen',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Gruppen.js',
'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Gruppen.js'),
'config' => []
);
$tabs['lektor'] = array (
'title' => 'LektorInnenzuteilung',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Lektor.js',
'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Lektor.js'),
'config' => []
);
$tabs['notiz'] = array (
'title' => 'Notizen',
'component' => APP_ROOT . 'public/js/components/LVVerwaltung/Tabs/Notiz.js',
'component' => absoluteJsImportUrl('public/js/components/LVVerwaltung/Tabs/Notiz.js'),
'config' => []
);
$this->terminateWithSuccess($tabs);
@@ -5,7 +5,7 @@ if (!defined('BASEPATH'))
class Tags extends Tag_Controller
{
const BERECHTIGUNG_KURZBZ = ['admin:rw', 'assistenz:rw'];
const BERECHTIGUNG_KURZBZ = ['admin:rw', 'assistenz:r'];
public function __construct()
{
@@ -1,6 +1,5 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Messages extends FHCAPI_Controller
@@ -14,13 +13,15 @@ class Messages extends FHCAPI_Controller
'getMsgVarsPrestudent' => ['admin:r', 'assistenz:r'],
'getMsgVarsLoggedInUser' => ['admin:r', 'assistenz:r'],
'getNameOfDefaultRecipient' => ['admin:r', 'assistenz:r'],
'getNameOfDefaultRecipients' => ['admin:r', 'assistenz:r'],
'sendMessage' => ['admin:r', 'assistenz:r'],
'deleteMessage' => ['admin:r', 'assistenz:r'],
'getVorlagentext' => ['admin:r', 'assistenz:r'],
'getDataVorlage' => ['admin:r', 'assistenz:r'],
'getPreviewText' => ['admin:r', 'assistenz:r'],
'getReplyData' => ['admin:r', 'assistenz:r'],
'getPersonId' => ['admin:r', 'assistenz:r'],
'getUid' => ['admin:r', 'assistenz:r'],
'getUids' => ['admin:r', 'assistenz:r'],
]);
//Load Models
@@ -37,26 +38,37 @@ class Messages extends FHCAPI_Controller
// Load language phrases
$this->loadPhrases([
'ui'
'ui', 'messages'
]);
}
public function getMessages($id, $type_id, $size, $page)
public function getMessages($id, $type_id, $size=null, $page=null)
{
if($type_id != 'person_id'){
$id = $this->_getPersonId($id, $type_id);
}
$offset = $size * ($page - 1);
$limit = $size;
if(!(is_null($size) && is_null($page)))
{
$offset = $size * ($page - 1);
$limit = $size;
}
else
{
$offset = null;
$limit = null;
}
$result = $this->MessageModel->getMessagesForTable($id, $offset, $limit);
$data = $this->getDataOrTerminateWithError($result);
if (hasData($result))
{
$data = getData($result);
$this->addMeta('count', $data['count']);
$this->terminateWithSuccess($data['data']);
}
$this->addMeta('count', $data['count']);
$this->terminateWithSuccess($data['data']);
$this->terminateWithSuccess(array());
}
public function getVorlagen()
@@ -66,33 +78,23 @@ class Messages extends FHCAPI_Controller
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung');
$data = $this->getDataOrTerminateWithError($result);
$oe_kurzbz = current($data);
if (hasData($result))
{
$this->load->model('system/Vorlage_model', 'VorlageModel');
$this->load->model('system/Vorlage_model', 'VorlageModel');
$data = getData($result);
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$oe_kurzbz = array_column($data, 'oe_kurzbz');
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz);
$this->terminateWithSuccess($data);
$this->terminateWithSuccess(hasData($result) ? getData($result) : array());
}
//If admin
$this->VorlageModel->addOrder('vorlage_kurzbz', 'ASC');
$result = $this->VorlageModel->loadWhere(
array(
'mimetype' => 'text/html'
));
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
$this->terminateWithSuccess(array());
}
public function getVorlagentext($vorlage_kurzbz)
public function getDataVorlage($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');
@@ -104,30 +106,53 @@ class Messages extends FHCAPI_Controller
]);
$data = $this->getDataOrTerminateWithError($result);
//not correct with Vorlage
$vorlage = current($data);
//$this->terminateWithSuccess($data);
$this->terminateWithSuccess($vorlage->text);
$this->terminateWithSuccess($vorlage);
}
public function getMessageVarsPerson($id, $typeId)
public function getMessageVarsPerson($typeId)
{
$person_id = ($typeId == 'mitarbeiter_uid') ? $this->_getPersonId($id, $typeId) : $id;
$result = $this->MessageModel->getMsgVarsDataByPersonId($person_id);
$data = $this->getDataOrTerminateWithError($result);
$ids = $this->input->post('ids');
$messageVarsPerson = [];
$this->terminateWithSuccess($data);
foreach ($ids as $id)
{
$person_id = ($typeId == 'mitarbeiter_uid') ? $this->_getPersonId($id, $typeId) : $id;
$result = $this->MessageModel->getMsgVarsDataByPersonId($person_id);
$data = $this->getDataOrTerminateWithError($result);
$messageVarsPerson[] = current($data);
}
$this->terminateWithSuccess($messageVarsPerson);
}
public function getMsgVarsPrestudent($id, $typeId)
public function getMsgVarsPrestudent($typeId)
{
$prestudent_id = ($typeId == 'uid') ? $this->_getPrestudentIdFromUid($id) : $id;
$result = $this->MessageModel->getMsgVarsDataByPrestudentId($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$ids = $this->input->post('ids');
if(!is_array($ids)) {
$ids = array($ids);
}
$messageVarsPrestudent = [];
$this->terminateWithSuccess($data);
if($typeId == 'uid')
{
$prestudent_ids = [];
foreach ($ids as $id)
{
$prestudent_ids[] = $this->_getPrestudentIdFromUid($id);
}
}
else
$prestudent_ids = $ids;
foreach ($prestudent_ids as $prestudent_id)
{
$result = $this->MessageModel->getMsgVarsDataByPrestudentId($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$messageVarsPrestudent[] = current($data);
}
$this->terminateWithSuccess($messageVarsPrestudent);
}
public function getMsgVarsLoggedInUser()
@@ -138,27 +163,45 @@ class Messages extends FHCAPI_Controller
$this->terminateWithSuccess($data);
}
public function getNameOfDefaultRecipient($id, $type_id)
public function getNameOfDefaultRecipients($type_id)
{
$id = ($type_id != 'person_id') ? $this->_getPersonId($id, $type_id) : $id;
$ids = $this->input->post('ids');
if(!is_array($ids)) {
$ids = array($ids);
}
$recipients = [];
if (empty($ids)) {
throw new InvalidArgumentException($this->p->t('ui', 'errorMissingOrInvalidParameters', ['parameter'=> 'Id(s)']), self::ERROR_TYPE_GENERAL);
}
$this->load->model('person/Person_model', 'PersonModel');
if($type_id != 'person_id'){
foreach ($ids as $id)
{
$person_id = $this->_getPersonId($id, $type_id);
$result = $this->PersonModel->load($person_id);
$data = $this->getDataOrTerminateWithError($result);
$name = current($data);
$recipients[$id] = $name->vorname . " " . $name->nachname;
}
}
else {
foreach ($ids as $id) {
$result = $this->PersonModel->load($id);
$data = $this->getDataOrTerminateWithError($result);
$name = current($data);
$recipients[$id] = $name->vorname . " " . $name->nachname;
}
}
$result = $this->PersonModel->load($id);
$data = $this->getDataOrTerminateWithError($result);
$name = current($data);
$this->terminateWithSuccess($name->vorname . " " . $name->nachname );
$this->terminateWithSuccess($recipients);
}
public function sendMessage($recipient_id)
public function sendMessage($typeId)
{
//has to be uid
// $this->terminateWithError("uid", $recipient_id, self::ERROR_TYPE_GENERAL);
//default setting
$receiversPersonId = $this->_getPersonId($recipient_id, 'uid');
$resultReturn = [];
$uid = getAuthUID();
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
@@ -196,49 +239,61 @@ class Messages extends FHCAPI_Controller
$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')
if (isset($_POST['ids']))
{
$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);
$ids = json_decode($_POST['ids']);
unset($_POST['ids']);
foreach ($data as $k => $v) {
$_POST[$k] = $v;
}
}
$result = $this->messagelib->sendMessageUser($receiversPersonId, $subject, $bodyParsed, $benutzer->person_id, null, $relationmessage_id);
if (!is_array($ids)) {
$ids = [$ids];
}
$this->terminateWithSuccess($result);
foreach ($ids as $id)
{
$receiversPersonId = $typeId == "person_id" ? $id : $this->_getPersonId($id, $typeId);
if($typeId == 'uid')
{
$prestudent_id = $this-> _getPrestudentIdFromUid($id);
$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);
}
elseif($typeId == 'person_id')
{
$result = $this->MessagesModel->parseMessageTextPerson($id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
}
elseif($typeId == 'prestudent_id')
{
$result = $this->MessagesModel->parseMessageTextPrestudent($id, $body);
$bodyParsed = $this->getDataOrTerminateWithError($result);
}
else
{
$this->terminateWithError($this->p->t('messages', 'error_missingLogic', ['type'=> $typeId]), self::ERROR_TYPE_GENERAL);
}
$result =$this->messagelib->sendMessageUser($receiversPersonId, $subject, $bodyParsed, $benutzer->person_id, null, $relationmessage_id);
$data = $this->getDataOrTerminateWithError($result);
$resultReturn[] = current($data);
}
$this->terminateWithSuccess($resultReturn);
}
public function getPreviewText($id, $type_id)
public function getPreviewText($type_id)
{
if (isset($_POST['data']))
{
@@ -246,39 +301,60 @@ class Messages extends FHCAPI_Controller
unset($_POST['data']);
}
else
$this->terminateWithError("Textbody missing ", self::ERROR_TYPE_GENERAL);
$this->terminateWithError($this->p->t('messages', 'errorMissingOrInvalidParameters', ['parameter'=> "Textbody"]), self::ERROR_TYPE_GENERAL);
switch($type_id)
if (isset($_POST['ids']))
{
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;
$ids = json_decode($_POST['ids']);
if(!is_array($ids))
{
$ids = array($ids);
}
unset($_POST['ids']);
}
else
$this->terminateWithError($this->p->t('ui', 'errorMissingOrInvalidParameters', ['parameter'=> 'Id(s)']), self::ERROR_TYPE_GENERAL);
$bodyParsed = $this->getDataOrTerminateWithError($result);
$bodyParsed = [];
foreach ($ids as $id)
{
switch($type_id)
{
case 'uid':
$prestudent_id = $this->_getPrestudentIdFromUid($id);
$result = $this->MessagesModel->parseMessageTextPrestudent($prestudent_id, $data);
$bodyParsed[$id] = $this->getDataOrTerminateWithError($result);
break;
case 'prestudent_id':
$result = $this->MessagesModel->parseMessageTextPrestudent($id, $data);
$bodyParsed[$id] = $this->getDataOrTerminateWithError($result);
break;
case 'person_id':
$result = $this->MessagesModel->parseMessageTextPerson($id, $data);
$bodyParsed[$id] = $this->getDataOrTerminateWithError($result);
break;
case 'mitarbeiter_uid':
{
$person_id = $this->_getPersonId($id, $type_id);
$result = $this->MessagesModel->parseMessageTextPerson($person_id, $data);
$bodyParsed[$id] = $this->getDataOrTerminateWithError($result);
}
break;
default:
$this->terminateWithError($this->p->t('messages', 'error_missingLogic', ['type'=> $type_id]), self::ERROR_TYPE_GENERAL);
break;
}
}
$this->terminateWithSuccess($bodyParsed);
}
public function getReplyData($messageId)
{
//TODO(Manu) validation of messageId: if number
if (!is_numeric($messageId)) {
$this->terminateWithError($this->p->t('ui', 'error_valueNotNumeric', ['value'=> 'Message ID']), self::ERROR_TYPE_GENERAL);
}
$this->MessageModel->addSelect('public.tbl_msg_message.*');
$this->MessageModel->addSelect('r.*');
@@ -301,7 +377,6 @@ class Messages extends FHCAPI_Controller
$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);
@@ -349,6 +424,11 @@ class Messages extends FHCAPI_Controller
['prestudent_id' => $id]
);
}
else
{
$this->terminateWithError($this->p->t('messages', 'error_missingLogic', ['type'=> $typeId]), self::ERROR_TYPE_GENERAL);
}
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
@@ -356,8 +436,11 @@ class Messages extends FHCAPI_Controller
$this->terminateWithSuccess($person->person_id);
}
public function getUid($id, $typeId)
public function getUids($typeId)
{
$ids = $this->input->post('ids');
$benutzerIds = [];
if (!$typeId)
{
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Type ID']), self::ERROR_TYPE_GENERAL);
@@ -365,39 +448,50 @@ class Messages extends FHCAPI_Controller
elseif ($typeId == 'person_id')
{
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['person_id' => $id]
);
foreach ($ids as $id)
{
$result = $this->BenutzerModel->loadWhere(
['person_id' => $id]
);
$data = $this->getDataOrTerminateWithError($result);
$benutzer = current($data);
$benutzerIds[$id] = $benutzer->uid;
}
}
elseif($typeId == 'prestudent_id')
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $id]
);
foreach ($ids as $id)
{
$result = $this->PrestudentModel->loadWhere(
['prestudent_id' => $id]
);
$data = $this->getDataOrTerminateWithError($result);
$person = current($data);
$person_id = $person->person_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]
);
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere(
['person_id' => $person_id]
);
$data = $this->getDataOrTerminateWithError($result);
$benutzer = current($data);
$benutzerIds[$id] = $benutzer->uid;
}
}
elseif($typeId == 'uid' || $typeId == 'mitarbeiter_uid')
{
$this->terminateWithSuccess($id);
$this->terminateWithSuccess($ids);
}
else
{
$this->terminateWithError("MESSAGES::getUID logic for type_id " . $typeId . " not defined yet", self::ERROR_TYPE_GENERAL);
$this->terminateWithError($this->p->t('messages', 'error_missingLogic', ['type'=> $typeId]), self::ERROR_TYPE_GENERAL);
}
$data = $this->getDataOrTerminateWithError($result);
$benutzer = current($data);
$this->terminateWithSuccess($benutzer->uid);
$this->terminateWithSuccess($benutzerIds);
}
private function _getPersonId($id, $typeId)
@@ -416,11 +510,16 @@ class Messages extends FHCAPI_Controller
['prestudent_id' => $id]
);
}
else
{
$this->terminateWithError($this->p->t('messages', 'error_missingLogic', ['type'=> $typeId]), self::ERROR_TYPE_GENERAL);
}
$data = $this->getDataOrTerminateWithError($result);
if (count($data) < 1)
{
$this->terminateWithError('Error: Messages API no person_id found.');
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
}
$person = current($data);
@@ -429,7 +528,6 @@ class Messages extends FHCAPI_Controller
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]
@@ -438,7 +536,7 @@ class Messages extends FHCAPI_Controller
$data = $this->getDataOrTerminateWithError($result);
if (count($data) < 1)
{
$this->terminateWithError('Error: Messages API no prestudent_id found.');
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$student = current($data);
@@ -463,4 +561,4 @@ class Messages extends FHCAPI_Controller
date_format(date_create($sentDate), 'd.m.Y H:i'), $receiverName, $receiverSurname, $body
);
}
}
}
@@ -0,0 +1,44 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizAnrechnung extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "anrechnung_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -0,0 +1,43 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizBestellung extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "bestellung_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -17,5 +17,106 @@ class NotizLehreinheit extends Notiz_Controller
'getMitarbeiter' => ['admin:r', 'assistenz:r'],
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
//Permission checks for allowed Oes
$allowedOes = $this->permissionlib->getOE_isEntitledFor('assistenz') ?: [];
if ($this->router->method == 'addNewNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$lehreinheit_id = $post_data['id'];
if(!$lehreinheit_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes);
}
if ($this->router->method == 'updateNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$notiz_id = $post_data['notiz_id'];
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
//get lehreinheit_id
$result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]);
$data = $this->getDataOrTerminateWithError($result);
$lehreinheit_id = current($data)->lehreinheit_id;
if(!$lehreinheit_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes);
}
if ($this->router->method == 'deleteNotiz')
{
$notiz_id = $this->input->post('notiz_id');
$lehreinheit_id = $this->input->post('id');
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
if(!$lehreinheit_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes);
}
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
}
private function _checkAllowedOesFromLehreinheit($lehreinheit_id, $allowedOes)
{
//get oe from lehreinheit
$result = $this->LehreinheitModel->getOes($lehreinheit_id);
$data = $this->getDataOrTerminateWithError($result);
$oes = current($data);
if (!in_array($oes, $allowedOes))
{
return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg') . " " . $oes, self::ERROR_TYPE_GENERAL);
}
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "lehreinheit_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -0,0 +1,44 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizMitarbeiter extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "mitarbeiter_uid")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -20,33 +20,100 @@ class NotizPerson extends Notiz_Controller
'isBerechtigt' => ['admin:r', 'assistenz:r'],
'getCountNotes' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
//Permission checks for allowed Oes
if ($this->router->method == 'addNewNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$person_id = $post_data['id'];
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkIfBerechtigungForOnePrestudentExists($person_id, $allowedStgs);
}
if ( $this->router->method == 'updateNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$notiz_id = $post_data['notiz_id'];
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
//get person_id
$result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]);
$data = $this->getDataOrTerminateWithError($result);
$person_id = current($data)->person_id;
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
$this->_checkIfBerechtigungForOnePrestudentExists($person_id, $allowedStgs);
}
if ($this->router->method == 'deleteNotiz' )
{
$notiz_id = $this->input->post('notiz_id');
$person_id = $this->input->post('id');
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
if(!$person_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'person ID']), self::ERROR_TYPE_GENERAL);
}
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
$this->_checkIfBerechtigungForOnePrestudentExists($person_id, $allowedStgs);
}
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "person_id")
{
return $this->terminateWithError($this->p->t('ui', 'error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
$this->terminateWithError($this->p->t('ui', 'error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if (!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre', 'error_keineSchreibrechte');
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
public function loadDokumente()
//stv: if person has permission of one studiengang of person -> permission to add/update/delete Note
private function _checkIfBerechtigungForOnePrestudentExists($person_id, $allowedStgs)
{
$notiz_id = $this->input->post('notiz_id');
$result = $this->PrestudentModel->loadWhere(['person_id' => $person_id]);
$data = $this->getDataOrTerminateWithError($result);
// TODO(chris): make CI variant of endpoint
$this->NotizModel->addSelect($this->NotizModel->escape(base_url('content/notizdokdownload.php?id=')) . ' || campus.tbl_dms_version.dms_id AS preview');
return parent::loadDokumente();
$checkarray = [];
foreach ($data as $item)
{
if(in_array($item->studiengang_kz, $allowedStgs))
{
return true;
}
}
$this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL);
}
}
}
@@ -0,0 +1,117 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizPrestudent extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
//Load Models
$this->load->model('person/Notiz_model', 'NotizModel');
$this->load->model('person/Notizzuordnung_model', 'NotizzuordnungModel');
$this->load->model('crm/Student_model', 'StudentModel');
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui'
]);
//Permission checks for Studiengangsarray
$allowedStgs = $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: [];
if ($this->router->method == 'addNewNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$prestudent_id = $post_data['id'];
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Lehreinheit ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs);
}
if ($this->router->method == 'updateNotiz')
{
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$notiz_id = $post_data['notiz_id'];
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
//get prestudent_id
$result = $this->NotizzuordnungModel->loadWhere(['notiz_id' => $notiz_id]);
$data = $this->getDataOrTerminateWithError($result);
$prestudent_id = current($data)->prestudent_id;
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs);
}
if ($this->router->method == 'deleteNotiz')
{
$notiz_id = $this->input->post('notiz_id');
$prestudent_id = $this->input->post('id');
if(!$notiz_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Notiz ID']), self::ERROR_TYPE_GENERAL);
}
if(!$prestudent_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Prestudent ID']), self::ERROR_TYPE_GENERAL);
}
$this->_checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs);
}
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "prestudent_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
private function _checkAllowedOesFromPrestudent($prestudent_id, $allowedStgs)
{
$student_uid = $this->StudentModel->getUID($prestudent_id);
$result = $this->StudentModel->loadWhere(['student_uid' => $student_uid]);
$data = $this->getDataOrTerminateWithError($result);
$studiengang_kz = current($data)->studiengang_kz;
if (!in_array($studiengang_kz, $allowedStgs))
{
return $this->terminateWithError($this->p->t('ui', 'error_keineBerechtigungStg'), self::ERROR_TYPE_GENERAL);
}
}
}
@@ -0,0 +1,32 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizProjekt extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "projekt_kurzbz")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -0,0 +1,32 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizProjektphase extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "projektphase_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -0,0 +1,32 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizProjekttask extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "projekttask_id")
{
$this->terminateWithError($this->p->t('ui','error_typeNotizIdIncorrect'), self::ERROR_TYPE_GENERAL);
}
//TODO define permission
if(!$this->permissionlib->isBerechtigt('admin', 'suid') && !$this->permissionlib->isBerechtigt('assistenz', 'suid'))
{
$result = $this->p->t('lehre','error_keineSchreibrechte');
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess("berechtigt in überschreibender Funktion");
}
}
@@ -0,0 +1,69 @@
<?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 Studienplan extends FHCAPI_Controller
{
public function __construct()
{
// TODO(chris): access!
parent::__construct([
'getBySemester' => self::PERM_LOGGED
]);
}
public function getBySemester()
{
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$studiengang_kz = $this->input->get('studiengang_kz');
$studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz');
$ausbildungssemester = $this->input->get('ausbildungssemester') ?: null;
$orgform_kurzbz = $this->input->get('orgform_kurzbz') ?: null;
if (!$studiengang_kz || !is_numeric($studiengang_kz))
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Studiengangskennzahl']), self::ERROR_TYPE_GENERAL);
if (!$studiensemester_kurzbz)
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Studiensemester']), self::ERROR_TYPE_GENERAL);
if (isset($ausbildungssemester) && !is_numeric($ausbildungssemester))
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Ausbildungssemester']), self::ERROR_TYPE_GENERAL);
//~ $this->load->library('form_validation');
//~ $this->form_validation->set_rules('studiengang_kz', 'StudiengangKz', 'required|numeric');
//~ $this->form_validation->set_rules('studiensemester_kurzbz', 'StudiensemesterKurbz', 'required');
//~ $this->form_validation->set_rules('ausbildungssemester', 'Ausbildungssemester', 'numeric');
//~ if (!$this->form_validation->run())
//~ {
//~ $this->addMeta('fail2', 'fail2');
//~ return $this->terminateWithValidationErrors($this->form_validation->error_array());
//~ }
$this->addMeta('stg_kz', $studiengang_kz);
$this->addMeta('sem', $studiensemester_kurzbz);
$this->addMeta('sem2', $ausbildungssemester);
$this->addMeta('org', $orgform_kurzbz);
$result = $this->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $ausbildungssemester, $orgform_kurzbz);
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
$this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
}
@@ -25,7 +25,8 @@ class Studiensemester extends FHCAPI_Controller
array(
'getAll' => self::PERM_LOGGED,
'getAktNext' => self::PERM_LOGGED,
'getStudienjahrByStudiensemester' => self::PERM_LOGGED
'getStudienjahrByStudiensemester' => self::PERM_LOGGED,
'getAllStudiensemesterAndAktOrNext' => self::PERM_LOGGED
)
);
// Load model StudiensemesterModel
@@ -152,4 +153,17 @@ class Studiensemester extends FHCAPI_Controller
$this->terminateWithSuccess((getData(success($studienjahrObj))));
}
public function getAllStudiensemesterAndAktOrNext() {
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addOrder("start", "DESC");
$result = $this->StudiensemesterModel->getAktOrNextSemester();
$aktuell = getData($result)[0];
$this->StudiensemesterModel->addSelect('*');
$result = $this->StudiensemesterModel->load();
$studiensemester = getData($result);
$this->terminateWithSuccess(array($studiensemester, $aktuell));
}
}
@@ -127,9 +127,9 @@ class Unterbrechung extends FHCAPI_Controller
$this->form_validation->set_rules(
'datum_wiedereinstieg',
'Datum Wiedereinstieg',
'required|callback_isValidDate|callback_isDateInFuture',
'required|is_valid_date|callback_isDateInFuture',
[
'isValidDate' => $this->p->t('ui', 'error_invalid_date'),
'is_valid_date' => $this->p->t('ui', 'error_invalid_date'),
'isDateInFuture' => $this->p->t('ui', 'error_invalid_date')
]
);
@@ -209,18 +209,9 @@ class Unterbrechung extends FHCAPI_Controller
$this->terminateWithSuccess(getData($result));
}
public function isValidDate($date)
{
try {
new DateTime($date);
} catch (Exception $e) {
return false;
}
return true;
}
public function isDateInFuture($date)
{
return new DateTime() < new DateTime($date);
}
}
@@ -20,8 +20,6 @@ class Abschlusspruefung extends FHCAPI_Controller
'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'],
@@ -102,35 +100,45 @@ class Abschlusspruefung extends FHCAPI_Controller
{
$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->addSelect(
'lehre.tbl_abschlusspruefung.*,
p1.person_id AS p1_person_id, p1.vorname AS p1_vorname, p1.nachname AS p1_nachname,
p1.titelpre AS p1_titelpre, p1.titelpost AS p1_titelpost,
p2.person_id AS p2_person_id, p2.vorname AS p2_vorname, p2.nachname AS p2_nachname,
p2.titelpre AS p2_titelpre, p2.titelpost AS p2_titelpost,
p3.person_id AS p3_person_id, p3.vorname AS p3_vorname, p3.nachname AS p3_nachname,
p3.titelpre AS p3_titelpre, p3.titelpost AS p3_titelpost,
pv.person_id AS pv_person_id, pv.vorname AS pv_vorname, pv.nachname AS pv_nachname,
pv.titelpre AS pv_titelpre, pv.titelpost AS pv_titelpost, ben.uid AS pv_uid'
);
//~ $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');
@@ -220,8 +228,10 @@ class Abschlusspruefung extends FHCAPI_Controller
$this->terminateWithSuccess($typStudiengang);
}
public function getMitarbeiter($searchString)
public function getMitarbeiter()
{
$searchString = $this->input->get('searchString') ?? '';
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'mitAkadGrad');
@@ -232,8 +242,10 @@ class Abschlusspruefung extends FHCAPI_Controller
$this->terminateWithSuccess($result ?: []);
}
public function getPruefer($searchString)
public function getPruefer()
{
$searchString = $this->input->get('searchString') ?? '';
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->MitarbeiterModel->searchMitarbeiter($searchString, 'ohneMaUid');
@@ -444,58 +456,4 @@ class Abschlusspruefung extends FHCAPI_Controller
}
$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);
}
}
@@ -39,7 +39,7 @@ class Archiv extends FHCAPI_Controller
'archive' => ['admin:w', 'assistenz:w'],
'download' => ['admin:w', 'assistenz:w'],
'update' => ['admin:w'],
'delete' => ['admin:w', 'assistenz:w']
'delete' => ['admin:w', 'assistenz:w'],
]);
// Load models
@@ -107,13 +107,9 @@ class Archiv extends FHCAPI_Controller
$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 != '')
@@ -133,12 +129,7 @@ class Archiv extends FHCAPI_Controller
//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
{
@@ -146,12 +137,6 @@ class Archiv extends FHCAPI_Controller
$result = $this->aktelib->get($akte_id);
}
/* $fileObj->filename
* $fileObj->file
* $fileObj->name
* $fileObj->mimetype
* $fileObj->disposition*/
}
/**
@@ -36,15 +36,44 @@ class Aufnahmetermine extends FHCAPI_Controller
// Load models
$this->load->model('crm/Reihungstest_model', 'ReihungstestModel');
$this->load->model('crm/RtPerson_model', 'RtPersonModel');
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$this->load->model('organisation/Studienordnung_model', 'StudienordnungModel');
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
}
public function getAufnahmetermine($person_id)
{
$result = $this->ReihungstestModel->getReihungstestPerson($person_id);
$arrayRt = $this->getDataOrTerminateWithError($result);
$data = $this->getDataOrTerminateWithError($result);
foreach ($arrayRt as $item) {
//Studienplan
$result = $this->StudienplanModel->loadWhere([
'studienplan_id' => $item->studienplan_id
]);
$data = $this->getDataOrTerminateWithError($result);
$studienordnung_id_ber = current($data)->studienordnung_id;
$this->terminateWithSuccess($data);
//Studienordnung
$result = $this->StudienordnungModel->loadWhere([
'studienordnung_id' => $studienordnung_id_ber
]);
$data = $this->getDataOrTerminateWithError($result);
$studiengang_kz_ber = current($data)->studiengang_kz;
//Studiengang von studiengang_kz_ber
$result = $this->StudiengangModel->load($studiengang_kz_ber);
$data = $this->getDataOrTerminateWithError($result);
$studiengangkurzbzlang_ber = current($data)->kurzbzlang;
$typ_ber = current($data)->typ;
//add to Array
$item->studiengang_kz_ber = $studiengang_kz_ber;
$item->studiengangkurzbzlang_ber = $studiengangkurzbzlang_ber;
$item->studiengangtyp_ber = $typ_ber;
}
$this->terminateWithSuccess($arrayRt);
}
public function insertAufnahmetermin()
@@ -60,7 +89,6 @@ class Aufnahmetermine extends FHCAPI_Controller
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
}
$rt_id = (isset($formData['rt_id']) && !empty($formData['rt_id'])) ? $formData['rt_id'] : null;
$anmeldedatum = (isset($formData['anmeldedatum']) && !empty($formData['anmeldedatum'])) ? $formData['anmeldedatum'] : null;
$teilgenommen = (isset($formData['teilgenommen']) && !empty($formData['teilgenommen'])) ? $formData['teilgenommen'] : false;
@@ -224,7 +252,11 @@ class Aufnahmetermine extends FHCAPI_Controller
)
);
$data = $this->getDataOrTerminateWithError($result);
//check if existing placementtest
if(!hasData($result))
$this->terminateWithSuccess([]);
else
$data = getData($result);
$studienplan_arr = [];
$include_ids = [];
@@ -233,12 +265,18 @@ class Aufnahmetermine extends FHCAPI_Controller
if($item->studienplan_id != null)
$studienplan_arr[] = $item->studienplan_id;
}
if(!hasData($studienplan_arr))
$this->terminateWithSuccess([]);
//get Placementtests Person
$person_id = $this->_getPersonId($prestudent_id);
$resultRt = $this->ReihungstestModel->getReihungstestPerson($person_id);
$dataRt = $this->getDataOrTerminateWithError($resultRt);
//check if existing placementtest
if(!hasData($result))
$this->terminateWithSuccess([]);
else
$dataRt = getData($resultRt);
foreach ($dataRt as $item)
{
@@ -298,7 +336,7 @@ class Aufnahmetermine extends FHCAPI_Controller
$reihungstestangetreten =
(isset($formData['reihungstestangetreten']) && !empty($formData['reihungstestangetreten']))
? $formData['reihungstestangetreten']
: null;
: false;
$aufnahmegruppe_kurzbz =
(isset($formData['aufnahmegruppe_kurzbz']) && !empty($formData['aufnahmegruppe_kurzbz']))
? $formData['aufnahmegruppe_kurzbz']
@@ -354,6 +392,7 @@ class Aufnahmetermine extends FHCAPI_Controller
$person_id = $this->input->get('person_id');
$punkte = $this->input->get('punkte');
$reihungstest_id = $this->input->get('reihungstest_id');
$has_excluded_gebiete = $this->input->get('hasExcludedAreas');
if(!$reihungstest_id)
{
@@ -364,22 +403,27 @@ class Aufnahmetermine extends FHCAPI_Controller
$studiengang_kz = $this->input->get('studiengang_kz');
$this->load->model('testtool/Ablauf_model', 'AblaufModel');
$result = $this->AblaufModel->getAblaufGebieteAndGewichte($studiengang_kz);
$result = $this->AblaufModel->getAblaufGebieteAndGewichte($studiengang_kz, 1);
$data = $this->getDataOrTerminateWithError($result);
$weightedArray = [];
$basis_gebiet_id_arr = [];
$basis_gebiet_id_toString = '';
foreach ($data as $abl)
{
$weightedArray[$abl->gebiet_id] = $abl->gewicht;
$basis_gebiet_id_arr[]= $abl->gebiet_id;
}
$basis_gebiet_id_toString = implode(', ', $basis_gebiet_id_arr);
$result = $this->ReihungstestModel->getReihungstestErgebnisPerson($person_id, $punkte, $reihungstest_id, $weightedArray);
/* if (isError($result))
{
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}*/
$result = $this->ReihungstestModel->getReihungstestErgebnisPerson(
$person_id,
$punkte,
$reihungstest_id,
$weightedArray,
$has_excluded_gebiete,
$basis_gebiet_id_toString
);
$this->terminateWithSuccess($result);
}
@@ -33,6 +33,9 @@ class Config extends FHCAPI_Controller
{
// TODO(chris): permissions
parent::__construct([
'get' => ['admin:r', 'assistenz:r'],
'set' => ['admin:r', 'assistenz:r'],
'filter' => ['admin:r', 'assistenz:r'],
'student' => ['admin:r', 'assistenz:r'],
'students' => ['admin:r', 'assistenz:r']
]);
@@ -45,13 +48,257 @@ class Config extends FHCAPI_Controller
'lehre',
'stv',
'konto',
'abschlusspruefung'
'abschlusspruefung',
'projektarbeit'
]);
// Load Config
$this->load->config('stv');
}
/**
* get App config
*/
public function get()
{
$this->load->model('system/Variable_model', 'VariableModel');
$this->load->config('stv');
$config = [];
#number_displayed_past_studiensemester
$result = $this->VariableModel->getVariables(getAuthUID(), ['number_displayed_past_studiensemester']);
$data = $this->getDataOrTerminateWithError($result);
$number_displayed_past_studiensemester_default = $this->config->item('number_displayed_past_studiensemester_default');
$config['number_displayed_past_studiensemester'] = [
"type" => "number",
"label" => $this->p->t('stv', 'settings_no_displayed_past_sem'),
"value" => $data['number_displayed_past_studiensemester']
?? $number_displayed_past_studiensemester_default
];
#font_size
$result = $this->VariableModel->getVariables(getAuthUID(), ['stv_font_size']);
$data = $this->getDataOrTerminateWithError($result);
$config['font_size'] = [
"type" => "select",
"label" => $this->p->t('stv', 'settings_fontsize'),
"value" => $data['stv_font_size'] ?? "fs_normal",
"options" => [
"fs_xx-small" => $this->p->t('stv', 'settings_fontsize_xx-small'),
"fs_x-small" => $this->p->t('stv', 'settings_fontsize_x-small'),
"fs_small" => $this->p->t('stv', 'settings_fontsize_small'),
"fs_normal" => $this->p->t('stv', 'settings_fontsize_normal'),
"fs_big" => $this->p->t('stv', 'settings_fontsize_big'),
"fs_huge" => $this->p->t('stv', 'settings_fontsize_huge')
]
];
#others
Events::trigger('stv_config_get', function & () use (&$config) {
return $config;
});
$this->terminateWithSuccess($config);
}
/**
* set App config
*/
public function set()
{
$this->load->model('system/Variable_model', 'VariableModel');
$this->load->library('form_validation');
$this->form_validation->set_rules(
'number_displayed_past_studiensemester',
$this->p->t('stv', 'settings_no_displayed_past_sem'),
'required|integer'
);
$this->form_validation->set_rules(
'font_size',
$this->p->t('stv', 'settings_fontsize'),
'required|in_list[fs_xx-small,fs_x-small,fs_small,fs_normal,fs_big,fs_huge]'
);
Events::trigger('stv_config_validation', $this->form_validation);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$this->VariableModel->setVariable(
getAuthUID(),
'number_displayed_past_studiensemester',
$this->input->post('number_displayed_past_studiensemester')
);
$this->VariableModel->setVariable(
getAuthUID(),
'stv_font_size',
$this->input->post('font_size')
);
Events::trigger('stv_config_set', $this->input);
$this->terminateWithSuccess();
}
/*
* Get the config for the student filters
*
* @return void
*/
public function filter()
{
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->model('crm/Buchungstyp_model', 'BuchungstypModel');
$this->BuchungstypModel->addOrder('beschreibung');
$result = $this->BuchungstypModel->load();
$buchungstyp_kurzbz = $this->getDataOrTerminateWithError($result);
$buchungstyp_kurzbz_plus_all = array_merge([[
'buchungstyp_kurzbz' => 'all',
'beschreibung' => $this->p->t('stv', 'konto_all_types')
]], $buchungstyp_kurzbz);
$this->load->model('crm/Statusgrund_model', 'StatusgrundModel');
$result = $this->StatusgrundModel->getAktiveGruende();
$statusgruende = $this->getDataOrTerminateWithError($result);
$result = [];
$result[] = [
'id' => 'filter_konto_count_0',
'label' => $this->p->t('stv', 'filter_konto_count_0'),
'type' => 'konto',
'fixed' => [
'missing' => true,
'usestdsem' => true
],
'dynamic' => [
'buchungstyp_kurzbz' => [
'type' => 'select',
'values' => $buchungstyp_kurzbz,
'value_key' => 'buchungstyp_kurzbz',
'label_key' => 'beschreibung'
]
]
];
$result[] = [
'id' => 'filter_konto_missing_counter',
'label' => $this->p->t('stv', 'filter_konto_missing_counter'),
'type' => 'konto_counter',
'dynamic' => [
'buchungstyp_kurzbz' => [
'type' => 'select',
'values' => $buchungstyp_kurzbz_plus_all,
'value_key' => 'buchungstyp_kurzbz',
'label_key' => 'beschreibung',
'default' => 'all'
],
'samestg' => [
'type' => 'bool',
'label' => $this->p->t('stv', 'filter_konto_samestg'),
'default' => $this->variablelib->getVar('kontofilterstg') == 'true'
]
]
];
$result[] = [
'id' => 'filter_documents',
'label' => $this->p->t('stv', 'filter_documents'),
'type' => 'documents'
];
$result[] = [
'id' => 'filter_konto_missing_counter_past',
'label' => $this->p->t('stv', 'filter_konto_missing_counter_past'),
'type' => 'konto_counter',
'fixed' => [
'past' => true
],
'dynamic' => [
'buchungstyp_kurzbz' => [
'type' => 'select',
'values' => $buchungstyp_kurzbz_plus_all,
'value_key' => 'buchungstyp_kurzbz',
'label_key' => 'beschreibung',
'default' => 'all'
],
'samestg' => [
'type' => 'bool',
'label' => $this->p->t('stv', 'filter_konto_samestg'),
'default' => $this->variablelib->getVar('kontofilterstg') == 'true'
]
]
];
$result[] = [
'id' => 'filter_konto_missing_studiengebuehr',
'label' => $this->p->t('stv', 'filter_konto_missing_studiengebuehr'),
'type' => 'konto',
'fixed' => [
'missing' => true,
'usestdsem' => true
],
'dynamic' => [
'buchungstyp_kurzbz' => [
'type' => 'select',
'values' => $buchungstyp_kurzbz,
'value_key' => 'buchungstyp_kurzbz',
'label_key' => 'beschreibung'
]
]
];
$result[] = [
'id' => 'filter_konto_studiengebuehrerhoeht',
'label' => $this->p->t('stv', 'filter_konto_studiengebuehrerhoeht'),
'type' => 'konto',
'fixed' => [
'usestdsem' => true
],
'dynamic' => [
'buchungstyp_kurzbz' => [
'type' => 'select',
'values' => $buchungstyp_kurzbz,
'value_key' => 'buchungstyp_kurzbz',
'label_key' => 'beschreibung'
]
]
];
$result[] = [
'id' => 'filter_zgv_without_date',
'label' => $this->p->t('stv', 'filter_zgv_without_date'),
'type' => 'zgv'
];
$result[] = [
'id' => 'filter_statusgrund',
'label' => $this->p->t('stv', 'filter_statusgrund'),
'type' => 'statusgrund',
'fixed' => [
'usestdsem' => true
],
'dynamic' => [
'statusgrund_id' => [
'type' => 'select',
'values' => $statusgruende,
'value_key' => 'statusgrund_id',
'label_key' => 'bezeichnung'
]
]
];
Events::trigger('stv_conf_filter', function & () use (&$result) {
return $result;
});
$this->terminateWithSuccess($result);
}
public function student()
{
$result = [];
@@ -59,21 +306,21 @@ class Config extends FHCAPI_Controller
$result['details'] = [
'title' => $this->p->t('stv', 'tab_details'),
'component' => './Stv/Studentenverwaltung/Details/Details.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Details.js'),
'config' => $config['details']
];
$result['notes'] = [
'title' => $this->p->t('stv', 'tab_notes'),
'component' => './Stv/Studentenverwaltung/Details/Notizen.js',
'component' => absoluteJsImportUrl('public/js/components/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'
'suffixhelper' => absoluteJsImportUrl('public/js/helpers/Stv/Studentenverwaltung/Details/Notizen/NotizenSuffixHelper.js')
];
$result['contact'] = [
'title' => $this->p->t('stv', 'tab_contact'),
'component' => './Stv/Studentenverwaltung/Details/Kontakt.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Kontakt.js'),
'config' => [
'showBankaccount' => $this->permissionlib->isBerechtigt('mitarbeiter/bankdaten')
|| $this->permissionlib->isBerechtigt('student/bankdaten')
@@ -81,20 +328,23 @@ class Config extends FHCAPI_Controller
];
$result['prestudent'] = [
'title' => $this->p->t('stv', 'tab_prestudent'),
'component' => './Stv/Studentenverwaltung/Details/Prestudent.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Prestudent.js'),
'config' => $config['prestudent']
];
$result['status'] = [
'title' => 'Status',
'component' => './Stv/Studentenverwaltung/Details/MultiStatus.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/MultiStatus.js'),
'config' => [
'showStatusVorruecken' => defined('STATUS_VORRUECKEN_ANZEIGEN') ? STATUS_VORRUECKEN_ANZEIGEN : true,
]
];
$result['documents'] = [
'title' => $this->p->t('stv', 'tab_documents'),
'component' => './Stv/Studentenverwaltung/Details/Dokumente.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Dokumente.js')
];
$result['banking'] = [
'title' => $this->p->t('stv', 'tab_banking'),
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Konto.js'),
'config' => [
'showZahlungsbestaetigung' => (defined('ZAHLUNGSBESTAETIGUNG_ANZEIGEN') && ZAHLUNGSBESTAETIGUNG_ANZEIGEN),
'showBuchungsnr' => $this->permissionlib->isBerechtigt('admin'),
@@ -106,20 +356,22 @@ class Config extends FHCAPI_Controller
];
$result['resources'] = [
'title' => $this->p->t('stv', 'tab_resources'),
'component' => './Stv/Studentenverwaltung/Details/Betriebsmittel.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Betriebsmittel.js'),
'showOnlyWithUid' => true
];
$result['groups'] = [
'title' => $this->p->t('stv', 'tab_groups'),
'component' => './Stv/Studentenverwaltung/Details/Gruppen.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Groups.js'),
'showOnlyWithUid' => true
];
$result['messages'] = [
'title' => $this->p->t('stv', 'tab_messages'),
'component' => './Stv/Studentenverwaltung/Details/Messages.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Messages.js'),
];
$result['grades'] = [
'title' => $this->p->t('stv', 'tab_grades'),
'component' => './Stv/Studentenverwaltung/Details/Noten.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Noten.js'),
'showOnlyWithUid' => true,
'config' => [
'usePoints' => defined('CIS_GESAMTNOTE_PUNKTE') && CIS_GESAMTNOTE_PUNKTE,
@@ -132,29 +384,42 @@ class Config extends FHCAPI_Controller
$result['exam'] = [
'title' => $this->p->t('stv', 'tab_exam'),
'component' => './Stv/Studentenverwaltung/Details/Pruefung.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Pruefung.js'),
'showOnlyWithUid' => true
];
$result['exemptions'] = [
'title' => $this->p->t('lehre', 'anrechnungen'),
'component' => './Stv/Studentenverwaltung/Details/Anrechnungen.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Anrechnungen.js'),
'config' => $config['exemptions']
];
$result['finalexam'] = [
'title' => $this->p->t('stv', 'tab_finalexam'),
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung.js'),
'showOnlyWithUid' => true,
'config' => $config['finalexam']
];
$result['projektarbeit'] = [
'title' => $this->p->t('stv', 'tab_projektarbeit'),
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Projektarbeit.js'),
'config' => array_merge(
$config['projektarbeit'],
['showVertragsdetails' =>
defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN') && FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN]
)
];
$result['mobility'] = [
'title' => $this->p->t('stv', 'tab_mobility'),
'component' => './Stv/Studentenverwaltung/Details/Mobility.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Mobility.js'),
'showOnlyWithUid' => true
];
$result['archive'] = [
'title' => $this->p->t('stv', 'tab_archive'),
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Archiv.js'),
'config' => [
'showEdit' => $this->permissionlib->isBerechtigt('admin')
]
@@ -162,22 +427,24 @@ class Config extends FHCAPI_Controller
$result['jointstudies'] = [
'title' => $this->p->t('stv', 'tab_jointstudies'),
'component' => './Stv/Studentenverwaltung/Details/JointStudies.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/JointStudies.js'),
'showOnlyWithUid' => true
];
$result['coursedates'] = [
'title' => $this->p->t('stv', 'tab_courseDates'),
'component' => './Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Lehrveranstaltungstermine.js')
];
$result['admissionDates'] = [
'title' => $this->p->t('stv', 'tab_admissionDates'),
'component' => './Stv/Studentenverwaltung/Details/Aufnahmetermine.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Aufnahmetermine.js')
];
$result['functions'] = [
'title' => $this->p->t('stv', 'tab_functions'),
'component' => './Stv/Studentenverwaltung/Details/Funktionen.js'
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Funktionen.js'),
'showOnlyWithUid' => true
];
Events::trigger('stv_conf_student', function & () use (&$result) {
@@ -195,7 +462,7 @@ class Config extends FHCAPI_Controller
$config = $this->config->item('tabs');
$result['banking'] = [
'title' => $this->p->t('stv', 'tab_banking'),
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Konto.js'),
'config' => [
'showZahlungsbestaetigung' => (defined('ZAHLUNGSBESTAETIGUNG_ANZEIGEN') && ZAHLUNGSBESTAETIGUNG_ANZEIGEN),
'showBuchungsnr' => $this->permissionlib->isBerechtigt('admin'),
@@ -205,9 +472,14 @@ class Config extends FHCAPI_Controller
'additionalCols' => []
]
];
$result['groups'] = [
'title' => $this->p->t('stv', 'tab_groups'),
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Groups.js'),
'showOnlyWithUid' => true
];
$result['status'] = [
'title' => 'Status',
'component' => './Stv/Studentenverwaltung/Details/MultiStatus.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/MultiStatus.js'),
'config' => [
'changeStatusToAbbrecherStgl' => $this->permissionlib->isBerechtigt('admin'),
'changeStatusToAbbrecherStud' => $this->permissionlib->isBerechtigt('admin'),
@@ -218,17 +490,37 @@ class Config extends FHCAPI_Controller
];
$result['finalexam'] = [
'title' => $this->p->t('stv', 'tab_finalexam'),
'component' => './Stv/Studentenverwaltung/Details/Abschlusspruefung.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Abschlusspruefung.js'),
'showOnlyWithUid' => true,
'config' => $config['finalexam']
];
$result['archive'] = [
'title' => $this->p->t('stv', 'tab_archive'),
'component' => './Stv/Studentenverwaltung/Details/Archiv.js',
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Archiv.js'),
'config' => [
'showEdit' => $this->permissionlib->isBerechtigt('admin')
]
];
if($this->permissionlib->isBerechtigt('basis/person'))
{
$result['combinePeople'] = [
'title' => $this->p->t('stv', 'tab_combine_people'),
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/CombinePeople.js'),
'config' => $config['combinePeople']
];
}
$result['kontaktieren'] = [
'title' => $this->p->t('stv', 'tab_kontaktieren'),
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Kontaktieren.js'),
];
$result['messages'] = [
'title' => $this->p->t('stv', 'tab_messages'),
'component' => absoluteJsImportUrl('public/js/components/Stv/Studentenverwaltung/Details/Messages.js'),
];
Events::trigger('stv_conf_students', function & () use (&$result) {
return $result;
});
@@ -2,6 +2,7 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \CI3_Events as Events;
use \DateTime as DateTime;
class Dokumente extends FHCAPI_Controller
@@ -19,6 +20,8 @@ class Dokumente extends FHCAPI_Controller
'getDoktypen' => ['admin:r', 'assistenz:r'],
'uploadDokument' => ['admin:rw', 'assistenz:rw'],
'download' => ['admin:rw', 'assistenz:rw'],
'getDocumentDropDown' => ['admin:rw', 'assistenz:rw'],
'getDocumentDropDownMulti' => ['admin:rw', 'assistenz:rw'],
]);
// Load Libraries
@@ -75,52 +78,32 @@ class Dokumente extends FHCAPI_Controller
$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);
$mergedArray = [];
foreach($docNames as $doc)
foreach ($resultPreDoc as $pre)
{
$result = $this->AkteModel->getAktenFAS($person_id, $doc, $studiengang_kz, $prestudent_id, true);
$result = $this->AkteModel->getAktenFAS($person_id, $pre->dokument_kurzbz, $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)
foreach (getData($result) as $doc)
{
array_push($arrayAccepted, $value);
$merged = clone $doc;
$merged->docdatum = $pre->docdatum;
$merged->insertvonma = $pre->insertvonma;
$merged->bezeichnung = $pre->bezeichnung;
$mergedArray[] = $merged;
}
}
}
//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;
else
{
$mergedArray[] = $pre;
}
$mergedArray[] = $merged;
}
$this->terminateWithSuccess($mergedArray);
@@ -566,4 +549,426 @@ class Dokumente extends FHCAPI_Controller
return false;
}
}
public function getDocumentDropDown($prestudent_id, $studiensemester_kurzbz, $studiengang_kz)
{
$this->load->helper('hlp_common');
//permission to create also odt, and doc outputs of certain documents(menu abschlusspruefung)
$hasPermissionOutputformat = $this->permissionlib->isBerechtigt('system/change_outputformat', 's');
if (!$prestudent_id)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Prestudent_id']), self::ERROR_TYPE_GENERAL);
if (!$studiensemester_kurzbz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiensemester']), self::ERROR_TYPE_GENERAL);
if(!$studiengang_kz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
$uid = $this->_loadUIDFromPrestudent($prestudent_id);
$semArray = $this->_getEntriesStudiensemester();
$stgTyp = $this->_getStudiengangstyp($studiengang_kz);
$documents = [
buildDropdownEntryPrintArray("accountinfo", "Accountinfoblatt", "xml=accountinfoblatt.xml.php&xsl=AccountInfo&output=pdf", $uid, 10, null),
buildDropdownEntryPrintArray("ausbildungsvertrag", "Ausbildungsvertrag", "xml=ausbildungsvertrag.xml.php&xsl=Ausbildungsver&output=pdf&prestudent_id=$prestudent_id", null,20, null),
buildDropdownEntryPrintArray("ausbildungsvertrag_en", "Ausbildungsvertrag Zweisprachig", "xml=ausbildungsvertrag.xml.php&xsl=AusbVerEng&output=pdf&prestudent_id=$prestudent_id", null,21, null),
buildDropdownEntryPrintArray("bescheid", "Bescheid (nur Voransicht)", "xml=abschlusspruefung.rdf.php&xsl_stg_kz=$studiengang_kz&xsl=Bescheid&output=pdf", $uid, 25, null),
buildDropdownEntryPrintArray("diplomasupp", "Diploma Supplement (nur Voransicht)", "xml=diplomasupplement.xml.php&xsl_stg_kz=$studiengang_kz&xsl=DiplSupplement&output=pdf", $uid, 26, null),
buildDropdownEntryPrintArray("studienbestaetigung", "Studienbestätigung", "xml=student.rdf.php&xsl=Inskription&output=pdf&ss=$studiensemester_kurzbz&xsl_stg_kz=$studiengang_kz", $uid, 50, null),
buildDropdownEntryPrintArray("studienbestaetigung_en", "Studienbestätigung Englisch", "xml=student.rdf.php&xsl=InskriptionEng&output=pdf&ss=$studiensemester_kurzbz&xsl_stg_kz=$studiengang_kz", $uid, 51, null),
buildDropdownEntryPrintArray("zutrittskarte", "Zutrittskarte", "xsl=ZutrittskarteStud&output=pdf&data=$uid", $uid,200, "zutrittskarte.php"),
buildDropdownEntryPrintArray("studienblatt", "Studienblatt", "xml=studienblatt.xml.php&xsl=Studienblatt&output=pdf&ss=$studiensemester_kurzbz", $uid, 60, null),
buildDropdownEntryPrintArray("studienblatt_eng", "Studienblatt Englisch", "xml=studienblatt.xml.php&xsl=StudienblattEng&output=pdf&ss=$studiensemester_kurzbz", $uid, 61, null),
$this->buildStudienerfolgSubmenu("de", $uid, $semArray, $studiensemester_kurzbz),
$this->buildStudienerfolgSubmenu("en", $uid, $semArray, $studiensemester_kurzbz),
$this->buildStudienerfolgSubmenu("de", $uid, $semArray, $studiensemester_kurzbz, true),
$this->buildStudienerfolgSubmenu("en", $uid, $semArray, $studiensemester_kurzbz, true),
[
"id" => "submenu_studstatus",
"type" => "submenu",
"name" => "Verwaltung des StudierendenStatus",
"order" => 110,
"data" => [
buildDropdownEntryPrintArray("Abmeldung", "Abmeldung", "xml=AntragAbmeldung.xml.php&xsl=AntragAbmeldung&prestudent_id=$prestudent_id&output=pdf", $uid, null, null),
buildDropdownEntryPrintArray("Abmeldung durch Stgl", "AntragAbmeldungStgl", "xml=AntragAbmeldungStgl.xml.php&xsl=AntragAbmeldungStgl&prestudent_id=$prestudent_id&output=pdf", $uid, null, null),
buildDropdownEntryPrintArray("Unterbrechung", "Unterbrechung", "xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&prestudent_id=$prestudent_id&output=pdf", $uid, null, null),
buildDropdownEntryPrintArray("Wiederholung", "Abmeldung durch Ablauf der Wiederholungsfrist", "xml=AntragWiederholung.xml.php&xsl=AntragWiederholung&prestudent_id=$prestudent_id&output=pdf", $uid, null, null),
]
],
//Bakkzeugnis bzw. Diplomzeugnis is just shown in tab final_exam
buildDropdownEntryPrintArray("zeugnis", "Zeugnis", "xml=zeugnis.rdf.php&xsl=Zeugnis&output=pdf&xsl_stg_kz=$studiengang_kz&ss=$studiensemester_kurzbz", $uid, 121, null),
buildDropdownEntryPrintArray("zeugnis_en", "Zeugnis Englisch", "xml=zeugnis.rdf.php&xsl=ZeugnisEng&output=pdf&xsl_stg_kz=$studiengang_kz&ss=$studiensemester_kurzbz", $uid, 122, null),
];
Events::trigger('DocumentGenerationDropDown',
// passing $menu per reference
function & () use (&$documents) {
return $documents;
},
$prestudent_id,
$studiensemester_kurzbz,
$studiengang_kz
);
$extraEntries = $this->loadDropDownEntriesBakkOrDipl($stgTyp, $uid);
$documents = array_merge($documents, $extraEntries);
usort($documents, function ($a, $b) {
$orderA = isset($a['order']) ? (int)$a['order'] : PHP_INT_MAX;
$orderB = isset($b['order']) ? (int)$b['order'] : PHP_INT_MAX;
return $orderA <=> $orderB;
});
$this->terminateWithSuccess($documents);
//return $documents || null;
}
public function getDocumentDropDownMulti($studiensemester_kurzbz,$studiengang_kz)
{
//permission to create also odt, and doc outputs of certain documents (menu abschlusspruefung)
$hasPermissionOutputformat = $this->permissionlib->isBerechtigt('system/change_outputformat', 's');
$studentUids = $this->input->get('studentUids');
$prestudentIds = [];
if (is_array($studentUids) && !empty($studentUids)) {
foreach ($studentUids as $uid) {
$prestudent_id = $this-> _loadPrestudentFromUid($uid);
$prestudentIds[] = $prestudent_id;
}
}
else
{
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Array StudentUIDs']), self::ERROR_TYPE_GENERAL);
}
if (!$studiensemester_kurzbz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiensemester']), self::ERROR_TYPE_GENERAL);
if(!$studiengang_kz)
$this->terminateWithError($this->p->t('ui', 'errorMissingValue', ['value' => 'Studiengang_kz']), self::ERROR_TYPE_GENERAL);
$uidString = implode(";", $studentUids);
$prestudentIdsString = implode(";", $prestudentIds);
$semArray = $this->_getEntriesStudiensemester();
$stgTyp = $this->_getStudiengangstyp($studiengang_kz);
$documents = [
buildDropdownEntryPrintArray("accountinfo", "Accountinfoblatt", "xml=accountinfoblatt.xml.php&xsl=AccountInfo&output=pdf", $uidString, 10, null),
buildDropdownEntryPrintArray("ausbildungsvertrag", "Ausbildungsvertrag", "xml=ausbildungsvertrag.xml.php&xsl=Ausbildungsver&output=pdf", $uidString, 20, null),
buildDropdownEntryPrintArray("ausbildungsvertrag_en", "Ausbildungsvertrag Englisch", "xml=ausbildungsvertrag.xml.php&xsl=AusbVerEng&output=pdf", $uidString, 21, null),
buildDropdownEntryPrintArray("studienbestaetigung", "Studienbestätigung", "xml=student.rdf.php&xsl=Inskription&output=pdf&ss=$studiensemester_kurzbz&xsl_stg_kz=$studiengang_kz", $uidString, 50, null),
buildDropdownEntryPrintArray("studienbestaetigung_en", "Studienbestätigung Englisch", "xml=student.rdf.php&xsl=InskriptionEng&output=pdf&ss=$studiensemester_kurzbz&xsl_stg_kz=$studiengang_kz", $uidString, 51, null),
buildDropdownEntryPrintArray("zutrittskarte", "Zutrittskarte", "xsl=ZutrittskarteStud&output=pdf&data=$uidString", $uidString,200, "zutrittskarte.php"),
buildDropdownEntryPrintArray("studienblatt", "Studienblatt", "xml=studienblatt.xml.php&xsl=Studienblatt&output=pdf&ss=$studiensemester_kurzbz", $uidString, 60, null),
buildDropdownEntryPrintArray("studienblatt_eng", "Studienblatt Englisch", "xml=studienblatt.xml.php&xsl=StudienblattEng&output=pdf&ss=$studiensemester_kurzbz", $uidString, 61, null),
// Studienerfolg Menüs automatisch
$this->buildStudienerfolgSubmenu("de", $uidString, $semArray, $studiensemester_kurzbz),
$this->buildStudienerfolgSubmenu("en", $uidString, $semArray, $studiensemester_kurzbz),
$this->buildStudienerfolgSubmenu("de", $uidString, $semArray, $studiensemester_kurzbz, true),
$this->buildStudienerfolgSubmenu("en", $uidString, $semArray, $studiensemester_kurzbz, true),
[
"id" => "submenu_studstatus",
"type" => "submenu",
"name" => "Verwaltung des StudierendenStatus",
"order" => 110,
"data" => [
buildDropdownEntryPrintArray("Abmeldung", "Abmeldung", "xml=AntragAbmeldung.xml.php&xsl=AntragAbmeldung&prestudent_id=$prestudentIdsString&output=pdf", $uidString, null, null),
buildDropdownEntryPrintArray("Abmeldung durch Stgl", "AntragAbmeldungStgl", "xml=AntragAbmeldungStgl.xml.php&xsl=AntragAbmeldungStgl&prestudent_id=$prestudentIdsString&output=pdf", $uidString, null, null),
buildDropdownEntryPrintArray("Unterbrechung", "Unterbrechung", "xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&prestudent_id=$prestudentIdsString&output=pdf", $uidString, null, null),
buildDropdownEntryPrintArray("Wiederholung", "Abmeldung durch Ablauf der Wiederholungsfrist", "xml=AntragWiederholung.xml.php&xsl=AntragWiederholung&prestudent_id=$prestudentIdsString&output=pdf", $uidString, null, null),
]
],
buildDropdownEntryPrintArray("diplomasupp", "Diploma Supplement (nur Voransicht)", "xml=diplomasupplement.xml.php&xsl_stg_kz=$studiengang_kz&xsl=DiplSupplement&output=pdf", $uidString, 35, null),
buildDropdownEntryPrintArray("zeugnis", "Zeugnis", "xml=zeugnis.rdf.php&xsl=Zeugnis&output=pdf&xsl_stg_kz=$studiengang_kz&ss=$studiensemester_kurzbz", $uidString, 121, null),
buildDropdownEntryPrintArray("zeugnis_en", "Zeugnis Englisch", "xml=zeugnis.rdf.php&xsl=ZeugnisEng&output=pdf&xsl_stg_kz=$studiengang_kz&ss=$studiensemester_kurzbz", $uidString, 122, null),
];
Events::trigger('DocumentGenerationDropDownMulti',
// passing $menu per reference
function & () use (&$documents) {
return $documents;
},
$studentUids,
$studiensemester_kurzbz,
$studiengang_kz
);
$extraEntries = $this->loadDropDownEntriesBakkOrDipl($stgTyp, $uidString);
$documents = array_merge($documents, $extraEntries);
usort($documents, function ($a, $b) {
$orderA = isset($a['order']) ? (int)$a['order'] : PHP_INT_MAX;
$orderB = isset($b['order']) ? (int)$b['order'] : PHP_INT_MAX;
return $orderA <=> $orderB;
});
$this->terminateWithSuccess($documents);
return $documents || null;
}
private function _loadUIDFromPrestudent($prestudent_id)
{
if(!$prestudent_id){
return $this->terminateWithError("no prestudent ID received.");
}
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->loadWhere(
['prestudent_id' => $prestudent_id]
);
$data = $this->getDataOrTerminateWithError($result);
if(!(is_array($data) && count($data) > 0))
{
return null;
}
$student = current($data);
return $student->student_uid;
}
private function _loadPrestudentFromUid($studentUid)
{
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->loadWhere(
['student_uid' => $studentUid]
);
$data = $this->getDataOrTerminateWithError($result);
$student = current($data);
return $student->prestudent_id;
}
/**
* is building an array with studiensemesterkurzb
* actual studiensemester plus the 5 studiensemester in the past
* @return Array Studiensemester_kurzbz
*/
private function _getEntriesStudiensemester(){
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addPlusMinus(1, 5);
$this->StudiensemesterModel->addOrder('ende', 'DESC');
$result = $this->StudiensemesterModel->load();
$data = $this->getDataOrTerminateWithError($result);
foreach($data as $sem)
{
$semArray[] = $sem->studiensemester_kurzbz;
}
array_shift($semArray);
return $semArray;
}
/**
* is returning the typ of Studiengang (Bakk oder Master)
* @return character eg. 'b' or 'm'
*/
private function _getStudiengangstyp($studiengang_kz)
{
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$result = $this->StudiengangModel->loadWhere(
array('studiengang_kz' => $studiengang_kz)
);
$data = $this->getDataOrTerminateWithError($result);
$typStudiengang = current($data)->typ;
return $typStudiengang;
}
/**
* helper function to create ArrayStructure
* actual studiensemester plus the 5 studiensemester in the past
* @return Array Studiensemester_kurzbz
*/
private function buildStudienerfolgSubmenu($lang, $uid, $semArray, $studiensemester_kurzbz, $fa = false)
{
$entries = [];
$xsl = $lang === "de" ? "Studienerfolg" : "StudienerfolgEng";
$idPrefix = "submenu_studienerfolg_" . $lang . ($fa ? "_fa" : "");
$entries[] = buildDropdownEntryPrintArray(
$idPrefix . "_aktuell",
"ausgewähltes Semester",
"xml=studienerfolg.rdf.php&xsl=$xsl&ss=$studiensemester_kurzbz" . ($fa ? "&typ=finanzamt" : ""),
$uid
);
//all semester
$entries[] = buildDropdownEntryPrintArray(
$idPrefix . "_all",
"alle Semester",
"xml=studienerfolg.rdf.php&xsl=$xsl&ss=$studiensemester_kurzbz&all=true" . ($fa ? "&typ=finanzamt" : ""),
$uid
);
//sem from array
foreach ($semArray as $i => $sem) {
$entries[] = buildDropdownEntryPrintArray(
$idPrefix . ($i === 0 ? "_akt" : "_minus" . $i),
$sem,
"xml=studienerfolg.rdf.php&xsl=$xsl&ss=$sem" . ($fa ? "&typ=finanzamt" : ""),
$uid
);
}
$order = 0;
if ($lang === "de" && !$fa) $order = 75; // Studienerfolg
if ($lang === "en" && !$fa) $order = 76; // Studienerfolg Englisch
if ($lang === "de" && $fa) $order = 77; // Studienerfolg Finanzamt
if ($lang === "en" && $fa) $order = 78; // Studienerfolg Finanzamt Englisch
return [
"id" => $idPrefix,
"type" => "submenu",
"name" => "Studienerfolg " . ($fa ? " Finanzamt" : "") . ($lang === "de" ? "" : "Englisch") ,
"order" => $order,
"data" => $entries,
];
}
private function loadDropDownEntriesFinalExam($hasPermissionOutputformat, $stgTyp, $uid)
{
if ($stgTyp == 'b')
$postfix = 'Bakk';
else if ($stgTyp == 'm' || $stgTyp == 'd')
$postfix = 'Master';
else
return [];
$arrayFinalExam = [
'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',
],
],
];
$langLabels = [
"de" => "Deutsch",
"en" => "Englisch"
];
$docLabels = [
"pruefungsprotokoll" => "Prüfungsprotokoll",
"pruefungszeugnis" => "Zeugnis",
"urkunde" => "Urkunde"
];
$submenuData = [];
if ($hasPermissionOutputformat) {
foreach ($arrayFinalExam as $docType => $langs) {
foreach ($langs as $lang => $types) {
$xsl = $types[$postfix];
$idPrefix = $docType . "_" . $lang;
$baseName = $docLabels[$docType] . " " . $langLabels[$lang];
$baseUrl = "xml=abschlusspruefung.rdf.php&xsl={$xsl}";
//3 outputformates
foreach (["pdf", "odt", "docx"] as $format) {
$submenuData[] = buildDropdownEntryPrintArray(
$idPrefix . "_" . $format,
$baseName . " (" . strtoupper($format) . ")",
$baseUrl . "&output=" . $format,
$uid
);
}
}
}
}
else
{
foreach ($arrayFinalExam as $docType => $langs) {
foreach ($langs as $lang => $types) {
$xsl = $types[$postfix]; // Auswahl Bakk/Master für jeweilige Sprache
$id = $docType . "_" . $lang;
$name = $docLabels[$docType] . " " . $langLabels[$lang];
$url = "xml=abschlusspruefung.rdf.php&xsl=" . $xsl . "&output=pdf";
$submenuData[] = buildDropdownEntryPrintArray($id, $name, $url, $uid);
}
}
}
return [
"id" => "submenu_finalexam",
"type" => "submenu",
"name" => "Abschlussprüfung",
"data" => $submenuData,
"order" => null,
"order" => 80,
];
}
private function loadDropDownEntriesBakkOrDipl($stgTyp, $uid)
{
$entries = [];
if ($stgTyp == 'b')
{
$entries[] = buildDropdownEntryPrintArray("bakkurkunde", "Bakkurkunde", "xml=abschlusspruefung.rdf.php&xsl=Bakkurkunde&output=pdf", $uid, 22, null);
$entries[] = buildDropdownEntryPrintArray("bakkurkundeEng", "Bakkurkunde Englisch", "xml=abschlusspruefung.rdf.php&xsl=BakkurkundeEng&output=pdf", $uid, 23, null);
}
if ($stgTyp == 'm' || $stgTyp == 'd')
{
$entries[] = buildDropdownEntryPrintArray("diplomurkunde", "Diplomurkunde", "xml=abschlusspruefung.rdf.php&xsl=Diplomurkunde&output=pdf", $uid, 27, null);
$entries[] = buildDropdownEntryPrintArray("diplomurkundeEng", "Diplomurkunde Englisch", "xml=abschlusspruefung.rdf.php&xsl=DiplomurkundeEng&output=pdf", $uid, 28, null);
}
return $entries;
}
}
@@ -83,7 +83,7 @@ class GemeinsameStudien extends FHCAPI_Controller
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addOrder('studienjahr_kurzbz', 'DESC');
$this->StudiensemesterModel->addOrder('start', 'DESC');
$result = $this->StudiensemesterModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
@@ -60,7 +60,8 @@ class Grades extends FHCAPI_Controller
{
$this->load->model('codex/Note_model', 'NoteModel');
$this->NoteModel->addOrder('note');
$this->NoteModel->addOrder('notenwert', 'ASC');
$this->NoteModel->addOrder('bezeichnung', 'ASC');
$result = $this->NoteModel->load();
@@ -9,6 +9,8 @@ class Gruppen extends FHCAPI_Controller
public function __construct()
{
parent::__construct([
'add' => ['admin:rw', 'assistenz:rw'],
'search' => ['admin:r', 'assistenz:r'],
'getGruppen' => ['admin:r', 'assistenz:r'],
'deleteGruppe' => ['admin:rw', 'assistenz:rw'],
]);
@@ -18,7 +20,9 @@ class Gruppen extends FHCAPI_Controller
// Load language phrases
$this->loadPhrases([
'ui', 'gruppenmanagement'
'ui',
'gruppenmanagement',
'lehre'
]);
// Load models
@@ -26,15 +30,141 @@ class Gruppen extends FHCAPI_Controller
$this->load->model('organisation/Gruppe_model', 'GruppeModel');
}
public function add()
{
$this->load->library("form_validation");
$this->form_validation->set_rules(
'gruppe_kurzbz',
$this->p->t('gruppenmanagement', 'gruppe'),
'required|is_in_db[organisation/Gruppe_model]',
[
'required' => $this->p->t('ui', 'error_fieldRequired'),
'is_in_db' => $this->p->t('ui', 'error_fieldNotFound')
]
);
$this->form_validation->set_rules(
'uid',
$this->p->t('ui', 'student_uid'),
'required|is_in_db[crm/Student_model:student_uid]',
[
'required' => $this->p->t('ui', 'error_fieldRequired'),
'is_in_db' => $this->p->t('ui', 'error_fieldNotFound')
]
);
$this->form_validation->set_rules(
'studiensemester_kurzbz',
$this->p->t('lehre', 'studiensemester'),
'required|is_in_db[organisation/Studiensemester_model]',
[
'required' => $this->p->t('ui', 'error_fieldRequired'),
'is_in_db' => $this->p->t('ui', 'error_fieldNotFound')
]
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$gruppe_kurzbz = $this->input->post('gruppe_kurzbz');
$uid = $this->input->post('uid');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$result = $this->BenutzergruppeModel->load([
$gruppe_kurzbz,
$uid
]);
$benutzergruppe = $this->getDataOrTerminateWithError($result);
if ($benutzergruppe) {
$this->terminateWithError(
$this->p->t('gruppenmanagement', 'error_alreadyInGroup', [
'uid' => $uid,
'studiensemester_kurzbz' => current($benutzergruppe)->studiensemester_kurzbz
]),
self::ERROR_TYPE_GENERAL
);
}
$result = $this->BenutzergruppeModel->insert([
'uid' => $uid,
'gruppe_kurzbz' => $gruppe_kurzbz,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'insertamum' => date('c'),
'insertvon' => getAuthUID()
]);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess();
}
public function search()
{
$query = $this->input->post('query');
if (!$query)
$this->terminateWithSuccess([]);
// add query to where clause
$query = strtoupper($query);
$query = $this->GruppeModel->db->escape_like_str($query);
$query = '%' . str_replace(' ', '%', $query) . '%';
$this->GruppeModel->db->group_start();
$this->GruppeModel->db->or_like('UPPER(gruppe_kurzbz)', $query, 'none', false);
$this->GruppeModel->db->or_like('UPPER(bezeichnung)', $query, 'none', false);
$this->GruppeModel->db->or_like('UPPER(beschreibung)', $query, 'none', false);
$this->GruppeModel->db->group_end();
// add stg sorting 1
$studiengang_kz = $this->input->post('studiengang_kz');
$sort_stg = $studiengang_kz ? "WHEN studiengang_kz = " . $this->GruppeModel->escape($studiengang_kz) . " THEN 0" : "";
// add stg sorting 2
$studiengang_kzs = [];
$result = $this->permissionlib->getSTG_isEntitledFor('admin');
if ($result)
$studiengang_kzs = array_merge($studiengang_kzs, $result);
$result = $this->permissionlib->getSTG_isEntitledFor('assistenz');
if ($result)
$studiengang_kzs = array_merge($studiengang_kzs, $result);
// selects
$this->GruppeModel->addSelect("*");
$this->GruppeModel->addSelect("CASE
" . $sort_stg . "
WHEN studiengang_kz IN (" . implode(",", $this->GruppeModel->db->escape($studiengang_kzs)) . ")
THEN 1
ELSE 2
END AS sort_stg");
// ordering
$this->GruppeModel->addOrder("sort_stg");
$this->GruppeModel->addOrder("sort");
$this->GruppeModel->addOrder("gruppe_kurzbz");
// default where clause & execute
$result = $this->GruppeModel->loadWhere([
'lehre' => true,
'sichtbar' => true,
'aktiv' => true,
'direktinskription' => false,
'generiert' => false
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
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');
$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(
@@ -49,29 +179,48 @@ class Gruppen extends FHCAPI_Controller
public function deleteGruppe()
{
$student_uid = $this->input->post('id');
$this->load->library("form_validation");
$this->form_validation->set_rules(
'uid',
$this->p->t('person', 'UID'),
'required',
[
'required' => $this->p->t('ui', 'error_fieldRequired')
]
);
$this->form_validation->set_rules(
'gruppe_kurzbz',
$this->p->t('gruppenmanagement', 'gruppe'),
'required',
[
'required' => $this->p->t('ui', 'error_fieldRequired')
]
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$uid = $this->input->post('uid');
$gruppe_kurzbz = $this->input->post('gruppe_kurzbz');
//Validate if automatic group generation
$result = $this->GruppeModel-> loadWhere(
array(
'gruppe_kurzbz' => $gruppe_kurzbz
)
);
// Validate if automatic group generation
$result = $this->GruppeModel->loadWhere([
'gruppe_kurzbz' => $gruppe_kurzbz
]);
$data = $this->getDataOrTerminateWithError($result);
$generation = current($data);
if($generation->generiert)
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
)
);
$result = $this->BenutzergruppeModel->delete([
'gruppe_kurzbz' => $gruppe_kurzbz,
'uid' => $uid
]);
$data = $this->getDataOrTerminateWithError($result);
@@ -52,6 +52,7 @@ class Kontakt extends FHCAPI_Controller
// Extra Permissionchecks
$permsMa = [];
$permsStud = [];
$permsDefault = null;
switch ($this->router->method) {
case 'getBankverbindung':
case 'loadBankverbindung':
@@ -68,7 +69,7 @@ class Kontakt extends FHCAPI_Controller
case 'getKontakte':
case 'loadAddress':
case 'loadContact':
$permsMa = $permsStud = ['admin:r', 'assistenz:r'];
$permsMa = $permsStud = $permsDefault = ['admin:r', 'assistenz:r'];
break;
case 'addNewAddress':
case 'addNewContact':
@@ -76,7 +77,7 @@ class Kontakt extends FHCAPI_Controller
case 'updateContact':
case 'deleteAddress':
case 'deleteContact':
$permsMa = $permsStud = ['admin:rw', 'assistenz:rw'];
$permsMa = $permsStud = $permsDefault = ['admin:rw', 'assistenz:rw'];
break;
}
if ($this->router->method == 'getAdressen'
@@ -91,7 +92,7 @@ class Kontakt extends FHCAPI_Controller
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);
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud, $permsDefault);
} elseif ($this->router->method == 'loadAddress'
|| $this->router->method == 'loadContact'
|| $this->router->method == 'loadBankverbindung'
@@ -135,7 +136,7 @@ class Kontakt extends FHCAPI_Controller
$person_id = current($data)->person_id;
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud);
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud, $permsDefault);
}
}
public function getAdressen($person_id)
@@ -48,7 +48,8 @@ class Konto extends FHCAPI_Controller
// Load language phrases
$this->loadPhrases([
'konto'
'konto',
'lehre'
]);
}
@@ -112,7 +113,7 @@ class Konto extends FHCAPI_Controller
*
* @return void
*/
public function getBuchungstypen()
public function getBuchungstypen($studiensemester_kurzbz = null)
{
$this->load->model('crm/Buchungstyp_model', 'BuchungstypModel');
@@ -122,6 +123,7 @@ class Konto extends FHCAPI_Controller
$data = $this->getDataOrTerminateWithError($result);
$this->_getOEHBeitrag($data, $studiensemester_kurzbz);
$this->terminateWithSuccess($data);
}
@@ -239,7 +241,7 @@ class Konto extends FHCAPI_Controller
$data[$field] = $this->input->post($field);
if (defined('FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE') && isset(unserialize(FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE)[$data['buchungstyp_kurzbz']])) {
$data['kostenstelle'] = unserialize(FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE)[$data['buchungstyp_kurzbz']];
$data['studiengang_kz'] = unserialize(FAS_BUCHUNGSTYP_FIXE_KOSTENSTELLE)[$data['buchungstyp_kurzbz']];
}
$result = [];
@@ -352,7 +354,7 @@ class Konto extends FHCAPI_Controller
continue;
}
$result = $this->KontoModel->insert([
'person_id' => $buchung['person_id'],
'studiengang_kz' => $buchung['studiengang_kz'],
@@ -361,7 +363,7 @@ class Konto extends FHCAPI_Controller
'buchungstyp_kurzbz' => $buchung['buchungstyp_kurzbz'],
'credit_points' => $buchung['credit_points'],
'zahlungsreferenz' => $buchung['zahlungsreferenz'],
'betrag' => $betrag,
'betrag' => number_format($betrag, 2, '.', ''),
'buchungsdatum' => $buchungsdatum,
'mahnspanne' => '0',
'buchungsnr_verweis' => $buchung['buchungsnr'],
@@ -494,4 +496,43 @@ class Konto extends FHCAPI_Controller
$this->terminateWithSuccess();
}
private function _getOEHBeitrag(&$data, $studiensemester_kurzbz = null)
{
if (is_null($studiensemester_kurzbz))
{
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$studiensemester_akt = $this->variablelib->getVar('semester_aktuell');
}
else
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
if ($this->StudiensemesterModel->isValidStudiensemester($studiensemester_kurzbz))
$studiensemester_akt = $studiensemester_kurzbz;
else
$this->terminateWithError($this->p->t('lehre', 'error_noStudiensemester'));
}
$this->load->model('codex/Oehbeitrag_model', 'OehbeitragModel');
$oehBeitrag = $this->OehbeitragModel->getByStudiensemester($studiensemester_akt);
$oehStandardbetrag = null;
if (hasData($oehBeitrag))
{
$oeh = getData($oehBeitrag)[0];
$summe = ($oeh->studierendenbeitrag + $oeh->versicherung) * -1;
$oehStandardbetrag = number_format((float)$summe, 2, '.', '');
}
if ($oehStandardbetrag !== null)
{
$data = array_map(function ($buchungstyp) use ($oehStandardbetrag) {
if (isset($buchungstyp->buchungstyp_kurzbz) && (strtolower($buchungstyp->buchungstyp_kurzbz) === 'oeh'))
{
$buchungstyp->standardbetrag = $oehStandardbetrag;
}
return $buchungstyp;
}, $data);
}
}
}
@@ -0,0 +1,63 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Lehrverband extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'hasOrgforms' => ['admin:r', 'assistenz:r'],
'getTree' => ['admin:r', 'assistenz:r'],
'getSpecialgroups' => ['admin:r', 'assistenz:r']
]);
}
public function hasOrgforms($studiengang_kz)
{
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$result = $this->StudiengangModel->load($studiengang_kz);
$data = $this->getDataOrTerminateWithError($result);
if ($data) {
$data = current($data)->mischform;
}
$this->terminateWithSuccess($data);
}
public function getTree($studiengang_kz)
{
$this->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
$result = $this->LehrverbandModel->loadWhere([
'studiengang_kz' => $studiengang_kz,
'aktiv' => true
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getSpecialgroups($studiengang_kz)
{
$this->load->model('organisation/Gruppe_model', 'GruppeModel');
$where = [
'studiengang_kz' => $studiengang_kz,
'lehre' => true,
'sichtbar' => true,
'aktiv' => true,
'direktinskription' => false
];
$result = $this->GruppeModel->loadWhere($where);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -43,7 +43,7 @@ class Prestudent extends FHCAPI_Controller
// Load language phrases
$this->loadPhrases([
'ui', 'studierendenantrag', 'lehre'
'ui', 'studierendenantrag', 'lehre', 'global'
]);
}
@@ -98,11 +98,9 @@ class Prestudent extends FHCAPI_Controller
'person_id',
'berufstaetigkeit_code',
'ausbildungcode',
'zgv_code',
'zgvort',
'zgvdatum',
'zgvnation',
'zgvmas_code',
'zgvmaort',
'zgvmadatum',
'zgvmanation',
@@ -110,7 +108,6 @@ class Prestudent extends FHCAPI_Controller
'bismelden',
'anmerkung',
'dual',
'zgvdoktor_code',
'zgvdoktorort',
'zgvdoktordatum',
'zgvdoktornation',
@@ -125,6 +122,57 @@ class Prestudent extends FHCAPI_Controller
'standort_code'
];
// add zgv code fields only if user has permission
$this->load->library('PermissionLib');
$prestudentres = $this->PrestudentModel->load($prestudent_id);
if(!hasData($prestudentres))
{
$this->terminateWithError($this->p->t('ui', 'error_fieldNotFound', ['field' => 'Prestudent ' . $prestudent_id]));
}
$prestudent = (getData($prestudentres))[0];
$bakkZgvStg = $this->permissionlib->getSTG_isEntitledFor('student/editBakkZgv') ?: array();
$makkZgvStg = $this->permissionlib->getSTG_isEntitledFor('student/editMakkZgv') ?: array();
$dokZgvStg = $this->permissionlib->getSTG_isEntitledFor('student/editDokZgv') ?: array();
if(in_array($prestudent->studiengang_kz, $bakkZgvStg))
{
$array_allowed_props_prestudent[] = 'zgv_code';
}
else if(!is_null($this->input->post('zgv_code')))
{
$this->terminateWithError(
$this->p->t('global', 'zgv')
. ' - ' .
$this->p->t('ui', 'error_keineBerechtigungStg')
);
}
if(in_array($prestudent->studiengang_kz, $makkZgvStg))
{
$array_allowed_props_prestudent[] = 'zgvmas_code';
}
else if(!is_null($this->input->post('zgvmas_code')))
{
$this->terminateWithError(
$this->p->t('lehre', 'zgvMaster')
. ' - ' .
$this->p->t('ui', 'error_keineBerechtigungStg')
);
}
if(in_array($prestudent->studiengang_kz, $dokZgvStg))
{
$array_allowed_props_prestudent[] = 'zgvdoktor_code';
}
else if(!is_null($this->input->post('zgvdoktor_code')))
{
$this->terminateWithError(
$this->p->t('lehre', 'zgvDoktor')
. ' - ' .
$this->p->t('ui', 'error_keineBerechtigungStg')
);
}
// add UDFs
$result = $this->udflib->getDefinitionForModel($this->PrestudentModel);
@@ -0,0 +1,413 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Projektarbeit extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getProjektarbeit' => ['admin:r', 'assistenz:r'],
'loadProjektarbeit' => ['admin:r', 'assistenz:r'],
'insertProjektarbeit' => ['admin:rw', 'assistenz:rw'],
'updateProjektarbeit' => ['admin:rw', 'assistenz:rw'],
'deleteProjektarbeit' => ['admin:rw', 'assistenz:rw'],
'getTypenProjektarbeit' => ['admin:r', 'assistenz:r'],
'getFirmen' => ['admin:r', 'assistenz:r'],
'getLehrveranstaltungen' => ['admin:r', 'assistenz:r'],
'getNoten' => ['admin:r', 'assistenz:r'],
'getStudiensemester' => ['admin:r', 'assistenz:r']
]);
// Load Libraries
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'person',
'projektarbeit'
]);
// Load models
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$this->load->model('education/Projekttyp_model', 'ProjekttypModel');
$this->load->model('education/Paabgabe_model', 'PaabgabeModel');
$this->load->model('ressource/Firma_model', 'FirmaModel');
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('education/Note_model', 'NoteModel');
$this->load->model('education/Projektbetreuer_model', 'BetreuerModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
// load libraries
$this->load->library('PermissionLib');
}
/**
* Get projekt works for a uid.
*/
public function getProjektarbeit()
{
$student_uid = $this->input->get('uid');
if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
$result = $this->ProjektarbeitModel->getProjektarbeit($student_uid);
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
if (!hasData($result)) $this->terminateWithSuccess([]);
$projektarbeiten = getData($result);
foreach ($projektarbeiten as $projektarbeit)
{
$projektarbeit_id = $projektarbeit->projektarbeit_id;
$abgabeRes = $this->PaabgabeModel->getEndabgabe($projektarbeit_id);
if (isError($abgabeRes)) $this->terminateWithError(getError($abgabeRes), self::ERROR_TYPE_GENERAL);
if (hasData($abgabeRes))
{
$paabgabe = getData($abgabeRes)[0];
$projektarbeit->abgabedatum = $paabgabe->abgabedatum;
}
}
$this->terminateWithSuccess($projektarbeiten);
}
/**
* Load a single Projektarbeit by id.
*/
public function loadProjektarbeit()
{
$projektarbeit_id = $this->input->get('projektarbeit_id');
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id)) return $this->terminateWithError('Projektarbeit Id missing', self::ERROR_TYPE_GENERAL);
$this->ProjektarbeitModel->addSelect(
'lehre.tbl_projektarbeit.projektarbeit_id, titel, titel_english, themenbereich, projekttyp_kurzbz, lehrveranstaltung_id, lehreinheit_id,
firma_id, beginn, ende, gesperrtbis, note, final, freigegeben, tbl_projektarbeit.anmerkung, fa.name AS firma_name'
);
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
$this->ProjektarbeitModel->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
$this->ProjektarbeitModel->addJoin('public.tbl_firma fa', 'firma_id', 'LEFT');
$result = $this->ProjektarbeitModel->loadWhere(
array('projektarbeit_id' => $projektarbeit_id)
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
/**
* Inwert a Projektarbeit.
*/
public function insertProjektarbeit()
{
$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);
if (!$this->_hasBerechtigungForStudent($student_uid))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
$formData = $this->input->post('formData');
if ($this->_validate($formData) == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$projektarbeit = $this->_getProjektarbeitArr($formData);
$result = $this->ProjektarbeitModel->insert(
array_merge($projektarbeit, ['insertamum' => date('c'), 'insertvon' => getAuthUID(), 'student_uid' => $student_uid])
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* Update a Projektarbeit by ID.
*/
public function updateProjektarbeit()
{
$projektarbeit_id = $this->input->post('projektarbeit_id');
if (!$projektarbeit_id || !is_numeric($projektarbeit_id))
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID']), self::ERROR_TYPE_GENERAL);
if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
$formData = $this->input->post('formData');
if ($this->_validate($formData) == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$projektarbeit = $this->_getProjektarbeitArr($formData);
$result = $this->ProjektarbeitModel->update(
$projektarbeit_id,
array_merge($projektarbeit, ['updateamum' => date('c'), 'updatevon' => getAuthUID()])
);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* Delete Projektarbeit by ID after validation.
*/
public function deleteProjektarbeit()
{
$projektarbeit_id = $this->input->post('projektarbeit_id');
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id))
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID'], self::ERROR_TYPE_GENERAL));
if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
$validate = $this->_validateDelete($projektarbeit_id);
if (isError($validate)) return $this->terminateWithError(getError($validate), self::ERROR_TYPE_GENERAL);
$result = $this->ProjektarbeitModel->delete(
['projektarbeit_id' => $projektarbeit_id]
);
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
if (!hasData($result))
{
$this->outputJson($result);
}
return $this->terminateWithSuccess(current(getData($result)) ? : null);
}
/**
* Get all active projekt work types.
*/
public function getTypenProjektarbeit()
{
$result = $this->ProjekttypModel->loadWhere(['aktiv' => true]);
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
/**
* Gets companies by search string.
*/
public function getFirmen()
{
$searchString = $this->input->get('searchString');
if (!isset($searchString))
$this->terminateWithError($this->p->t('ui', 'error_fieldRequired', ['field' => 'Search term']), self::ERROR_TYPE_GENERAL);
$result = $this->FirmaModel->searchFirmen($searchString, $aktiv = true);
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
/**
* Get Lehrveranstaltungen by params, incling lehreinheiten for a specific Studiensemester..
*/
public function getLehrveranstaltungen()
{
$student_uid = $this->input->get('student_uid');
$studiengang_kz = $this->input->get('studiengang_kz');
$studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz');
$additional_lehrveranstaltung_id = $this->input->get('additional_lehrveranstaltung_id');
if (!isset($student_uid)) $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Student UID']), self::ERROR_TYPE_GENERAL);
if (!isset($studiensemester_kurzbz)) $this->terminateWithError('Studiensemster missing', self::ERROR_TYPE_GENERAL);
// get Lvs
$lvsResult = $this->LehrveranstaltungModel->getLvsForProjektarbeit($student_uid, $studiengang_kz, $additional_lehrveranstaltung_id);
if (isError($lvsResult)) return $this->terminateWithError($lvsResult, self::ERROR_TYPE_GENERAL);
$lvs = hasData($lvsResult) ? getData($lvsResult) : [];
foreach ($lvs as $lv)
{
// add Lehreinheiten for each Lv for the semester
$lehreinheiten = $this->LehreinheitModel->getLesForLv(
$lv->lehrveranstaltung_id, $studiensemester_kurzbz
);
foreach ($lehreinheiten as $lehreinheit)
{
if (!isEmptyArray($lehreinheit->lektoren))
{
$this->MitarbeiterModel->addSelect('kurzbz');
$this->MitarbeiterModel->db->where_in('tbl_mitarbeiter.mitarbeiter_uid', $lehreinheit->lektoren);
$maResult = $this->MitarbeiterModel->load();
if (isError($maResult)) return $this->terminateWithError($lvsResult, self::ERROR_TYPE_GENERAL);
$lehreinheit->lektoren = array_column(getData($maResult), 'kurzbz');
}
}
$lv->lehreinheiten = $lehreinheiten;
}
return $this->terminateWithSuccess($lvs);
}
/**
* Get all noten.
*/
public function getNoten()
{
$this->NoteModel->addOrder('notenwert', 'ASC');
$this->NoteModel->addOrder('bezeichnung', 'ASC');
$result = $this->NoteModel->load();
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
/**
* Get all Studiensemester, sorted.
*/
public function getStudiensemester()
{
$this->StudiensemesterModel->addOrder('start', 'DESC');
$result = $this->StudiensemesterModel->load();
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
/**
* Validate Projektarbeit data.
* @param formData
* @return bool true if data valid
*/
private function _validate($formData)
{
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('projekttyp_kurzbz', 'Projekttyp', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Projekttyp'])
]);
$this->form_validation->set_rules('lehreinheit_id', 'Lehreinheit', 'required|is_natural', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Lehreinheit']),
'is_natural' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Lehreinheit'])
]);
$this->form_validation->set_rules('beginn', 'Beginn', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Beginn'])
]);
$this->form_validation->set_rules('ende', 'Ende', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Ende'])
]);
$this->form_validation->set_rules('gesperrtbis', 'Ende', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_notValidDate', ['field' => 'Gesperrt bis'])
]);
return $this->form_validation->run();
}
/**
* Extract Projektarbeit data from passed form data.
* @param formData
* @return array
*/
private function _getProjektarbeitArr($formData)
{
return [
'titel' => $formData['titel'],
'titel_english' => $formData['titel_english'] ?? null,
'themenbereich' => $formData['themenbereich'] ?? null,
'projekttyp_kurzbz' => $formData['projekttyp_kurzbz'],
'firma_id' => $formData['firma_id'] ?? null,
'lehreinheit_id' => $formData['lehreinheit_id'],
'beginn' => isset($formData['beginn']) && !isEmptyString($formData['beginn']) ? $formData['beginn'] : null,
'ende' => isset($formData['ende']) && !isEmptyString($formData['ende']) ? $formData['ende'] : null,
'note' => $formData['note'] ?? null,
'final' => $formData['final'] ?? null,
'freigegeben' => $formData['freigegeben'] ?? null,
'anmerkung' => $formData['anmerkung'] ?? null,
'gesperrtbis' => isset($formData['gesperrtbis']) && !isEmptyString($formData['gesperrtbis']) ? $formData['gesperrtbis'] : null
];
}
/**
* Check if deletion of a Projektarbeit is possible.
* @param $projektarbeit_id
* @return object success if deletion possible, error otherwise.
*/
private function _validateDelete($projektarbeit_id)
{
$this->BetreuerModel->addSelect('1');
$result = $this->BetreuerModel->loadWhere(['projektarbeit_id' => $projektarbeit_id]);
if (isError($result)) return $result;
if (hasData($result)) return error($this->p->t('projektarbeit', 'error_betreuerNichtGeloescht'));
$this->PaabgabeModel->addSelect('1');
$result = $this->PaabgabeModel->loadWhere(['projektarbeit_id' => $projektarbeit_id]);
if (isError($result)) return $result;
if (hasData($result)) return error($this->p->t('projektarbeit', 'error_paabgabeNichtGeloescht'));
return success();
}
/**
* Checks permissions for a student.
* @param $student_uid
* @return bool true if authorized
*/
private function _hasBerechtigungForStudent($student_uid)
{
if (!$student_uid)
return false;
$this->load->model('crm/Student_model', 'StudentModel');
$this->StudentModel->addSelect('studiengang_kz');
$result = $this->StudentModel->load([$student_uid]);
if (isError($result) || !hasData($result))
return false;
$studiengang_kz = getData($result)[0]->studiengang_kz;
if ($this->permissionlib->isBerechtigt('admin', 'suid', $studiengang_kz))
return true;
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $studiengang_kz))
return true;
return false;
}
}
@@ -0,0 +1,435 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
use \CI3_Events as Events;
class Projektbetreuer extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getProjektbetreuer' => ['admin:r', 'assistenz:r'],
'saveProjektbetreuer' => ['admin:rw', 'assistenz:rw'],
'deleteProjektbetreuer' => ['admin:rw', 'assistenz:rw'],
'getBetreuerarten' => ['admin:r', 'assistenz:r'],
'getNoten' => ['admin:r', 'assistenz:r'],
'getDefaultStundensaetze' => ['admin:r', 'assistenz:r'],
'getProjektbetreuerBySearchQuery' => ['admin:r', 'assistenz:r'],
'getPerson' => ['admin:r', 'assistenz:r'],
'validateProjektbetreuer' => ['admin:r', 'assistenz:r']
]);
// Load Libraries
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'person',
'projektarbeit'
]);
// Load models
$this->load->model('education/Projektbetreuer_model', 'ProjektbetreuerModel');
$this->load->model('education/Betreuerart_model', 'BetreuerartModel');
$this->load->model('ressource/Stundensatz_model', 'StundensatzModel');
$this->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$this->load->model('education/Note_model', 'NoteModel');
$this->load->model('person/Person_model', 'PersonModel');
// load libraries
$this->load->library('PermissionLib');
}
/**
* Gets Projektbetreuer data for a Projektarbeit.
*/
public function getProjektbetreuer()
{
$projektarbeit_id = $this->input->get('projektarbeit_id');
if (!isset($projektarbeit_id))
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID']), self::ERROR_TYPE_GENERAL);
$qry = "
SELECT * FROM (
SELECT
projektarbeit_id, person_id, nachname, vorname, note, punkte, round(stunden, 1) AS stunden,
stundensatz, betreuerart_kurzbz, vertrag_id, titelpre, titelpost,
CASE
WHEN EXISTS
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE person_id=pers.person_id)
THEN 'Mitarbeiter'
WHEN EXISTS
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_student ON(uid=student_uid) WHERE person_id=pers.person_id)
THEN 'Student'
ELSE 'Person'
END AS status
FROM
lehre.tbl_projektbetreuer
JOIN public.tbl_person pers USING (person_id)
WHERE
projektarbeit_id = ?
) betreuer
ORDER BY
CASE WHEN status = 'Mitarbeiter' THEN 0 WHEN status = 'Person' THEN 1 ELSE 2 END";
$result = $this->ProjektbetreuerModel->execReadOnlyQuery($qry, [$projektarbeit_id]);
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
if (!hasData($result)) $this->terminateWithSuccess([]);
$projektbetreuer = getData($result);
//~ foreach ($projektbetreuer as $projektarbeit)
//~ {
//~ $projektarbeit_id = $projektarbeit->projektarbeit_id;
//~ $abgabeRes = $this->PaabgabeModel->getEndabgabe($projektarbeit_id);
//~ if (isError($abgabeRes)) $this->terminateWithError(getError($abgabeRes), self::ERROR_TYPE_GENERAL);
//~ if (hasData($abgabeRes))
//~ {
//~ $paabgabe = getData($abgabeRes)[0];
//~ $projektarbeit->abgabedatum = $paabgabe->abgabedatum;
//~ }
//~ }
// add thesis download link (from external extension)
foreach ($projektbetreuer as $pb)
{
$downloadLink = null;
Events::trigger(
'projektbeurteilung_download_link',
$pb->projektarbeit_id,
$pb->betreuerart_kurzbz,
$pb->person_id,
function ($value) use (&$downloadLink) {
$downloadLink = $value;
}
);
$pb->beurteilungDownloadLink = $downloadLink;
}
$this->terminateWithSuccess($this->_addFullNameToBetreuer($projektbetreuer));
}
/**
* Saves (adds or updates) a single Projektbetreuer for a Projektarbeit.
*/
public function saveProjektbetreuer()
{
$projektarbeit_id = $this->input->post('projektarbeit_id');
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id))
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Projektarbeit ID']), self::ERROR_TYPE_GENERAL);
if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
$projektbetreuer = $this->input->post('projektbetreuer');
if ($this->_validate($projektbetreuer) == false) $this->terminateWithValidationErrors($this->form_validation->error_array());
// check if assessor has already been assigned
if (isset($projektbetreuer['person_id']))
{
$this->ProjektbetreuerModel->addSelect('1');
$betreuerRes = $this->ProjektbetreuerModel->loadWhere(
[
'person_id' => $projektbetreuer['person_id'],
'projektarbeit_id' => $projektbetreuer['projektarbeit_id'],
'betreuerart_kurzbz' => $projektbetreuer['betreuerart_kurzbz']
]
);
if (hasData($betreuerRes)
&& (!isset($projektbetreuer['person_id_old']) || $projektbetreuer['person_id'] != $projektbetreuer['person_id_old'])) {
return $this->terminateWithError($this->p->t('projektarbeit', 'betreuerZugewiesen'), self::ERROR_TYPE_GENERAL);
}
}
$result = null;
$stunden = isset($projektbetreuer['stunden']) && !isEmptyString($projektbetreuer['stunden']) ? $projektbetreuer['stunden'] : null;
$stundensatz =
isset($projektbetreuer['stundensatz']) && !isEmptyString($projektbetreuer['stundensatz']) ? $projektbetreuer['stundensatz'] : null;
$betreuer = [
'projektarbeit_id' => $projektarbeit_id,
'person_id' => $projektbetreuer['person_id'],
'note' => $projektbetreuer['note'],
'stunden' => $stunden,
'stundensatz' => $stundensatz,
'betreuerart_kurzbz' => $projektbetreuer['betreuerart_kurzbz']
];
if (isset($projektbetreuer['person_id_old']) && isset($projektbetreuer['betreuerart_kurzbz_old']))
{
$result = $this->ProjektbetreuerModel->update(
[
'projektarbeit_id' => $projektarbeit_id,
'person_id' => $projektbetreuer['person_id_old'],
'betreuerart_kurzbz' => $projektbetreuer['betreuerart_kurzbz_old']
],
array_merge($betreuer, ['updateamum' => date('c'), 'updatevon' => getAuthUID()])
);
}
else
{
$result = $this->ProjektbetreuerModel->insert(
array_merge($betreuer, ['insertamum' => date('c'), 'insertvon' => getAuthUID()])
);
}
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
/**
* Delete a Projektbetreuer assignment to a Projektarbeit.
*/
public function deleteProjektbetreuer()
{
$projektarbeit_id = $this->input->post('projektarbeit_id');
$person_id = $this->input->post('person_id');
$betreuerart_kurzbz = $this->input->post('betreuerart_kurzbz');
if (!isset($projektarbeit_id) || !is_numeric($projektarbeit_id))
{
return $this->terminateWithError(
$this->p->t('ui', 'error_missingId', ['id'=> $this->p->t('projektarbeit', 'projektarbeit').' ID'], self::ERROR_TYPE_GENERAL)
);
}
if (!isset($person_id) || !is_numeric($person_id))
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID'], self::ERROR_TYPE_GENERAL));
if (!isset($betreuerart_kurzbz))
{
return $this->terminateWithError(
$this->p->t('ui', 'error_missingId', ['id'=> $this->p->t('projektarbeit', 'betreuerart')], self::ERROR_TYPE_GENERAL)
);
}
// check permission
if (!$this->ProjektarbeitModel->hasBerechtigungForProjektarbeit($projektarbeit_id))
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'assistenz:rw']]);
$validate = $this->_validateDelete($projektarbeit_id, $person_id, $betreuerart_kurzbz);
if (isError($validate)) return $this->terminateWithError(getError($validate), self::ERROR_TYPE_GENERAL);
// check if there is a Projektarbeitsbeurteilung - if yes, it is handled (possibly deleted) by external extension.
$beurteilungDeleteSuccess = true;
Events::trigger(
'projektarbeitsbeurteilung_delete',
$projektarbeit_id,
function ($value) use (&$beurteilungDeleteSuccess) {
$beurteilungDeleteSuccess = $value;
}
);
// if there is still a Beurteilung, Projektarbeit cannot be deleted - return with error
if (!$beurteilungDeleteSuccess) return $this->terminateWithError($this->p->t('projektarbeit', 'error_paarbeitHatBeurteilung'));
$result = $this->ProjektbetreuerModel->delete(
['projektarbeit_id' => $projektarbeit_id, 'person_id' => $person_id, 'betreuerart_kurzbz' => $betreuerart_kurzbz]
);
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
if (!hasData($result))
{
$this->outputJson($result);
}
return $this->terminateWithSuccess(getData($result));
}
/**
* Get all active Betreuerarten.
*/
public function getBetreuerarten()
{
$result = $this->BetreuerartModel->loadWhere(['aktiv' => true]);
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
/**
* Get all Noten.
*/
public function getNoten()
{
$result = $this->NoteModel->load();
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
return $this->terminateWithSuccess(hasData($result) ? getData($result) : []);
}
/**
* Get default Stundensätze for an employee in a semester.
*/
public function getDefaultStundensaetze()
{
$person_id = $this->input->get('person_id');
$studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz');
$result = $this->StundensatzModel->getStundensatzForMitarbeiter($person_id, $studiensemester_kurzbz);
return $this->terminateWithSuccess($result);
}
/**
* Get all Projektbetreuer by search string.
*/
public function getProjektbetreuerBySearchQuery()
{
$searchString = $this->input->get('searchString');
if (!isset($searchString))
$this->terminateWithError($this->p->t('ui', 'error_fieldRequired', ['field' => 'Search term']), self::ERROR_TYPE_GENERAL);
$result = $this->PersonModel->searchPerson($searchString);
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
if (!hasData($result)) $this->terminateWithSuccess([]);
$persons = $this->_addFullNameToBetreuer(getData($result));
// sort persons by type (employees first)
usort($persons, function ($a, $b) {
$statusRanks = ['Mitarbeiter' => 0, 'Person' => 1, 'Student' => 2];
return (isset($statusRanks[$a->status]) ? $statusRanks[$a->status] : count($statusRanks) + 1)
- (isset($statusRanks[$b->status]) ? $statusRanks[$b->status] : count($statusRanks) + 1);
});
return $this->terminateWithSuccess($persons);
}
/**
* Get person info by Id.
*/
public function getPerson()
{
$person_id = $this->input->get('person_id');
if (!isset($person_id))
$this->terminateWithError($this->p->t('ui', 'error_fieldRequired', ['field' => 'Person']), self::ERROR_TYPE_GENERAL);
$this->PersonModel->addSelect("CASE
WHEN EXISTS
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid) WHERE person_id=tbl_person.person_id)
THEN 'Mitarbeiter'
WHEN EXISTS
(SELECT 1 FROM public.tbl_benutzer JOIN public.tbl_student ON(uid=student_uid) WHERE person_id=tbl_person.person_id)
THEN 'Student'
ELSE 'Person'
END AS status");
$result = $this->PersonModel->addSelect('titelpre, titelpost, vorname, nachname, person_id');
$result = $this->PersonModel->load($person_id);
if (isError($result)) return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
return $this->terminateWithSuccess(hasData($result) ? $this->_addFullNameToBetreuer(getData($result))[0] : []);
}
/**
* Validate list of Projektbetreuer.
*/
public function validateProjektbetreuer()
{
$projektbetreuerArr = $this->input->post('projektbetreuer');
if (!is_array($projektbetreuerArr)) $projektbetreuerArr = [$projektbetreuerArr];
foreach ($projektbetreuerArr as $pb)
{
if ($this->_validate($pb) == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
}
$this->terminateWithSuccess([]);
}
/**
* Validation funciton for checking Projektbetreuer input.
* @param $formData Betreuer data
* @return bool true when data is valid
*/
private function _validate($formData)
{
$this->form_validation->set_data($formData);
$this->form_validation->set_rules('betreuerart_kurzbz', 'Betreuerart', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('projektarbeit', 'betreuerart')])
]);
$this->form_validation->set_rules('person_id', 'Person', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('projektarbeit', 'betreuer')])
]);
$this->form_validation->set_rules('stunden', 'Stunden', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => $this->p->t('projektarbeit', 'stunden')])
]);
$this->form_validation->set_rules('stundensatz', 'Stundensatz', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => $this->p->t('projektarbeit', 'stundensatz')])
]);
return $this->form_validation->run();
}
/**
* Check possibility of deletion of a Projektbetreuer.
* @param projektarbeit_id
* @param person_id
* @param betreuerart_kurzbz
* @return object success when delete possible, error otherwise
*/
private function _validateDelete($projektarbeit_id, $person_id, $betreuerart_kurzbz)
{
// check if contract exists
$this->ProjektbetreuerModel->addSelect('vertrag_id');
$result = $this->ProjektbetreuerModel->loadWhere(
['projektarbeit_id' => $projektarbeit_id, 'person_id' => $person_id, 'betreuerart_kurzbz' => $betreuerart_kurzbz]
);
if (isError($result)) return $result;
// if contract exists, no deletion is possible
if (hasData($result) && getData($result)[0]->vertrag_id != null) return error($this->p->t('projektarbeit', 'error_betreuerHatVertrag'));
return success();
}
/**
* Add full name to array with Betreuer.
* @param $betreuerArr
* @return array including Betreuer with their full names
*/
private function _addFullNameToBetreuer($betreuerArr)
{
foreach ($betreuerArr as $betreuer)
{
$betreuer->name = ($betreuer->titelpre ? $betreuer->titelpre . ' ' : '') .
$betreuer->nachname . ' ' . $betreuer->vorname . ($betreuer->titelpost ? ' ' . $betreuer->titelpre : '').
' (' . $betreuer->status . ')';
}
return $betreuerArr;
}
}
@@ -18,6 +18,8 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about addresses
@@ -111,7 +113,7 @@ class Pruefung extends FHCAPI_Controller
// Load language phrases
$this->loadPhrases([
'global', 'ui','lehre'
'global', 'ui', 'lehre', 'exam'
]);
}
@@ -172,174 +174,11 @@ class Pruefung extends FHCAPI_Controller
*
* @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)
* @return void
*/
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);
$this->insertOrUpdatePruefung();
}
/**
@@ -348,8 +187,6 @@ class Pruefung extends FHCAPI_Controller
* @param pruefung_id
*
* @return success or error
*
* no impact on lehre.tbl_zeugnisnote
*/
public function updatePruefung($pruefung_id)
{
@@ -359,48 +196,7 @@ class Pruefung extends FHCAPI_Controller
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);
$this->insertOrUpdatePruefung($pruefung_id);
}
/**
@@ -574,4 +370,198 @@ class Pruefung extends FHCAPI_Controller
return $this->terminateWithSuccess($data);
}
protected function insertOrUpdatePruefung($pruefung_id=null)
{
$authUID = getAuthUID();
$this->load->library('form_validation');
$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());
}
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$this->PruefungModel->db->trans_start();
if ($this->input->post('pruefungstyp_kurzbz') == "Termin2")
{
//Wenn ein 2. Termin angelegt wird, und kein 1. Termin vorhanden ist,
//dann wird auch ein 1. Termin angelegt mit der derzeitigen Zeugnisnote
$resultP = $this->PruefungModel->loadWhere(array(
'lehreinheit_id' => $this->input->post('lehreinheit_id'),
'student_uid' => $this->input->post('student_uid'),
'pruefungstyp_kurzbz' => 'Termin1'));
$termin1 = $this->getDataOrTerminateWithError($resultP);
if (!$termin1)
{
//check if existing Zeugnisnote
$this->ZeugnisnoteModel->addJoin('lehre.tbl_lehreinheit', 'lehrveranstaltung_id');
$this->ZeugnisnoteModel->db->where(
'lehre.tbl_zeugnisnote.studiensemester_kurzbz',
'lehre.tbl_lehreinheit.studiensemester_kurzbz',
false
);
$resultP = $this->ZeugnisnoteModel->loadWhere(array(
'lehrveranstaltung_id' => $this->input->post('lehrveranstaltung_id'),
'student_uid' => $this->input->post('student_uid')
));
$zeugnisnoten = $this->getDataOrTerminateWithError($resultP);
if ($zeugnisnoten)
{
$zeugnisnote = current($zeugnisnoten);
$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' => $zeugnisnote->benotungsdatum,
'pruefungstyp_kurzbz' => 'Termin1',
'note' => $zeugnisnote->note,
'punkte' => $zeugnisnote->punkte,
'anmerkung' => 'automatisiert aus Zeugnisnote erstellt',
'insertamum' => date('c'),
'insertvon' => $authUID,
]);
$this->getDataOrTerminateWithError($resultN);
}
//Wenn keine Zeugnisnote vorhanden ist, dann wird kein
//1.Termin angelegt
}
}
if(intval($pruefung_id) > 0)
{
$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'),
]
);
}
else
{
$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,
'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null
]);
}
$this->getDataOrTerminateWithError($result);
//get studiensemester_kurzbz and lehreveranstaltung_id from lehreinheit
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$result = $this->LehreinheitModel->load($this->input->post('lehreinheit_id'));
$lehreinheiten = $this->getDataOrTerminateWithError($result);
if (!$lehreinheiten) {
$this->terminateWithValidationErrors([
'lehreinheit_id' => $this->p->t('ui', 'error_fieldNotFound', [
'field' => $this->p->t('lehre', 'lehreinheit')
])
]);
}
$lehreinheit = current($lehreinheiten);
$studiensemester_kurzbz = $lehreinheit->studiensemester_kurzbz;
$lehrveranstaltung_id = $lehreinheit->lehrveranstaltung_id;
//check if existing zeugnisnote
$result = $this->ZeugnisnoteModel->loadWhere(array(
'lehrveranstaltung_id' => $lehrveranstaltung_id,
'student_uid' => $this->input->post('student_uid'),
'studiensemester_kurzbz' => $studiensemester_kurzbz
));
$zeugnisnoten = $this->getDataOrTerminateWithError($result);
if (!$zeugnisnoten)
{
//insert zeugnisnote, if not existing
$result = $this->ZeugnisnoteModel->insert(array(
'lehrveranstaltung_id' => $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,
'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null
));
$this->getDataOrTerminateWithError($result);
$this->PruefungModel->db->trans_complete();
$this->terminateWithSuccess();
}
$note = current($zeugnisnoten);
$uebernahmedatum = new DateTime($note->uebernahmedatum);
$benotungsdatum = new DateTime($note->benotungsdatum);
$pruefungsdatum = new DateTime($this->input->post('datum'));
$checkDate = $note->uebernahmedatum === '' || $benotungsdatum > $uebernahmedatum
? $benotungsdatum
: $uebernahmedatum;
if ($checkDate > $pruefungsdatum && $this->input->post('note') !== $note->note)
{
$this->PruefungModel->db->trans_complete();
$this->terminateWithSuccess($this->p->t('exam', 'hinweis_changeAfterExamDate'));
}
//update zeugnisnote, if existing and valid datum
$result = $this->ZeugnisnoteModel->update([
'lehrveranstaltung_id' => $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'),
'updateamum' => date('c'),
'updatevon' => $authUID,
'punkte' => $this->input->post('punkte') ? str_replace(',', '.', $this->input->post('punkte')) : null
]);
$this->PruefungModel->db->trans_complete();
$this->terminateWithSuccess();
}
}
@@ -114,9 +114,8 @@ class Status extends FHCAPI_Controller
$this->load->model('codex/Bismeldestichtag_model', 'BismeldestichtagModel');
$result = $this->BismeldestichtagModel->getLastReachedMeldestichtag();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
$this->terminateWithSuccess(hasData($result) ? getData($result) : array());
}
public function isLastStatus($prestudent_id)
@@ -296,7 +295,7 @@ class Status extends FHCAPI_Controller
}],
//Check if Rolle already exists
['rolle_doesnt_exist', function () use ($prestudent_id, $status_kurzbz, $studiensemester_kurzbz, $ausbildungssemester) {
if (!$status_kurzbz || !$studiensemester_kurzbz || !$ausbildungssemester)
if (!$status_kurzbz || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
return true; // Error will be handled by the required statements above
$result = $this->PrestudentstatusModel->load([$ausbildungssemester, $studiensemester_kurzbz, $status_kurzbz, $prestudent_id]);
@@ -637,7 +636,7 @@ class Status extends FHCAPI_Controller
$this->load->library('PrestudentLib');
$this->prestudentlib->setFirstStudent(
$resFirstStudent = $this->prestudentlib->setFirstStudent(
$prestudent_id,
$lastAufgenommener->studiensemester_kurzbz,
$lastAufgenommener->ausbildungssemester,
@@ -646,9 +645,8 @@ class Status extends FHCAPI_Controller
$this->input->post('statusgrund_id')
);
$this->getDataOrTerminateWithError($result);
$this->db->trans_commit();
$this->db->trans_complete();
$this->getDataOrTerminateWithError($resFirstStudent);
return $this->outputJsonSuccess(true);
}
@@ -903,7 +901,7 @@ class Status extends FHCAPI_Controller
$this->form_validation->set_rules('_default', '', [
['rolle_doesnt_exist', function () use ($prestudent_id, $status_kurzbz, $studiensemester_kurzbz, $ausbildungssemester) {
if (!$status_kurzbz || !$studiensemester_kurzbz || !$ausbildungssemester)
if (!$status_kurzbz || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
return true; // Error will be handled by the required statements above
$result = $this->PrestudentstatusModel->load([$ausbildungssemester, $studiensemester_kurzbz, $status_kurzbz, $prestudent_id]);
@@ -920,7 +918,7 @@ class Status extends FHCAPI_Controller
) {
if ($isBerechtigtNoStudstatusCheck)
return true; // Skip if access right says so
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
return true; // Error will be handled by the required statements above
$result = $this->prestudentstatuschecklib->checkStatusHistoryTimesequence(
@@ -945,7 +943,7 @@ class Status extends FHCAPI_Controller
) {
if ($isBerechtigtNoStudstatusCheck)
return true; // Skip if access right says so
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
return true; // Error will be handled by the required statements above
$result = $this->prestudentstatuschecklib->checkStatusHistoryLaststatus(
@@ -970,7 +968,7 @@ class Status extends FHCAPI_Controller
) {
if ($isBerechtigtNoStudstatusCheck)
return true; // Skip if access right says so
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
return true; // Error will be handled by the required statements above
$result = $this->prestudentstatuschecklib->checkStatusHistoryUnterbrechersemester(
@@ -995,7 +993,7 @@ class Status extends FHCAPI_Controller
) {
if ($isBerechtigtNoStudstatusCheck)
return true; // Skip if access right says so
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
return true; // Error will be handled by the required statements above
$result = $this->prestudentstatuschecklib->checkStatusHistoryAbbrechersemester(
@@ -1020,7 +1018,7 @@ class Status extends FHCAPI_Controller
) {
if ($isBerechtigtNoStudstatusCheck)
return true; // Skip if access right says so
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !$ausbildungssemester)
if (!$status_kurzbz || !$datum || !$studiensemester_kurzbz || !isset($ausbildungssemester) || $ausbildungssemester === '')
return true; // Error will be handled by the required statements above
$result = $this->prestudentstatuschecklib->checkStatusHistoryDiplomant(
@@ -1079,6 +1077,24 @@ class Status extends FHCAPI_Controller
$this->terminateWithSuccess(true);
}
protected function checkForCriticalChangesBis($oldstatus)
{
$changedFields = array();
$allowedFields = array('anmerkung', 'statusgrund_id');
$oldstatus_array = get_object_vars($oldstatus);
foreach($oldstatus_array as $key => $oldValue)
{
$newValue = $this->input->post($key);
if( $newValue !== $oldValue )
{
$changedFields[] = $key;
}
}
$criticalFieldsChanged = array_diff($changedFields, $allowedFields);
$hasCriticalChangesBis = count($criticalFieldsChanged) > 0 ? true : false;
return $hasCriticalChangesBis;
}
/**
* Updates a status entry
*
@@ -1103,6 +1119,7 @@ class Status extends FHCAPI_Controller
$oldstatus = current($oldstatus);
$hasCriticalChangesBis = $this->checkForCriticalChangesBis($oldstatus);
$isBerechtigtNoStudstatusCheck = $this->permissionlib->isBerechtigt('student/keine_studstatuspruefung');
$isBerechtigtBasisPrestudentstatus = $this->permissionlib->isBerechtigt('basis/prestudentstatus');
@@ -1113,7 +1130,6 @@ class Status extends FHCAPI_Controller
$ausbildungssemester = $this->input->post('ausbildungssemester') ?: $oldstatus->ausbildungssemester;
$datum = $this->input->post('datum') ?: $oldstatus->datum;
//Form Validation
$this->load->library('form_validation');
@@ -1136,9 +1152,15 @@ class Status extends FHCAPI_Controller
$this->p->t('global', 'datum'),
[
'is_valid_date',
['meldestichtag_not_exceeded', function ($value) use ($isBerechtigtNoStudstatusCheck) {
['meldestichtag_not_exceeded', function ($value) use ($isBerechtigtNoStudstatusCheck, $hasCriticalChangesBis){
if ($isBerechtigtNoStudstatusCheck)
return true; // Skip if access right says so
{
return true; // Skip if access right says so*/
}
if (!$hasCriticalChangesBis) {
return true; // Skip if no critical changes were made
}
if (!$value)
return true; // Error will be handled by the required statement above
@@ -1342,6 +1364,7 @@ class Status extends FHCAPI_Controller
'updateamum' => date('c'),
'updatevon' => $authUID
];
$nullableFields = ['statusgrund_id', 'anmerkung', 'rt_stufe'];
foreach ([
'orgform_kurzbz',
'anmerkung',
@@ -1350,8 +1373,17 @@ class Status extends FHCAPI_Controller
'rt_stufe',
'statusgrund_id'
] as $key)
if ($this->input->post($key))
{
if (in_array($key, $nullableFields))
{
$updateData[$key] = ($this->input->post($key) === '') ? null : $this->input->post($key);
}
else if ($this->input->post($key))
{
$updateData[$key] = $this->input->post($key);
}
}
if ($this->input->post('bestaetigtam')) {
$updateData['bestaetigtam'] = $this->input->post('bestaetigtam');
@@ -36,7 +36,8 @@ class Student extends FHCAPI_Controller
parent::__construct([
'get' => ['admin:r', 'assistenz:r'],
'save' => ['admin:rw', 'assistenz:rw'],
'check' => ['admin:rw', 'assistenz:rw'],
'saveStudent' => ['admin:rw', 'assistenz:rw'],
'getPerson' => ['admin:rw', 'assistenz:rw'],
'add' => ['admin:rw', 'assistenz:rw'] // TODO(chris): extra permissions
]);
@@ -55,7 +56,7 @@ class Student extends FHCAPI_Controller
// Load language phrases
$this->loadPhrases([
'ui', 'lehre'
'ui', 'lehre', 'person'
]);
}
@@ -107,30 +108,41 @@ class Student extends FHCAPI_Controller
$this->PrestudentModel->addSelect('p.matr_nr');
$this->PrestudentModel->addSelect('p.anrede');
$this->PrestudentModel->addSelect('p.zugangscode');
if($this->permissionlib->isBerechtigt('student/bpk'))
{
$this->PrestudentModel->addSelect('p.bpk');
}
if (defined('ACTIVE_ADDONS') && strpos(ACTIVE_ADDONS, 'bewerbung') !== false) {
$this->PrestudentModel->addSelect(
"(
SELECT kontakt
FROM public.tbl_kontakt
WHERE kontakttyp='email'
AND person_id=p.person_id
AND zustellung
ORDER BY kontakt_id
SELECT kontakt
FROM public.tbl_kontakt
WHERE kontakttyp='email'
AND person_id=p.person_id
AND zustellung
ORDER BY kontakt_id DESC
LIMIT 1
) AS email_privat",
false
);
$this->PrestudentModel->addSelect(
"(
SELECT kontakt
FROM public.tbl_kontakt
WHERE kontakttyp='email_unverifiziert'
AND person_id=p.person_id
AND zustellung
ORDER BY kontakt_id DESC
LIMIT 1
) AS email_privat_unverified",
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"
"public.get_rolle_prestudent(public.tbl_prestudent.prestudent_id, "
. $this->PrestudentModel->escape($studiensemester_kurzbz)
. ") AS statusofsemester"
);
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT');
@@ -146,9 +158,9 @@ class Student extends FHCAPI_Controller
'LEFT');*/
$result = $this->PrestudentModel->loadWhere(['tbl_prestudent.prestudent_id' => $prestudent_id]);
$student = $this->getDataOrTerminateWithError($result);
if (!$student)
return show_404();
@@ -208,7 +220,7 @@ class Student extends FHCAPI_Controller
]);
$this->load->library('UDFLib');
$result = $this->udflib->getCiValidations($this->PersonModel, $this->input->post());
$udf_field_validations = $this->getDataOrTerminateWithError($result);
@@ -219,7 +231,7 @@ class Student extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->StudentModel->loadWhere(['prestudent_id' => $prestudent_id]);
$student = $this->getDataOrTerminateWithError($result);
$uid = $student ? current($student)->student_uid : null;
@@ -232,7 +244,6 @@ class Student extends FHCAPI_Controller
$person_id = $person ? current($person)->person_id : null;
$array_allowed_props_lehrverband = ['verband', 'semester', 'gruppe'];
$update_lehrverband = array();
foreach ($array_allowed_props_lehrverband as $prop) {
@@ -292,7 +303,7 @@ class Student extends FHCAPI_Controller
}
$array_allowed_props_student = ['matrikelnr'];
if($this->isLaufendesSemester($studiensemester_kurzbz))
if($this->isLaufendesSemester($studiensemester_kurzbz))
{
$array_allowed_props_student = ['matrikelnr', 'verband', 'semester', 'gruppe'];
}
@@ -309,6 +320,10 @@ class Student extends FHCAPI_Controller
foreach ($array_allowed_props_benutzer as $prop) {
$val = $this->input->post($prop);
if ($val !== null) {
if($prop === 'alias' && $val === '')
{
$val = null;
}
$update_benutzer[$prop] = $val;
}
}
@@ -424,7 +439,32 @@ class Student extends FHCAPI_Controller
), ''));
}
public function check()
/**
* Saves data to a prestudent using their student_uid
*
* @param string $student_uid
* @param string $studiensemester_kurzbz
* @return void
*/
public function saveStudent($student_uid, $studiensemester_kurzbz)
{
$this->load->model('crm/Student_model', 'StudentModel');
$result = $this->StudentModel->load([$student_uid]);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
show_404(); // No Student with that ID
$student = current($data);
$this->checkPermissionsForPrestudent($student->prestudent_id, ['admin:rw', 'assistenz:rw']);
return $this->save($student->prestudent_id, $studiensemester_kurzbz);
}
public function getPerson()
{
$this->load->library('form_validation');
@@ -442,21 +482,55 @@ class Student extends FHCAPI_Controller
$this->load->model('person/Person_model', 'PersonModel');
$this->PersonModel->addSelect(
'person_id, vorname, nachname, vornamen, wahlname, gebdatum, staatsbuergerschaft, geburtsnation, sprache, anrede,
titelpost, titelpre, gebort, gebzeit, homepage, geschlecht, matr_nr,
aktiv, unruly, tbl_geschlecht.bezeichnung_mehrsprachig AS geschlecht_bezeichnung'
);
$this->PersonModel->addJoin('public.tbl_geschlecht', 'geschlecht');
if ($gebdatum)
$this->PersonModel->db->where('gebdatum', (new DateTime($gebdatum))->format('Y-m-d'));
if ($vorname && $nachname) {
$this->PersonModel->db->or_group_start();
$this->PersonModel->db->where('LOWER(nachname)', 'LOWER(' . $this->PersonModel->db->escape($nachname) . ')', false);
$this->PersonModel->db->where('LOWER(vorname)', 'LOWER(' . $this->PersonModel->db->escape($vorname) . ')', false);
$this->PersonModel->db->where('LOWER(nachname)', 'LOWER(' . $this->PersonModel->db->escape(trim($nachname)) . ')', false);
$this->PersonModel->db->where('LOWER(vorname)', 'LOWER(' . $this->PersonModel->db->escape(trim($vorname)) . ')', false);
$this->PersonModel->db->group_end();
} elseif ($nachname) {
$this->PersonModel->db->or_where('LOWER(nachname)', 'LOWER(' . $this->PersonModel->escape($nachname) . ')', false);
$this->PersonModel->db->or_where('LOWER(nachname)', 'LOWER(' . $this->PersonModel->escape(trim($nachname)) . ')', false);
}
$result = $this->PersonModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
foreach ($data as $person)
{
// get adresses
$langIdx = $this->_getLanguageIndex() - 1;
$person->geschlecht_bezeichnung = isset($person->geschlecht_bezeichnung[$langIdx]) ? $person->geschlecht_bezeichnung[$langIdx] : '';
// get Adresse
$this->AdresseModel->addOrder('heimatadresse', 'DESC');
$this->AdresseModel->addOrder('zustelladresse', 'DESC');
$this->AdresseModel->addOrder('adresse_id', 'DESC');
$result = $this->AdresseModel->loadWhere(['person_id' => $person->person_id]);
$adressen = $this->getDataOrTerminateWithError($result);
$person->adressen = $adressen;
// get status
$result = $this->PrestudentstatusModel->getLastStatusPerson($person->person_id);
$status = $this->getDataOrTerminateWithError($result);
$person->status = $status;
}
$this->terminateWithSuccess($data);
}
@@ -465,69 +539,58 @@ class Student extends FHCAPI_Controller
if (!$this->input->post('person_id')) {
if (!isset($_POST['address']) || !is_array($_POST['address']))
$_POST['address'] = [];
$_POST['address']['func'] = 1;
}
if ($this->input->post('incoming')) {
$_POST['ausbildungssemester'] = 0;
}
$this->load->library('form_validation');
$this->form_validation->set_rules('nachname', 'Nachname', 'callback_requiredIfNotPersonId', [
'requiredIfNotPersonId' => $this->p->t('ui', 'error_required')
]);
$this->form_validation->set_rules('geschlecht', 'Geschlecht', 'callback_requiredIfNotPersonId', [
'requiredIfNotPersonId' => $this->p->t('ui', 'error_required')
]);
$this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'callback_isValidDate', [
'isValidDate' => $this->p->t('ui', 'error_invalid_date')
]);
$this->form_validation->set_rules('address[func]', 'Address', 'required|integer|less_than[2]|greater_than[-2]');
$this->form_validation->set_rules('address[plz]', 'PLZ', 'callback_requiredIfAddressFunc', [
'requiredIfAddressFunc' => $this->p->t('ui', 'error_required')
]);
$this->form_validation->set_rules('address[gemeinde]', 'Gemeinde', 'callback_requiredIfAddressFunc', [
'requiredIfAddressFunc' => $this->p->t('ui', 'error_required')
]);
$this->form_validation->set_rules('address[ort]', 'Ort', 'callback_requiredIfAddressFunc', [
'requiredIfAddressFunc' => $this->p->t('ui', 'error_required')
]);
$this->form_validation->set_rules('address[address]', 'Adresse', 'callback_requiredIfAddressFunc', [
'requiredIfAddressFunc' => $this->p->t('ui', 'error_required')
]);
$this->form_validation->set_rules('email', 'E-Mail', 'valid_email');
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'required');
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required');
$this->form_validation->set_rules('ausbildungssemester', 'Ausbildungssemester', 'required|integer|less_than[9]|greater_than[-1]');
// TODO(chris): validate studienplan with studiengang, semester and orgform?
// TODO(chris): validate person_id, studiengang_kz, studiensemester_kurzbz, orgform_kurzbz, nation, gemeinde, ort, geschlecht?
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$this->_validate();
// TODO(chris): This should be in a library
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->load->model('organisation/Lehrverband_model', 'LehrverbandModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->db->trans_start();
$this->load->library('PrestudentLib');
$result = $this->addInteressent();
$errors = [];
$person_id = null;
$this->db->trans_complete();
$this->db->trans_begin();
if ($this->db->trans_status() === FALSE)
$this->terminateWithError('TODO(chris): TEXT', self::ERROR_TYPE_GENERAL);
$result = $this->_addPerson();
if (isError($result)) $errors[] = getError($result);
$this->terminateWithSuccess($result);
if (hasData($result))
{
$person_id = getData($result);
$result = $this->_addAdresse($person_id);
if (isError($result)) $errors[] = getError($result);
$result = $this->_addKontakt($person_id);
if (isError($result)) $errors[] = getError($result);
if (!$this->input->post('personOnly')) $result = $this->_addFirstPrestudentstatus($person_id);
if (isError($result)) $errors[] = getError($result);
}
if ($this->db->trans_status() === FALSE || !isEmptyArray($errors))
{
$this->db->trans_rollback();
$this->terminateWithError(isEmptyArray($errors) ? $this->p->t('stv', 'error_add_student') : $errors);
}
$this->db->trans_commit();
$this->terminateWithSuccess($person_id);
}
protected function addInteressent()
private function _addPerson()
{
// Person anlegen wenn nötig
$person_id = $this->input->post('person_id');
if (!$person_id) {
$this->load->model('person/Person_model', 'PersonModel');
$data = [
'nachname' => $this->input->post('nachname'),
'insertamum' => date('c'),
@@ -550,19 +613,25 @@ class Student extends FHCAPI_Controller
if ($this->input->post('geschlecht'))
$data['geschlecht'] = $this->input->post('geschlecht');
if ($this->input->post('gebdatum'))
$data['gebdatum'] = (new DateTime($this->input->post('datum_obj')))->format('Y-m-d');
$data['gebdatum'] = (new DateTime($this->input->post('gebdatum')))->format('Y-m-d');
if ($this->input->post('geburtsnation'))
$data['geburtsnation'] = $this->input->post('geburtsnation');
if ($this->input->post('staatsbuergerschaft'))
$data['staatsbuergerschaft'] = $this->input->post('staatsbuergerschaft');
$result = $this->PersonModel->insert($data);
$person_id = $this->getDataOrTerminateWithError($result);
return $this->PersonModel->insert($data);
}
// Addresse anlegen
$anlegen = $this->input->post('address[func]');
if ($anlegen) {
return success($person_id);
}
private function _addAdresse($person_id)
{
// Addresse anlegen?
$anlegen = $this->input->post('address[checked]');
if ($anlegen === true)
{
// Adresse laden
$this->load->model('person/Adresse_model', 'AdresseModel');
$data = [
@@ -574,50 +643,45 @@ class Student extends FHCAPI_Controller
'typ' => 'h',
'zustelladresse' => true,
];
if ($anlegen < 0) { // Überschreiben
$this->AdresseModel->addOrder('zustelladresse', 'DESC');
$this->AdresseModel->addOrder('sort');
$this->AdresseModel->addSelect('adresse_id');
$result = $this->AdresseModel->loadWhere([
'person_id' => $person_id
]);
$address = $this->getDataOrTerminateWithError($result);
if ($address) {
$address = current($address);
$data['updateamum'] = date('c');
$data['updatevon'] = getAuthUID();
if (isError($result)) return $result;
// wenn neue Adresse, heimatadresse setzen
if (!hasData($result)) $data['heimatadresse'] = true;
$result = $this->AdresseModel->update($address->adresse_id, $data);
$this->getDataOrTerminateWithError($result);
} else {
//Wenn keine Adrese vorhanden ist dann eine neue Anlegen
$anlegen = 1;
$data['heimatadresse'] = true;
}
}
if ($anlegen > 0) {
$data['person_id'] = $person_id;
$data['insertamum'] = date('c');
$data['insertvon'] = getAuthUID();
if (!isset($data['heimatadresse']))
$data['heimatadresse'] = !$this->input->post('person_id');
$result = $this->AdresseModel->insert($data);
$this->getDataOrTerminateWithError($result);
}
return $this->AdresseModel->insert($data);
}
return success(null);
}
private function _addKontakt($person_id)
{
// Kontaktdaten
$kontaktdaten = [];
foreach (['email', 'telefon', 'mobil'] as $k) {
foreach (['email', 'telefon', 'mobil'] as $k)
{
$v = $this->input->post($k);
if ($v)
$kontaktdaten[$k] = $v;
}
if (count($kontaktdaten)) {
if (count($kontaktdaten))
{
$this->load->model('person/Kontakt_model', 'KontaktModel');
foreach ($kontaktdaten as $typ => $kontakt) {
foreach ($kontaktdaten as $typ => $kontakt)
{
$data = [
'person_id' => $person_id,
'kontakttyp' => $typ,
@@ -627,83 +691,70 @@ class Student extends FHCAPI_Controller
'insertvon' => getAuthUID()
];
$result = $this->KontaktModel->insert($data);
$this->getDataOrTerminateWithError($result);
if (isError($result)) return $result;
}
}
return success(null);
}
private function _addFirstPrestudentstatus($person_id)
{
// Prestudent anlegen
$data = [
'aufmerksamdurch_kurzbz' => 'k.A.',
'person_id' => $person_id,
'studiengang_kz' => $this->input->post('studiengang_kz'),
'ausbildungcode' => $this->input->post('letzteausbildung'),
'anmerkung' => $this->input->post('anmerkungen'),
'reihungstestangetreten' => false,
'bismelden' => true
];
// Anmerkung with Ausbildungsart
$studiengang_kz = $this->input->post('studiengang_kz');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$ausbildungsart = $this->input->post('ausbildungsart');
$anmerkung = $this->input->post('anmerkungen');
$foerderrelevant = null;
if ($ausbildungsart)
$data['anmerkung'] .= ' Ausbildungsart:' . $ausbildungsart;
$anmerkung .= ' Ausbildungsart:' . $ausbildungsart;
// Incomings und ausserordentliche sind bei Meldung nicht förderrelevant
$incoming = $this->input->post('incoming');
if ($incoming || substr($data['studiengang_kz'], 0, 1) == '9')
$data['foerderrelevant'] = false;
// Wenn die Person schon im System erfasst ist, dann die ZGV des Datensatzes uebernehmen
$this->PrestudentModel->addOrder('zgvmas_code');
$this->PrestudentModel->addOrder('zgv_code', 'DESC');
$this->PrestudentModel->addLimit(1);
$result = $this->PrestudentModel->loadWhere([
'person_id' => $person_id
]);
$prestudent = $this->getDataOrTerminateWithError($result);
if ($prestudent) {
$prestudent = current($prestudent);
if ($prestudent->zgv_code) {
$data['zgv_code'] = $prestudent->zgv_code;
$data['zgvort'] = $prestudent->zgvort;
$data['zgvdatum'] = $prestudent->zgvdatum;
if ($incoming || substr($studiengang_kz, 0, 1) == '9')
$foerderrelevant = false;
$data['zgvmas_code'] = $prestudent->zgvmas_code;
$data['zgvmaort'] = $prestudent->zgvmaort;
$data['zgvmadatum'] = $prestudent->zgvmadatum;
}
}
// Prestudent speichern
$result = $this->PrestudentModel->insert($data);
$prestudent_id = $this->getDataOrTerminateWithError($result);
$result = $this->prestudentlib->setPrestudent(
$person_id,
$studiengang_kz,
$this->input->post('letzteausbildung'),
$anmerkung,
$foerderrelevant
);
if (isError($result)) return $result;
if (!hasData($result)) return error('Error when adding prestudent');
// Prestudent Rolle Anlegen
$data = [
'prestudent_id' => $prestudent_id,
'status_kurzbz' => $incoming ? 'Incoming' : 'Interessent',
'studiensemester_kurzbz' => $this->input->post('studiensemester_kurzbz'),
'ausbildungssemester' => $this->input->post('ausbildungssemester') ?: 0,
'orgform_kurzbz' => $this->input->post('orgform_kurzbz') ?: null,
'studienplan_id' => $this->input->post('studienplan_id') ?: null,
'datum' => date('Y-m-d'),
'insertamum' => date('c'),
'insertvon' => getAuthUID()
];
$result = $this->PrestudentstatusModel->insert($data);
$this->getDataOrTerminateWithError($result);
$prestudent_id = getData($result);
if ($incoming) {
// TODO(chris): IMPLEMENT!
//Matrikelnummer und UID generieren
//Benutzerdatensatz anlegen
//Studentendatensatz anlegen
//StudentLehrverband anlegen
// wenn Incoming, Incoming Daten hinzufügen
if ($incoming)
{
$statusResult = $this->prestudentlib->setFirstIncoming(
$prestudent_id,
$studiengang_kz,
$studiensemester_kurzbz,
$this->input->post('orgform_kurzbz'),
$this->input->post('studienplan_id')
);
}
else
{
// Prestudent Rolle Anlegen
$statusResult = $this->prestudentlib->setFirstStatus(
$prestudent_id,
$this->PrestudentstatusModel::STATUS_INTERESSENT,
$studiensemester_kurzbz,
$this->input->post('ausbildungssemester'),
$this->input->post('orgform_kurzbz'),
$this->input->post('studienplan_id')
);
}
if (!hasData($statusResult)) return error('error when adding status');
if (isError($statusResult)) return $statusResult;
// TODO(chris): DEBUG
/*$result = $this->PrestudentModel->loadWhere([
'pestudent_id' => 1
]);
if (isError($result)) {
return $result;
}*/
return success(true);
return success($prestudent_id);
}
public function requiredIfNotPersonId($value)
@@ -715,13 +766,84 @@ class Student extends FHCAPI_Controller
public function requiredIfAddressFunc($value)
{
if (!$_POST['address']['func'])
if (!isset($_POST['address']['checked']) || !$_POST['address']['checked'])
return true;
return !!$value;
}
public function isValidDate($value)
public function requiredIfStudentFunc($value)
{
return isValidDate($value);
if (isset($_POST['personOnly']) && $_POST['personOnly'])
return true;
return !!$value;
}
public function requiredIfStudentAndNotIncomingFunc($value)
{
if ((isset($_POST['incoming']) && $_POST['incoming']) || $this->requiredIfStudentFunc($value))
return true;
return !!$value;
}
/**
* Validates input data. Terminates with validation errors, if invalid.
*/
private function _validate()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('nachname', 'Nachname', 'callback_requiredIfNotPersonId', [
'requiredIfNotPersonId' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'nachname')])
]);
$this->form_validation->set_rules('geschlecht', 'Geschlecht', 'callback_requiredIfNotPersonId', [
'requiredIfNotPersonId' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'geschlecht')])
]);
$this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'is_valid_date', [
'is_valid_date' => $this->p->t('ui', 'error_invalid_date')
]);
//$this->form_validation->set_rules('address[checked]', 'Address', 'required');
$this->form_validation->set_rules('address[plz]', 'PLZ', 'callback_requiredIfAddressFunc', [
'requiredIfAddressFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'plz')])
]);
$this->form_validation->set_rules('address[gemeinde]', 'Gemeinde', 'callback_requiredIfAddressFunc', [
'requiredIfAddressFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'gemeinde')])
]);
$this->form_validation->set_rules('address[ort]', 'Ort', 'callback_requiredIfAddressFunc', [
'requiredIfAddressFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'ort')])
]);
$this->form_validation->set_rules('address[address]', 'Adresse', 'callback_requiredIfAddressFunc', [
'requiredIfAddressFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('person', 'adresse')])
]);
$this->form_validation->set_rules('email', 'E-Mail', 'valid_email');
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'callback_requiredIfStudentFunc', [
'requiredIfStudentFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'studiengang')])
]);
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'callback_requiredIfStudentFunc', [
'requiredIfStudentFunc' => $this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'studiensemester')])
]);
$this->form_validation->set_rules(
'ausbildungssemester',
'Ausbildungssemester',
'callback_requiredIfStudentAndNotIncomingFunc|integer|less_than[9]|greater_than[-1]',
[
'requiredIfStudentAndNotIncomingFunc' =>
$this->p->t('ui', 'error_fieldRequired', ['field' => $this->p->t('lehre', 'ausbildungssemester')]),
]
);
// TODO(chris): validate studienplan with studiengang, semester and orgform?
// TODO(chris): validate person_id, studiengang_kz, studiensemester_kurzbz, orgform_kurzbz, nation, gemeinde, ort, geschlecht?
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
private function _getLanguageIndex()
{
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->SpracheModel->addSelect('index');
$result = $this->SpracheModel->loadWhere(array('sprache' => getUserLanguage()));
$this->addMeta('lang', getUserLanguage());
return hasData($result) ? getData($result)[0]->index : 1;
}
}
@@ -44,14 +44,12 @@ class Students extends FHCAPI_Controller
}
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('PhrasesLib');
$this->loadPhrases(
array(
'lehre'
)
);
}
/**
@@ -75,7 +73,7 @@ class Students extends FHCAPI_Controller
* /(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)/(semester)/grp/(gruppe) => getStudentsSpezialgruppe
*
* /(studiensemester_kurzbz)/(studiengang_kz) => getStudents
* /(studiensemester_kurzbz)/(studiengang_kz)/(semester) => getStudents
@@ -101,39 +99,183 @@ class Students extends FHCAPI_Controller
}
/**
* @param string $studiensemester_kurzbz
*
* @return void
*/
public function getIncoming()
public function getIncoming($studiensemester_kurzbz)
{
$this->addMeta('ci_method', __FUNCTION__);
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
$this->addMeta('ci_params', [
'studiensemester_kurzbz' => $studiensemester_kurzbz
]);
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addJoin(
"(
SELECT prestudent_id
FROM public.tbl_prestudentstatus
WHERE status_kurzbz = 'Incoming'
AND studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
) test",
"prestudent_id"
);
$this->prepareQuery($studiensemester_kurzbz);
$this->PrestudentModel->addSelect("COALESCE(
v.semester::text,
CASE
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
THEN pls.ausbildungssemester::text
ELSE ''::text
END
) AS semester", false);
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* @param string $studiensemester_kurzbz
*
* @return void
*/
public function getOutgoing()
public function getOutgoing($studiensemester_kurzbz)
{
$this->addMeta('ci_method', __FUNCTION__);
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
$this->addMeta('ci_params', [
'studiensemester_kurzbz' => $studiensemester_kurzbz
]);
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addJoin(
"(
SELECT prestudent_id
FROM bis.tbl_bisio bis
JOIN public.tbl_student USING (student_uid)
JOIN public.tbl_studiensemester stdsem ON (
(bis.von >= stdsem.start AND bis.von <= stdsem.ende)
OR
(bis.bis >= stdsem.start AND bis.bis <= stdsem.ende)
OR
(bis.von <= stdsem.start AND bis.bis >= stdsem.ende)
)
WHERE NOT EXISTS (
SELECT 1
FROM public.tbl_prestudentstatus
WHERE status_kurzbz = 'Incoming'
AND prestudent_id = tbl_student.prestudent_id
) AND stdsem.studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
GROUP BY prestudent_id
) test",
"prestudent_id"
);
$this->prepareQuery($studiensemester_kurzbz);
$this->PrestudentModel->addSelect("COALESCE(
v.semester::text,
CASE
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
THEN pls.ausbildungssemester::text
ELSE ''::text
END
) AS semester", false);
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* @param string $studiensemester_kurzbz
*
* @return void
*/
public function getGemeinsamestudien()
public function getGemeinsamestudien($studiensemester_kurzbz)
{
$this->addMeta('ci_method', __FUNCTION__);
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
$this->addMeta('ci_params', [
'studiensemester_kurzbz' => $studiensemester_kurzbz
]);
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addJoin(
"(
SELECT prestudent_id
FROM bis.tbl_mobilitaet
WHERE studiensemester_kurzbz = " . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
) bis",
"prestudent_id"
);
$this->prepareQuery($studiensemester_kurzbz);
$this->PrestudentModel->addSelect("COALESCE(
v.semester::text,
CASE
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
THEN pls.ausbildungssemester::text
ELSE ''::text
END
) AS semester", false);
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getPrestudents($studiengang_kz,
$studiensemester_kurzbz = null, $filter = null
)
{
public function getPrestudents(
$studiengang_kz,
$studiensemester_kurzbz = null,
$filter = null
) {
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiengang_kz' => $studiengang_kz,
@@ -144,10 +286,12 @@ class Students extends FHCAPI_Controller
$this->fetchPrestudents($studiengang_kz, $studiensemester_kurzbz, $filter);
}
public function getPrestudentsOrgform($studiengang_kz, $orgform_kurzbz,
$studiensemester_kurzbz = null, $filter = null
)
{
public function getPrestudentsOrgform(
$studiengang_kz,
$orgform_kurzbz,
$studiensemester_kurzbz = null,
$filter = null
) {
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiengang_kz' => $studiengang_kz,
@@ -227,7 +371,7 @@ class Students extends FHCAPI_Controller
$stg = $this->getDataOrTerminateWithError($result);
if (!$stg)
$this->terminateWithValidationErrors(['' => 'Studiengang does not exist']); // TODO(chris): phrase
$this->terminateWithSuccess([]);
$stg = current($stg);
$where['ps.status_kurzbz'] = 'Interessent';
@@ -296,7 +440,10 @@ class Students extends FHCAPI_Controller
break;
default:
if (!$studiensemester_kurzbz) {
// TODO(chris): this does not work with $orgform_kurzbz != null
/** NOTE(chris):
* show all prestudents in this stg who don't have a status
* $orgform_kurzbz does not change the results since orgform is stored in the status table
*/
$where['ps.status_kurzbz'] = null;
} else {
$this->PrestudentModel->db->where_in('ps.status_kurzbz', [
@@ -310,42 +457,18 @@ class Students extends FHCAPI_Controller
break;
}
/*
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus pls', '
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
AND pls.prestudent_id=tbl_prestudent.prestudent_id
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
$this->PrestudentModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus ps', '
ps.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
AND ps.prestudent_id=tbl_prestudent.prestudent_id
AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')', 'LEFT');*/
$this->prepareQuery($studiensemester_kurzbz);
$this->PrestudentModel->addSelect("
CASE WHEN ps.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
THEN ps.ausbildungssemester::text
ELSE ''::text END AS semester", false);
CASE
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
THEN ps.ausbildungssemester::text
ELSE ''::text
END AS semester", false);
$this->PrestudentModel->addSelect("'' AS verband");
$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);
@@ -355,10 +478,13 @@ class Students extends FHCAPI_Controller
$this->terminateWithSuccess($data);
}
public function getStudents($studiensemester_kurzbz,
$studiengang_kz, $semester = null, $verband = null, $gruppe = null
)
{
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,
@@ -371,10 +497,14 @@ class Students extends FHCAPI_Controller
$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
)
{
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,
@@ -388,10 +518,12 @@ class Students extends FHCAPI_Controller
$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)
{
public function getStudentsSpezialgruppe(
$studiensemester_kurzbz,
$studiengang_kz,
$semester,
$gruppe_kurzbz
) {
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz,
@@ -403,10 +535,13 @@ class Students extends FHCAPI_Controller
$this->fetchStudents($studiensemester_kurzbz, $studiengang_kz, $semester, null, null, $gruppe_kurzbz, null);
}
public function getStudentsOrgformSpezialgruppe($studiensemester_kurzbz,
$orgform_kurzbz, $studiengang_kz, $semester, $gruppe_kurzbz
)
{
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,
@@ -430,8 +565,15 @@ class Students extends FHCAPI_Controller
*
* @return void
*/
protected function fetchStudents($studiensemester_kurzbz, $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
) {
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
@@ -440,21 +582,6 @@ class Students extends FHCAPI_Controller
$this->terminateWithError($studiensemester_kurzbz . ' - ' . $this->p->t('lehre', 'error_noStudiensemester'));
}
/*
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id');
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus pls', '
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
AND pls.prestudent_id=tbl_prestudent.prestudent_id
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
$this->PrestudentModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
$this->PrestudentModel->addJoin(
'public.tbl_studentlehrverband v',
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz=' . $this->PrestudentModel->escape($studiensemester_kurzbz)
);*/
$this->prepareQuery($studiensemester_kurzbz, '');
$this->PrestudentModel->addSelect('v.semester');
@@ -462,18 +589,6 @@ 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 = [];
@@ -496,7 +611,7 @@ class Students extends FHCAPI_Controller
if (!$verband && !$gruppe && $orgform_kurzbz !== null) {
$this->PrestudentModel->db->where(
"(
SELECT orgform_kurzbz
SELECT orgform_kurzbz
FROM public.tbl_prestudentstatus
WHERE prestudent_id=tbl_prestudent.prestudent_id
AND studiensemester_kurzbz=" . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
@@ -506,13 +621,12 @@ class Students extends FHCAPI_Controller
false
);
}
}
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->loadWhere($where);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
@@ -540,39 +654,18 @@ class Students extends FHCAPI_Controller
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
/*
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus pls', '
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
AND pls.prestudent_id=tbl_prestudent.prestudent_id
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
$this->PrestudentModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid', 'LEFT');
$this->PrestudentModel->addJoin(
'public.tbl_studentlehrverband v',
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz=' . $this->PrestudentModel->escape($studiensemester_kurzbz),
'LEFT'
);*/
$this->prepareQuery($studiensemester_kurzbz);
$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->PrestudentModel->addSelect("COALESCE(
v.semester::text,
CASE
WHEN pls.status_kurzbz IN ('Aufgenommener', 'Bewerber', 'Wartender', 'interessent')
THEN pls.ausbildungssemester::text
ELSE ''::text
END
) AS semester", false);
$this->PrestudentModel->addSelect("COALESCE(v.verband::text, ''::text)");
$this->PrestudentModel->addSelect("COALESCE(v.gruppe::text, ''::text)");
$this->addSelectPrioRel();
@@ -609,40 +702,12 @@ class Students extends FHCAPI_Controller
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
/*
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id');
$this->PrestudentModel->addJoin('public.tbl_prestudentstatus pls', '
pls.status_kurzbz=public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL)
AND pls.prestudent_id=tbl_prestudent.prestudent_id
AND pls.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, NULL)
AND pls.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, NULL)', 'LEFT');
$this->PrestudentModel->addJoin('lehre.tbl_studienplan sp', 'studienplan_id', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
$this->PrestudentModel->addJoin(
'public.tbl_studentlehrverband v',
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz=' . $this->PrestudentModel->escape($studiensemester_kurzbz),
'LEFT'
);*/
$this->prepareQuery($studiensemester_kurzbz);
$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();
@@ -681,33 +746,12 @@ class Students extends FHCAPI_Controller
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
/*
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id');
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
$this->PrestudentModel->addJoin(
'public.tbl_studentlehrverband v',
'v.student_uid=s.student_uid AND v.studiensemester_kurzbz=' . $this->PrestudentModel->escape($studiensemester_kurzbz),
'LEFT'
);*/
$this->prepareQuery($studiensemester_kurzbz);
$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);
@@ -721,6 +765,81 @@ class Students extends FHCAPI_Controller
$this->terminateWithSuccess($data);
}
/**
* @param string $studiensemester_kurzbz
*
* @return void
*/
public function search($studiensemester_kurzbz)
{
$this->addMeta('ci_method', __FUNCTION__);
$this->addMeta('ci_params', array(
'studiensemester_kurzbz' => $studiensemester_kurzbz
));
$this->load->library('SearchLib', [ 'config' => 'searchstv' ]);
$this->load->library('form_validation');
$this->form_validation->set_rules('searchstr', 'searchstr', 'required');
$this->form_validation->set_rules('types[]', 'types', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->searchlib->search($this->input->post('searchstr'), $this->input->post('types'));
$data = $this->getDataOrTerminateWithError($result);
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->prepareQuery($studiensemester_kurzbz);
$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(
"public.get_rolle_prestudent(public.tbl_prestudent.prestudent_id, "
. $this->PrestudentModel->escape($studiensemester_kurzbz)
. ") AS statusofsemester"
);
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
$prestudent_ids = [];
$student_uids = [];
$this->addMeta('data', $data);
foreach ($data as $row) {
$dataset = json_decode($row->data);
if ($row->type == 'prestudent') {
$prestudent_ids[] = $dataset->prestudent_id;
} elseif ($row->type == 'student') {
$student_uids[] = $dataset->uid;
}
}
if ($prestudent_ids && $student_uids) {
$this->PrestudentModel->db->where_in('tbl_prestudent.prestudent_id', $prestudent_ids);
$this->PrestudentModel->db->or_where_in('s.student_uid', $student_uids);
} elseif ($prestudent_ids) {
$this->PrestudentModel->db->where_in('tbl_prestudent.prestudent_id', $prestudent_ids);
} elseif ($student_uids) {
$this->PrestudentModel->db->where_in('s.student_uid', $student_uids);
} else {
$this->terminateWithSuccess([]);
}
$result = $this->PrestudentModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* @param string|null $studiensemester_kurzbz
* @param string $type
@@ -731,6 +850,45 @@ class Students extends FHCAPI_Controller
{
$stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
$this->load->config('stv');
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
{
$tags = $this->config->item('stv_prestudent_tags');
$whereTags = '';
if (is_array($tags) && !isEmptyArray($tags)) {
$tags = array_keys($tags);
foreach ($tags as $key => $tag) {
$tags[$key] = $this->db->escape($tag);
}
$whereTags = " AND nt.typ_kurzbz IN (" . implode(",", $tags) . ")";
}
$subQueryTag = "
(
SELECT
tag.prestudent_id,
COALESCE(json_agg(tag ORDER BY tag.done), '[]'::json) AS tags
FROM (
SELECT DISTINCT ON (n.notiz_id)
n.notiz_id AS id,
nt.typ_kurzbz,
array_to_json(nt.bezeichnung_mehrsprachig)->>0 AS beschreibung,
n.text AS notiz,
nt.style,
n.erledigt AS done,
nz.prestudent_id
FROM public.tbl_notizzuordnung AS nz
JOIN public.tbl_notiz AS n ON nz.notiz_id = n.notiz_id
JOIN public.tbl_notiz_typ AS nt ON n.typ = nt.typ_kurzbz "
. $whereTags .
"
) AS tag
GROUP BY tag.prestudent_id
) AS tag_data_agg
";
}
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
@@ -753,8 +911,17 @@ class Students extends FHCAPI_Controller
AND ps.studiensemester_kurzbz=public.get_stdsem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')
AND ps.ausbildungssemester=public.get_absem_prestudent(tbl_prestudent.prestudent_id, ' . $stdsemEsc . ')', 'LEFT');
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
{
$this->PrestudentModel->addJoin($subQueryTag, 'tag_data_agg.prestudent_id = tbl_prestudent.prestudent_id', 'LEFT');
}
$this->PrestudentModel->addSelect("b.uid");
if(defined('STV_TAGS_ENABLED') && STV_TAGS_ENABLED)
{
$this->PrestudentModel->addSelect('tag_data_agg.tags');
}
$this->PrestudentModel->addSelect('titelpre');
$this->PrestudentModel->addSelect('nachname');
$this->PrestudentModel->addSelect('vorname');
@@ -771,6 +938,13 @@ class Students extends FHCAPI_Controller
// verband
// gruppe
//add status per semester
$this->PrestudentModel->addSelect(
"public.get_rolle_prestudent(public.tbl_prestudent.prestudent_id, "
. $this->PrestudentModel->escape($studiensemester_kurzbz)
. ") AS statusofsemester"
);
$this->PrestudentModel->addSelect('UPPER(stg.typ || stg.kurzbz) AS studiengang');
$this->PrestudentModel->addSelect('tbl_prestudent.studiengang_kz');
$this->PrestudentModel->addSelect('stg.bezeichnung AS stg_bezeichnung');
@@ -805,13 +979,7 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect('mentor');
$this->PrestudentModel->addSelect('b.aktiv AS bnaktiv');
/*$this->PrestudentModel->addSelect('tbl_prestudent.reihungstest_id');
$this->PrestudentModel->addSelect('tbl_prestudent.anmeldungreihungstest');
$this->PrestudentModel->addSelect('tbl_prestudent.gsstudientyp_kurzbz');
$this->PrestudentModel->addSelect('tbl_prestudent.priorisierung');
$this->PrestudentModel->addSelect('p.zugangscode');
$this->PrestudentModel->addSelect('p.bpk');*/
$this->PrestudentModel->addSelect('unruly');
$this->PrestudentModel->db->where_in('tbl_prestudent.studiengang_kz', $this->allowedStgs);
@@ -827,13 +995,13 @@ class Students extends FHCAPI_Controller
$this->PrestudentModel->addSelect("(
SELECT count(*)
FROM (
SELECT *, public.get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) AS laststatus
FROM PUBLIC.tbl_prestudent pss
JOIN PUBLIC.tbl_prestudentstatus USING (prestudent_id)
SELECT *, public.get_rolle_prestudent(pss.prestudent_id, NULL) AS laststatus
FROM public.tbl_prestudent pss
JOIN public.tbl_prestudentstatus USING (prestudent_id)
WHERE person_id = p.person_id
AND studiensemester_kurzbz = (
SELECT studiensemester_kurzbz
FROM PUBLIC.tbl_prestudentstatus
FROM public.tbl_prestudentstatus
WHERE prestudent_id = tbl_prestudent.prestudent_id
AND status_kurzbz = 'Interessent'
LIMIT 1
@@ -842,7 +1010,7 @@ class Students extends FHCAPI_Controller
) prest
WHERE laststatus NOT IN ('Abbrecher', 'Abgewiesener', 'Absolvent')
AND priorisierung <= tbl_prestudent.priorisierung
) || ' (' || tbl_prestudent.priorisierung || ')' AS priorisierung_relativ", false);
) || ' (' || COALESCE(tbl_prestudent.priorisierung::text, ' '::text) || ')' AS priorisierung_relativ", false);
}
/**
@@ -854,40 +1022,20 @@ class Students extends FHCAPI_Controller
*/
protected function addFilter($studiensemester_kurzbz)
{
$filter = json_decode($this->input->get('filter'), true);
$filter = $this->input->post('filter');
if (!is_array($filter))
{
$this->addMeta('addfilter', 'invalid filter: ' . $this->input->get('filter'));
$this->addMeta('addfilter', 'invalid filter: ' . json_encode($this->input->post('filter')));
return;
}
if (isset($filter['konto_count_0'])) {
$bt = $this->PrestudentModel->escape($filter['konto_count_0']);
$stdsem = $this->PrestudentModel->escape($studiensemester_kurzbz);
$this->PrestudentModel->db->where('(
SELECT count(*)
FROM public.tbl_konto
WHERE person_id=tbl_prestudent.person_id
AND buchungstyp_kurzbz=' . $bt . '
AND studiensemester_kurzbz=' . $stdsem . '
) =', 0);
$this->PrestudentModel->db->where('get_rolle_prestudent(tbl_prestudent.prestudent_id, NULL) !=', 'Incoming');
}
if (isset($filter['konto_missing_counter'])) {
$bt = $this->PrestudentModel->escape($filter['konto_missing_counter']);
$stg = '';
if ($this->variablelib->getVar('kontofilterstg') == 'true')
$stg = ' AND studiengang_kz=tbl_prestudent.studiengang_kz';
$bt = $bt == 'alle' ? '' : ' AND buchungstyp_kurzbz=' . $bt;
$this->PrestudentModel->db->where('(
SELECT sum(betrag)
FROM public.tbl_konto
WHERE person_id=tbl_prestudent.person_id' .
$bt .
$stg . '
) !=', 0);
foreach ($filter as $item) {
if (isset($item['usestdsem']) && $item['usestdsem'])
$item['studiensemester_kurzbz'] = $studiensemester_kurzbz;
if (!$this->PrestudentModel->addFilter($item)) {
$this->addMeta('addfilter', 'invalid filter: ' . json_encode($item));
return;
}
}
}
}
@@ -0,0 +1,48 @@
<?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
]);
$this->config->load('stv');
}
public function getTag($readonly_tags = null)
{
parent::getTag($this->config->item('stv_prestudent_tags'));
}
public function getTags($tags = null)
{
parent::getTags($this->config->item('stv_prestudent_tags'));
}
public function addTag($withZuordnung = true, $updatable_tags = null)
{
parent::addTag(true, $this->config->item('stv_prestudent_tags'));
}
public function updateTag($updatable_tags = null)
{
parent::updateTag($this->config->item('stv_prestudent_tags'));
}
public function deleteTag($withZuordnung = true, $updatable_tags = null)
{
parent::deleteTag(true, $this->config->item('stv_prestudent_tags'));
}
public function doneTag($updatable_tags = null)
{
parent::doneTag($this->config->item('stv_prestudent_tags'));
}
}
@@ -165,7 +165,17 @@ class Verband extends FHCAPI_Controller
$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("CONCAT(
UPPER(CONCAT(typ, kurzbz)),
'-',
semester,
(
SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END
FROM public.tbl_lehrverband
WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester
ORDER BY verband, gruppe LIMIT 1
)
) AS name", false);
$this->StudiengangModel->addSelect('semester');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
@@ -173,6 +183,7 @@ class Verband extends FHCAPI_Controller
$this->StudiengangModel->addOrder('semester');
if ($org_form !== null) {
$this->StudiengangModel->addSelect("v.orgform_kurzbz");
$this->StudiengangModel->db->group_start();
$this->StudiengangModel->db->where('v.semester', 0);
$this->StudiengangModel->db->or_where('v.orgform_kurzbz', $org_form);
@@ -188,6 +199,7 @@ class Verband extends FHCAPI_Controller
array_unshift($list, [
'name' => 'PreStudent',
'link' => $link . 'prestudent',
'no_sem_reload' => true,
'stg_kz' => (int)$studiengang_kz,
'children' => $this->getStdSem($link . 'prestudent/', $studiengang_kz)
]);
@@ -203,6 +215,7 @@ class Verband extends FHCAPI_Controller
$this->StudienordnungModel->addDistinct();
$this->StudienordnungModel->addSelect("CONCAT(studiengang_kz, '/', p.orgform_kurzbz) AS link");
$this->StudienordnungModel->addSelect("p.orgform_kurzbz AS name");
$this->StudienordnungModel->addSelect("studiengang_kz AS stg_kz");
$this->StudienordnungModel->addJoin('lehre.tbl_studienplan p', 'studienordnung_id');
@@ -216,7 +229,6 @@ class Verband extends FHCAPI_Controller
$list = array_merge($list, $result);
}
}
}
$this->terminateWithSuccess($list);
}
@@ -272,6 +284,7 @@ class Verband extends FHCAPI_Controller
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband ORDER BY gruppe LIMIT 1)) AS name", false);
$this->StudiengangModel->addSelect("CASE WHEN MAX(gruppe)='' OR MAX(gruppe)=' ' THEN TRUE ELSE FALSE END AS leaf");
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($semester) . ' AS semester');
$this->StudiengangModel->addSelect('verband');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
@@ -320,6 +333,8 @@ class Verband extends FHCAPI_Controller
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, gruppe, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband AND gruppe=v.gruppe ORDER BY gruppe LIMIT 1)) AS name", false);
$this->StudiengangModel->addSelect("TRUE AS leaf", false);
$this->StudiengangModel->addSelect('v.semester');
$this->StudiengangModel->addSelect('v.verband');
$this->StudiengangModel->addSelect('gruppe');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
@@ -0,0 +1,102 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Vertrag extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getVertrag' => ['admin:r', 'assistenz:r'],
'cancelVertrag' => ['admin:r', 'assistenz:r']
]);
// Load Libraries
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'person',
'projektarbeit'
]);
// Load models
$this->load->model('accounting/Vertrag_model', 'VertragModel');
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
// load libraries
$this->load->library('PermissionLib');
}
public function getVertrag()
{
$vertrag_id = $this->input->get('vertrag_id');
if (!isset($vertrag_id) || !is_numeric($vertrag_id))
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Vertrag ID']), self::ERROR_TYPE_GENERAL);
$result = $this->VertragModel->getVertragById($vertrag_id);
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
if (!hasData($result)) $this->terminateWithSuccess([]);
$vertrag = getData($result)[0];
$this->terminateWithSuccess($vertrag);
}
public function cancelVertrag()
{
$vertrag_id = $this->input->post('vertrag_id');
$person_id = $this->input->post('person_id');
if (!isset($vertrag_id) || !is_numeric($vertrag_id))
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Vertrag ID']), self::ERROR_TYPE_GENERAL);
if (!isset($person_id) || !is_numeric($person_id))
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Person ID']), self::ERROR_TYPE_GENERAL);
// * first find lehrveranstaltung_id of the contracts lehrveranstaltung
$this->VertragModel->addSelect('lehrveranstaltung_id');
$this->VertragModel->addJoin('lehre.tbl_lehrveranstaltung', 'lehrveranstaltung_id', 'LEFT');
$result = $this->VertragModel->loadWhere(['vertrag_id' => $vertrag_id]);
if (isError($result)) $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
if (!hasData($result)) $this->terminateWithSuccess([]);
$lehrveranstaltung_id = getData($result)[0]->lehrveranstaltung_id;
$allOe = $this->LehrveranstaltungModel->getAllOe($lehrveranstaltung_id);
if (isError($allOe)) $this->terminateWithError(getError($allOe), self::ERROR_TYPE_GENERAL);
$allOe = hasData($allOe) ? array_column(getData($allOe), 'oe_kurzbz') : [];
// * then check if the user has permissions to cancel the corresponding lv-organisational units
if (!$this->permissionlib->isBerechtigtMultipleOe('admin', $allOe, 'suid') &&
!$this->permissionlib->isBerechtigtMultipleOe('lehre/lehrauftrag_bestellen', $allOe, 'suid'))
{
return $this->_outputAuthError([$this->router->method => ['admin:rw', 'lehrauftrag_bestellen:rw']]);
}
$uidResult = $this->BenutzerModel->getFromPersonId($person_id);
if (isError($uidResult)) $this->terminateWithError(getError($uidResult), self::ERROR_TYPE_GENERAL);
if (!hasData($uidResult)) $this->terminateWithError("no user found", self::ERROR_TYPE_GENERAL);
$mitarbeiter_uid = getData($uidResult)[0]->uid;
$result = $this->VertragModel->cancelVertrag($vertrag_id, $mitarbeiter_uid);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,62 @@
<?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 the VV Config
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Config extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'printDocument' => ['vertrag/mitarbeiter:r'],
]);
}
public function printDocument()
{
$params = [];
$menu = [];
Events::trigger(
'multiActionPrintHonorarvertrag',
// passing $menu per reference
function & () use (&$menu) {
return $menu;
},
$params
);
if (is_array($menu) && isset($menu[0]))
{
$this->terminateWithSuccess($menu[0]);
}
else
{
// $this->terminateWithError('Error with Event 'multiActionPrintHonorarvertrag');
$this->terminateWithSuccess();
}
}
}
@@ -26,9 +26,6 @@ class Vertraege extends FHCAPI_Controller
'deleteLehrauftrag' =>['vertrag/mitarbeiter:w'],
'deleteBetreuung' =>['vertrag/mitarbeiter:w'],
'getMitarbeiter' => ['vertrag/mitarbeiter:r'],
'getHeader' => ['vertrag/mitarbeiter:r'],
'getPersonAbteilung' => ['vertrag/mitarbeiter:r'],
'getLeitungOrg' => ['vertrag/mitarbeiter:r'],
]);
//Load Models and Libraries
@@ -241,7 +238,7 @@ class Vertraege extends FHCAPI_Controller
}
}
$this->db->trans_complete();
$this->terminateWithSuccess(true);
$this->terminateWithSuccess($vertrag_id);
}
public function updateContract()
@@ -358,7 +355,7 @@ class Vertraege extends FHCAPI_Controller
}
$this->db->trans_complete();
$this->terminateWithSuccess(true);
$this->terminateWithSuccess($vertrag_id);
}
public function loadContract($vertrag_id)
@@ -684,37 +681,4 @@ class Vertraege extends FHCAPI_Controller
}
return $this->terminateWithSuccess(getData($result));
}
public function getPersonAbteilung($mitarbeiter_uid)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getPersonAbteilung($mitarbeiter_uid);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function getLeitungOrg($oekurzbz)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getLeitungOrg($oekurzbz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
public function getHeader($person_id)
{
$this->load->model('ressource/Mitarbeiter_model', 'Mitarbeitermodel');
$result = $this->Mitarbeitermodel->getHeader($person_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($data));
}
}
@@ -51,13 +51,17 @@ class Vorlagen extends FHCAPI_Controller
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerfunktionByUid($uid, 'oezuordnung');
$data = $this->getDataOrTerminateWithError($result);
$oe_kurzbz = current($data);
if (hasData($result))
{
$data = getData($result);
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz->oe_kurzbz);
$data = $this->getDataOrTerminateWithError($result);
$oe_kurzbz = array_column($data, 'oe_kurzbz');
$result = $this->VorlageModel->getAllVorlagenByOe($oe_kurzbz);
$this->terminateWithSuccess(hasData($result) ? getData($result) : array());
}
$this->terminateWithSuccess(array());
$this->terminateWithSuccess($data);
}
}
@@ -233,10 +233,10 @@ class Person extends API_Controller
//Quersumme bilden
for ($i = 0; $i < 10; $i++)
{
$erg += $gewichtung[$i] * $tmpSvnr{$i};
$erg += $gewichtung[$i] * $tmpSvnr[$i];
}
if ($tmpSvnr{3} != ($erg % 11)) //Vergleichen der Pruefziffer mit Quersumme Modulo 11
if ($tmpSvnr[3] != ($erg % 11)) //Vergleichen der Pruefziffer mit Quersumme Modulo 11
{
return error('SVNR ist ungueltig');
}
@@ -244,7 +244,7 @@ class Person extends API_Controller
if (mb_strlen($person['svnr']) == 12)
{
$last = substr($person['svnr'], 10, 12);
if ($last{0} != 'v' || !is_numeric($last{1}))
if ($last[0] != 'v' || !is_numeric($last[1]))
{
return error('SVNR ist ungueltig');
}
@@ -0,0 +1,52 @@
<?php
/**
* Copyright (C) 2026 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*/
class Admin extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'dashboard/admin:rw',
'preview' => 'dashboard/admin:r',
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function index()
{
$this->load->view('dashboard/admin.php', []);
}
public function preview($dashboard_kurzbz = 'CIS')
{
$this->load->view('dashboard/preview.php', [
'dashboard_kurzbz' => $dashboard_kurzbz
]);
}
}
-76
View File
@@ -1,76 +0,0 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
class Api extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/admin:rw',
'getNews' => 'dashboard/benutzer:r',
'getAmpeln' => 'dashboard/benutzer:r',
)
);
$this->load->library('AuthLib', null, 'AuthLib');
$this->_setAuthUID();
}
public function index()
{
echo 'Dashboard API Controller';
}
/**
* Get News.
*/
public function getNews()
{
$limit = $this->input->get('limit');
$this->load->model('content/News_model', 'NewsModel');
$result = $this->NewsModel->getAll($limit);
if (hasData($result))
{
$this->outputJson(getData($result), REST_Controller::HTTP_OK);
}
else
{
$this->terminateWithJsonError('fehler entdeckt');
}
}
/**
* Get Ampeln.
*/
public function getAmpeln()
{
$this->load->model('content/Ampel_model', 'AmpelModel');
$result = $this->AmpelModel->getByUser($this->_uid);
if (hasData($result))
{
$this->outputJson(getData($result), REST_Controller::HTTP_OK);
}
else
{
$this->terminateWithJsonError('fehler entdeckt');
}
}
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid) show_error('User authentification failed');
}
}
@@ -1,216 +0,0 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
/**
* Description of Config
*
* @author bambi
*/
class Config extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/benutzer:r',
'dummy' => 'dashboard/benutzer:r',
'genWidgetId' => 'dashboard/benutzer:rw',
'addWidgetsToPreset' => 'dashboard/admin:rw',
'removeWidgetFromPreset' => 'dashboard/admin:rw',
'addWidgetsToUserOverride' => 'dashboard/benutzer:rw',
'removeWidgetFromUserOverride' => 'dashboard/benutzer:rw',
'funktionen' => 'dashboard/admin:r',
'preset' => 'dashboard/admin:r',
'presetBatch' => 'dashboard/admin:r'
)
);
$this->load->library('dashboard/DashboardLib', null, 'DashboardLib');
$this->load->library('AuthLib', null, 'AuthLib');
$this->load->model('ressource/Funktion_model', 'FunktionModel');
}
public function index()
{
$dashboard_kurzbz = $this->input->get('db');
$uid = $this->AuthLib->getAuthObj()->username;
$dashboard = $this->DashboardLib->getDashboardByKurzbz($dashboard_kurzbz);
if(!$dashboard) {
http_response_code(404);
$this->terminateWithJsonError(array(
'error' => 'Dashboard ' . $dashboard_kurzbz . ' not found.'
));
}
$mergedconfig = $this->DashboardLib->getMergedConfig($dashboard->dashboard_id, $uid);
$this->outputJsonSuccess($mergedconfig);
}
public function genWidgetId()
{
$dashboard_kurzbz = $this->input->get('db');
$widgetid = $this->DashboardLib->generateWidgetId($dashboard_kurzbz);
$this->outputJsonSuccess(array(
'widgetid' => $widgetid
));
}
public function addWidgetsToPreset()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$preset = $this->DashboardLib->getPresetOrCreateEmptyPreset($dashboard_kurzbz, $funktion_kurzbz);
$preset_decoded = json_decode($preset->preset, true);
$this->DashboardLib->addWidgetsToWidgets($preset_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$preset->preset = json_encode($preset_decoded);
$result = $this->DashboardLib->insertOrUpdatePreset($preset);
if (isError($result)) {
http_response_code(500);
$this->terminateWithJsonError('preset could not be saved');
}
$this->outputJsonSuccess(array('msg' => 'preset successfully stored.', 'data' => $preset_decoded));
}
public function removeWidgetFromPreset()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$widgetid = $input->widgetid;
$preset = $this->DashboardLib->getPreset($dashboard_kurzbz, $funktion_kurzbz);
if ($preset === null) {
http_response_code(404);
$this->terminateWithJsonError('preset for dashboard ' . $dashboard_kurzbz . ' and funktion ' . $funktion_kurzbz . ' not found.');
}
$preset_decoded = json_decode($preset->preset, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($preset_decoded, $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
}
$preset->preset = json_encode($preset_decoded);
$result = $this->DashboardLib->insertOrUpdatePreset($preset);
if (isError($result))
{
http_response_code(500);
$this->terminateWithJsonError('failed to remove widget');
}
$this->outputJsonSuccess(array('msg' => 'preset successfully updated.'));
}
public function addWidgetsToUserOverride()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$uid = $this->AuthLib->getAuthObj()->username;
$override = $this->DashboardLib->getOverrideOrCreateEmptyOverride($dashboard_kurzbz, $uid);
$override_decoded = json_decode($override->override, true);
$this->DashboardLib->addWidgetsToWidgets($override_decoded, $dashboard_kurzbz, $funktion_kurzbz, $input->widgets);
$override->override = json_encode($override_decoded);
$result = $this->DashboardLib->insertOrUpdateOverride($override);
if (isError($result)) {
http_response_code(500);
$this->terminateWithJsonError('override could not be saved');
}
$this->outputJsonSuccess(array('msg' => 'override successfully stored.', 'data' => $override_decoded));
}
public function removeWidgetFromUserOverride()
{
$input = json_decode($this->input->raw_input_stream);
$dashboard_kurzbz = $input->db;
$funktion_kurzbz = $input->funktion_kurzbz;
$uid = $this->AuthLib->getAuthObj()->username;
$widgetid = $input->widgetid;
$override = $this->DashboardLib->getOverride($dashboard_kurzbz, $uid);
if (empty($override)) {
http_response_code(404);
$this->terminateWithJsonError('userconfig for dashboard ' . $dashboard_kurzbz . ' not found.');
}
$override_decoded = json_decode($override->override, true);
if (!$this->DashboardLib->removeWidgetFromWidgets($override_decoded, $funktion_kurzbz, $widgetid))
{
http_response_code(404);
$this->terminateWithJsonError('widgetid ' . $widgetid . ' not found');
}
$override->override = json_encode($override_decoded);
$result = $this->DashboardLib->insertOrUpdateOverride($override, $uid);
if (isError($result))
{
http_response_code(500);
$this->terminateWithJsonError('failed to remove widget');
}
$this->outputJsonSuccess(array('msg' => 'override successfully updated.'));
}
public function funktionen()
{
$funktionen = $this->FunktionModel->load();
if (isError($funktionen)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($funktionen)
]);
}
return $this->outputJsonSuccess(getData($funktionen) ?: []);
}
public function preset()
{
$db = $this->input->get('db');
$funktion = $this->input->get('funktion');
$conf = $this->DashboardLib->getPreset($db, $funktion);
if (!$conf)
return $this->outputJsonSuccess(['widgets' => [$funktion => []]]);
return $this->outputJsonSuccess(json_decode($conf->preset, true));
}
public function presetBatch()
{
$db = $this->input->get('db');
$funktionen = $this->input->get('funktionen');
$result = [];
foreach ($funktionen as $funktion) {
$conf = $this->DashboardLib->getPreset($db, $funktion);
if ($conf)
{
$preset = json_decode($conf->preset, true);
if (!isset($preset[$funktion]) || !isset($preset[$funktion]['widgets']))
$result[$funktion] = [];
else
$result[$funktion] = $preset[$funktion]['widgets'];
}
else
$result[$funktion] = [];
}
return $this->outputJsonSuccess($result);
}
}
@@ -1,86 +0,0 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
/**
* Description of Widget
*
* @author chris
*/
class Dashboard extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/admin:r',
'create' => 'dashboard/admin:rw',
'update' => 'dashboard/admin:rw',
'delete' => 'dashboard/admin:rw'
)
);
$this->load->library('dashboard/DashboardLib', null, 'DashboardLib');
$this->load->model('dashboard/Dashboard_model', 'DashboardModel');
}
public function index()
{
$result = $this->DashboardModel->load();
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
public function create()
{
$input = $this->getPostJSON();
$result = $this->DashboardModel->insert($input);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
public function update()
{
$input = $this->getPostJSON();
$result = $this->DashboardModel->update($input->dashboard_id, $input);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
public function delete()
{
$input = $this->getPostJSON();
$result = $this->DashboardModel->delete($input->dashboard_id);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result) ?: []);
}
}
@@ -1,58 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*/
class DashboardDemo extends Auth_Controller
{
private $_uid; // uid of the logged user
/**
* Constructor
*/
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'dashboard/benutzer:r',
'admin' => 'dashboard/admin:rw'
)
);
$this->load->library('AuthLib');
$this->load->library('WidgetLib');
$this->_setAuthUID(); // sets property uid
$this->setControllerId(); // sets the controller id
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function index()
{
$this->load->view('dashboard/dashboard_demo.php', []);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function admin()
{
$this->load->view('dashboard/dashboard_demo_admin.php', []);
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
if (!$this->_uid) show_error('User authentification failed');
}
}
@@ -1,109 +0,0 @@
<?php
defined('BASEPATH') || exit('No direct script access allowed');
/**
* Description of Widget
*
* @author chris
*/
class Widget extends Auth_Controller
{
public function __construct()
{
parent::__construct(
array(
'index' => ['dashboard/benutzer:r', 'dashboard/admin:r'],
'getAll' => 'dashboard/admin:r',
'getWidgetsForDashboard' => ['dashboard/benutzer:rw', 'dashboard/admin:r'],
'setAllowed' => 'dashboard/admin:rw'
)
);
$this->load->library('dashboard/DashboardLib', null, 'DashboardLib');
$this->load->model('dashboard/Widget_model', 'WidgetModel');
$this->load->model('dashboard/Dashboard_Widget_model', 'DashboardWidgetModel');
}
public function index()
{
$widget_id = $this->input->get('id');
$widget = $this->WidgetModel->load($widget_id);
if (isError($widget) || !getData($widget))
return $this->outputJsonSuccess([
"widget_id" => 0,
"widget_kurzbz" => "notfound",
"arguments" => json_encode([
"className" => 'alert-danger',
"title" => 'Widget Not Found',
"msg" => 'The widget with the id ' . $widget_id . ' could not be found'
]),
"setup" => json_encode([
"name" => 'Widget Not Found',
"file" => 'DashboardWidget/Default.js',
"width" => 1,
"height" => 1
])
]);
return $this->outputJsonSuccess(current(getData($widget)));
}
public function getAll()
{
$dashboard_id = $this->input->get('dashboard_id');
$result = $this->WidgetModel->getWithAllowedForDashboard($dashboard_id);
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result) ?: []);
}
public function getWidgetsForDashboard()
{
$db = $this->input->get('db');
$result = $this->WidgetModel->getForDashboard($db);
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
$this->outputJsonSuccess(getData($result) ?: []);
}
public function setAllowed()
{
$input = $this->getPostJSON();
$dashboard_id = $input->dashboard_id;
$widget_id = $input->widget_id;
$action = $input->action;
if ($action == 'add') {
$result = $this->DashboardWidgetModel->insert([
'dashboard_id' => $dashboard_id,
'widget_id' => $widget_id
]);
} elseif ($action == 'delete') {
$result = $this->DashboardWidgetModel->delete([
'dashboard_id' => $dashboard_id,
'widget_id' => $widget_id
]);
} else {
http_response_code(404); // TODO(chris): 400?
$this->terminateWithJsonError([
'error' => 'action value invalid'
]);
}
if (isError($result)) {
http_response_code(404);
$this->terminateWithJsonError([
'error' => getError($result)
]);
}
return $this->outputJsonSuccess(getData($result));
}
}
@@ -0,0 +1,913 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class AbgabetoolJob extends JOB_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
$this->_ci =& get_instance();
$this->_ci->load->helper('hlp_sancho_helper');
$this->_ci->load->model('education/Projektarbeit_model', 'ProjektarbeitModel');
$this->_ci->load->model('education/Projektbetreuer_model', 'ProjektbetreuerModel');
$this->_ci->load->model('education/Paabgabe_model', 'PaabgabeModel');
$this->_ci->load->model('crm/Student_model', 'StudentModel');
$this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->_ci->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$this->_ci->load->library('SignatureLib');
$this->_ci->load->config('abgabe');
$this->loadPhrases([
'abgabetool'
]);
}
// basically the notifyBetreuerMail function but email goes to assistenz
// and new abgaben are further evaluated for missing signature status
public function notifyAssistenzAboutMissingSignatureUploads() {
$this->_ci->logInfo('Start job FHC-Core->notifyAssistenzAboutMissingSignatureUploads');
$interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL');
$relevantTypes = $this->_ci->config->item('RELEVANT_PAABGABETYPEN_SAMMELMAIL_ASSISTENZ');
$result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSinceByAbgabedatum($interval, $relevantTypes);
$retval = getData($result);
// retval are paabgaben joined with projektarbeit and betreuer
if(count($retval) == 0) {
$this->logInfo("Keine Emails über neue Paabgaben an Assistenzen versandt");
return;
}
// group changed/new abgaben for projektarbeiten
$projektarbeiten = [];
foreach($retval as $abgabeWithNewUpload) {
// Check if the current item has a 'projektarbeit_id' field.
// Replace 'projektarbeit_id' with the actual key name if it's different.
if (isset($abgabeWithNewUpload->projektarbeit_id)) {
$projektarbeitId = $abgabeWithNewUpload->projektarbeit_id;
// If the 'projektarbeit_id' is not yet a key in $projektarbeiten,
// initialize it as an empty array.
if (!isset($projektarbeiten[$projektarbeitId])) {
$projektarbeiten[$projektarbeitId] = [];
}
// check signature for that abgabe, main point of this job
$this->checkAbgabeSignatur($abgabeWithNewUpload, $abgabeWithNewUpload->student_uid);
// Add the current row to the array associated with its 'projektarbeit_id'.
$projektarbeiten[$projektarbeitId][] = $abgabeWithNewUpload;
}
}
// for each projektarbeit fetch their assistenz and same them in their own dictionary to avoid too many mails
$assistenzMap = [];
// for each projektarbeit fetch their betreuer and save them in their own dictionary to avoid too many mails
$projektarbeitBetreuerMap = [];
forEach($projektarbeiten as $projektarbeit_id => $abgaben) {
$assistenzResult = $this->_ci->OrganisationseinheitModel->getAssistenzForOE($abgaben[0]->stg_oe_kurzbz);
forEach($assistenzResult->retval as $assistenzRow) {
if (!isset($assistenzMap[$assistenzRow->person_id])) {
$assistenzMap[$assistenzRow->person_id] = [];
}
// Add the current $assistenzRow to the $assistenzMap as an array associated with its projektarbeit_id.
$assistenzMap[$assistenzRow->person_id][] = [$projektarbeit_id, $assistenzRow];
}
$betreuerResult = $this->_ci->ProjektbetreuerModel->getAllBetreuerOfProjektarbeit($projektarbeit_id);
forEach($betreuerResult->retval as $betreuerRow) {
if (!isset($projektarbeitBetreuerMap[$projektarbeit_id])) {
$projektarbeitBetreuerMap[$projektarbeit_id] = [];
}
// Add the current betreuerRow to the betreuerMap as an array associated with its projektarbeit_id.
$projektarbeitBetreuerMap[$projektarbeit_id][] = $betreuerRow;
}
}
$count = 0;
foreach($assistenzMap as $assistenz_person_id => $tupelArr) {
$abgabenString = '<div style="font-family: Arial, sans-serif; color: #333;">';
$hasIssues = false; // Track if this assistant actually needs an email
foreach($tupelArr as $tupel) {
$projektarbeit_id = $tupel[0];
$assistenzRow = $tupel[1];
$betreuerArray = $projektarbeitBetreuerMap[$projektarbeit_id] ?? [];
$allAbgaben = $projektarbeiten[$projektarbeit_id];
// only keep abgaben that are not correctly signed
$issueAbgaben = array_filter($allAbgaben, function($abgabe) {
// We only care about cases where it's explicitly NOT true (false, error, or null)
return $abgabe->signatur !== true;
});
// if this specific project has no signature issues, skip to the next project
if(empty($issueAbgaben)) {
continue;
}
// If we reached here, we have at least one issue to report
$hasIssues = true;
// Format the Student Name (using the first available abgabe object)
$s = reset($issueAbgaben);
$nameParts = array_filter([$s->titelpre, $s->vorname, $s->nachname, $s->titelpost]);
$studentFullName = implode(' ', $nameParts);
// Format the Supervisors string
$betreuerStrings = [];
foreach($betreuerArray as $b) {
$bNameParts = array_filter([$b->titelpre, $b->vorname, $b->nachname, $b->titelpost]);
$bFullName = implode(' ', $bNameParts);
$betreuerStrings[] = "{$bFullName} ({$b->betreuerart_kurzbz})";
}
$allBetreuerFormatted = implode(', ', $betreuerStrings);
$projektarbeit_titel = $s->titel ?? 'Kein Titel vergeben';
// Project Header Section
$abgabenString .= "
<div style='margin-top: 25px; padding: 12px; background-color: #fff5f5; border-left: 4px solid #dc3545; border-bottom: 1px solid #fee;'>
<strong style='font-size: 16px; color: #b02a37;'>Projekt: {$projektarbeit_titel}</strong><br/>
<div style='margin-top: 5px; font-size: 14px;'>
<strong>Studierende/r:</strong> {$studentFullName}
</div>
<div style='margin-top: 3px; font-size: 14px;'>
<strong>Betreuer:</strong> {$allBetreuerFormatted}
</div>
<span style='color: #666; font-size: 12px;'>
ID: {$projektarbeit_id} | Stg: {$s->stgtyp}{$s->stgkz} ({$s->studiensemester_kurzbz})
</span>
</div>";
// Start Table
$abgabenString .= '
<table style="width: 100%; border-collapse: collapse; margin-bottom: 25px;">
<thead>
<tr style="background-color: #f8f9fa; text-align: left;">
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 20%;">Datum</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 45%;">Abgabe/Bezeichnung</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 35%;">Status</th>
</tr>
</thead>
<tbody>';
$printed = []; // lazy hack to avoid duplicate rows
foreach ($issueAbgaben as $abgabe) {
// if we had this paabgabe already (erstbetreuer/zweitbetreuer fetch achieves duplicates
if(in_array($abgabe->paabgabe_id, $printed)) {
continue; // skip this forEach iteration
}
$printed[] = $abgabe->paabgabe_id;
$abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y');
// label and color
if ($abgabe->signatur === false) {
$sigLabel = "FEHLENDE SIGNATUR";
$sigBg = "#dc3545";
} elseif ($abgabe->signatur === 'error') {
$sigLabel = "PRÜFUNG FEHLGESCHLAGEN";
$sigBg = "#fd7e14";
} else {
$sigLabel = "DATEI NICHT GEFUNDEN";
$sigBg = "#6c757d";
}
$abgabenString .= "
<tr>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$abgabedatumFormatted}</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px;'>
<strong>{$abgabe->bezeichnung}</strong>
</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; text-align: center;'>
<span style='color: #fff; background-color: {$sigBg}; padding: 3px 8px; border-radius: 3px; font-weight: bold; font-size: 11px;'>
{$sigLabel}
</span>
</td>
</tr>";
}
$abgabenString .= '</tbody></table>';
}
$abgabenString .= '</div>';
// only send the email if at least one project had an issue
if ($hasIssues) {
$assistenzRow = $tupelArr[0][1];
$anrede = $assistenzRow->anrede;
$anredeFillString = $assistenzRow->anrede == "Herr" ? "r" : "";
$fullFormattedNameString = $assistenzRow->first;
$path = $this->_ci->config->item('URL_ASSISTENZ');
$url = CIS_ROOT . $path;
$body_fields = array(
'anrede' => $anrede,
'anredeFillString' => $anredeFillString,
'fullFormattedNameString' => $fullFormattedNameString,
'abgabenString' => $abgabenString,
'linkAbgabetool' => $url
);
$email = $assistenzRow->uid . "@" . DOMAIN;
sendSanchoMail(
'PAANoSigAssSM',
$body_fields,
$email,
$this->p->t('abgabetool', 'c4missingSignatureNotification')
);
$count++;
}
}
$this->_ci->logInfo($count . " Emails bezüglich fehlender Signaturen erfolgreich versandt");
$this->_ci->logInfo('End job FHC-Core->notifyAssistenzAboutMissingSignatureUploads');
}
/**
* helper function to check the signature status of uploaded files for zwischenabgabe & endupload
*/
private function checkAbgabeSignatur($abgabe, $student_uid) {
$paabgabetypenToCheck = $this->config->item('SIGNATUR_CHECK_PAABGABETYPEN');
if(!in_array($abgabe->paabgabetyp_kurzbz, $paabgabetypenToCheck)) {
return;
}
if (!defined('SIGNATUR_URL')) {
$abgabe->signatur = 'error';
return;
}
$path = PAABGABE_PATH.$abgabe->paabgabe_id.'_'.$student_uid.'.pdf';
$signaturVorhanden = null; // if frontend receives null -> indicates no file found at path
if(file_exists($path)) {
// Check if the document is signed
$signList = SignatureLib::list($path);
if (is_array($signList) && count($signList) > 0)
{
// The document is signed
$signaturVorhanden = true;
}
elseif ($signList === null)
{
// frontend knows to handle it this way for signatures
$signaturVorhanden = 'error';
}
else
{
$signaturVorhanden = false;
}
$abgabe->signatur = $signaturVorhanden;
}
}
public function notifyAssistenzAboutChangedAbgaben() {
$this->_ci->logInfo('Start job FHC-Core->notifyAssistenzAboutChangedAbgaben');
$interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL');
$relevantTypes = $this->_ci->config->item('RELEVANT_PAABGABETYPEN_SAMMELMAIL_ASSISTENZ');
// get all new or changed termine in interval
$result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSince($interval, $relevantTypes);
$retval = getData($result);
if(count($retval) == 0) {
$this->_ci->logInfo("Keine Emails an Assistenzen über neue oder veränderte Termine versandt");
return;
}
// group changed/new abgaben for projektarbeiten
$projektarbeiten = [];
foreach($retval as $newOrChangedAbgabe) {
// Check if the current item has a 'projektarbeit_id' field.
// Replace 'projektarbeit_id' with the actual key name if it's different.
if (isset($newOrChangedAbgabe->projektarbeit_id)) {
$projektarbeitId = $newOrChangedAbgabe->projektarbeit_id;
// If the 'projektarbeit_id' is not yet a key in $projektarbeiten,
// initialize it as an empty array.
if (!isset($projektarbeiten[$projektarbeitId])) {
$projektarbeiten[$projektarbeitId] = [];
}
// Add the current row to the array associated with its 'projektarbeit_id'.
$projektarbeiten[$projektarbeitId][] = $newOrChangedAbgabe;
}
}
// for each projektarbeit fetch their assistenz and same them in their own dictionary to avoid too many mails
$assistenzMap = [];
// for each projektarbeit fetch their betreuer and save them in their own dictionary to avoid too many mails
$projektarbeitBetreuerMap = [];
forEach($projektarbeiten as $projektarbeit_id => $abgaben) {
$assistenzResult = $this->_ci->OrganisationseinheitModel->getAssistenzForOE($abgaben[0]->stg_oe_kurzbz);
forEach($assistenzResult->retval as $assistenzRow) {
if (!isset($assistenzMap[$assistenzRow->person_id])) {
$assistenzMap[$assistenzRow->person_id] = [];
}
// Add the current $assistenzRow to the $assistenzMap as an array associated with its projektarbeit_id.
$assistenzMap[$assistenzRow->person_id][] = [$projektarbeit_id, $assistenzRow];
}
$betreuerResult = $this->_ci->ProjektbetreuerModel->getAllBetreuerOfProjektarbeit($projektarbeit_id);
forEach($betreuerResult->retval as $betreuerRow) {
if (!isset($projektarbeitBetreuerMap[$projektarbeit_id])) {
$projektarbeitBetreuerMap[$projektarbeit_id] = [];
}
// Add the current betreuerRow to the betreuerMap as an array associated with its projektarbeit_id.
$projektarbeitBetreuerMap[$projektarbeit_id][] = $betreuerRow;
}
}
$count = 0;
foreach($assistenzMap as $assistenz_person_id => $tupelArr) {
$abgabenString = '<div style="font-family: Arial, sans-serif; color: #333;">';
foreach($tupelArr as $tupel) {
$projektarbeit_id = $tupel[0];
$assistenzRow = $tupel[1];
$betreuerArray = $projektarbeitBetreuerMap[$projektarbeit_id] ?? [];
$changedAbgaben = $projektarbeiten[$projektarbeit_id];
$relevantAbgaben = array_values(array_filter($changedAbgaben, function($abgabetermin) use ($assistenzRow) {
if($abgabetermin->updatevon == null && $abgabetermin->insertvon != $assistenzRow->uid) {
return $abgabetermin;
} else if($abgabetermin->updatevon != null && $abgabetermin->updatevon != $assistenzRow->uid) {
return $abgabetermin;
}
}));
if(count($relevantAbgaben) == 0) {
continue;
}
// Format the Student Name
$s = $relevantAbgaben[0];
$nameParts = [];
if (!empty($s->titelpre)) $nameParts[] = $s->titelpre;
$nameParts[] = $s->vorname;
$nameParts[] = $s->nachname;
if (!empty($s->titelpost)) $nameParts[] = $s->titelpost;
$studentFullName = implode(' ', $nameParts);
// Format the Supervisors string
$betreuerStrings = [];
foreach($betreuerArray as $b) {
$bNameParts = [];
if (!empty($b->titelpre)) $bNameParts[] = $b->titelpre;
$bNameParts[] = $b->vorname;
$bNameParts[] = $b->nachname;
if (!empty($b->titelpost)) $bNameParts[] = $b->titelpost;
$bFullName = implode(' ', $bNameParts);
$betreuerStrings[] = "{$bFullName} ({$b->betreuerart_kurzbz})";
}
$allBetreuerFormatted = implode(', ', $betreuerStrings);
$projektarbeit_titel = $s->titel ?? 'Kein Titel vergeben';
// Project Header Section
$abgabenString .= "
<div style='margin-top: 25px; padding: 12px; background-color: #f8f9fa; border-left: 4px solid #007bff; border-bottom: 1px solid #eee;'>
<strong style='font-size: 16px; color: #0056b3;'>Projekt: {$projektarbeit_titel}</strong><br/>
<div style='margin-top: 5px; font-size: 14px;'>
<strong>Studierende/r:</strong> {$studentFullName}
</div>
<div style='margin-top: 3px; font-size: 14px;'>
<strong>Betreuer:</strong> {$allBetreuerFormatted}
</div>
<span style='color: #666; font-size: 12px;'>
ID: {$projektarbeit_id} | Stg: {$s->stgtyp}{$s->stgkz} ({$s->studiensemester_kurzbz})
</span>
</div>";
// Start Table
$abgabenString .= '
<table style="width: 100%; border-collapse: collapse; margin-bottom: 25px;">
<thead>
<tr style="background-color: #eee; text-align: left;">
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 20%;">Zieldatum</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px;">Bezeichnung</th>
</tr>
</thead>
<tbody>';
foreach ($relevantAbgaben as $abgabe) {
$dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y');
$abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y');
$kurzbzLine = !empty($abgabe->kurzbz) ? "<br/><small style='color: #777; font-style: italic;'>{$abgabe->kurzbz}</small>" : "";
$abgabenString .= "
<tr>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$dateEmailFormatted}</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px;'>
<strong>{$abgabe->bezeichnung}</strong>{$kurzbzLine}
</td>
</tr>";
}
$abgabenString .= '</tbody></table>';
}
$abgabenString .= '</div>';
// done with building the change list, now send it
$assistenzRow = $tupelArr[0][1];
$anrede = $assistenzRow->anrede;
$anredeFillString = $assistenzRow->anrede == "Herr" ? "r" : "";
$fullFormattedNameString = $assistenzRow->first;
$path = $this->_ci->config->item('URL_ASSISTENZ');
$url = CIS_ROOT.$path;
$body_fields = array(
'anrede' => $anrede,
'anredeFillString' => $anredeFillString,
'fullFormattedNameString' => $fullFormattedNameString,
'abgabenString' => $abgabenString,
'linkAbgabetool' => $url
);
$email = $assistenzRow->uid."@".DOMAIN;
// send email with bundled info
sendSanchoMail(
'PAAChangesAssSM',
$body_fields,
$email,
$this->p->t('abgabetool', 'changedAbgabeterminev2')
);
$count++;
}
$this->_ci->logInfo($count . " Emails erfolgreich versandt");
$this->_ci->logInfo('End job FHC-Core->notifyAssistenzAboutChangedAbgaben');
}
public function notifyBetreuerAboutChangedAbgaben() {
$this->_ci->logInfo('Start job FHC-Core->notifyBetreuerAboutChangedAbgaben');
$interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL');
$relevantTypes = $this->_ci->config->item('RELEVANT_PAABGABETYPEN_SAMMELMAIL_BETREUER');
// get all new or changed termine in interval
$result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSince($interval, $relevantTypes);
$retval = getData($result);
if(!$retval) {
$this->_ci->logInfo("Keine Emails an Betreuer über neue oder veränderte Termine versandt");
return;
}
// group changed/new abgaben for projektarbeiten
$projektarbeiten = [];
foreach($retval as $newOrChangedAbgabe) {
// Check if the current item has a 'projektarbeit_id' field.
// Replace 'projektarbeit_id' with the actual key name if it's different.
if (isset($newOrChangedAbgabe->projektarbeit_id)) {
$projektarbeitId = $newOrChangedAbgabe->projektarbeit_id;
// check if the updatevon field is NOT the same as the student the projektarbeit is assigned to
// since uploading a file to a paabgabe is also putting updateamum & updatevon
// we have our own "student has uploaded a file" emailjob anyways
if($newOrChangedAbgabe->student_uid === $newOrChangedAbgabe->updatevon) {
continue;
}
// If the 'projektarbeit_id' is not yet a key in $projektarbeiten,
// initialize it as an empty array.
if (!isset($projektarbeiten[$projektarbeitId])) {
$projektarbeiten[$projektarbeitId] = [];
}
// Add the current row to the array associated with its 'projektarbeit_id'.
$projektarbeiten[$projektarbeitId][] = $newOrChangedAbgabe;
}
}
if(count($projektarbeiten) == 0) {
$this->_ci->logInfo("Keine Emails an Betreuer über neue oder veränderte Termine versandt");
return;
}
// for each projektarbeit fetch their betreuer and save them in their own dictionary to avoid too many mails
$betreuerMap = [];
forEach($projektarbeiten as $projektarbeit_id => $abgaben) {
$betreuerResult = $this->_ci->ProjektbetreuerModel->getAllBetreuerOfProjektarbeit($projektarbeit_id);
forEach($betreuerResult->retval as $betreuerRow) {
if (!isset($betreuerMap[$betreuerRow->person_id])) {
$betreuerMap[$betreuerRow->person_id] = [];
}
// Add the current betreuerRow to the betreuerMap as an array associated with its projektarbeit_id.
$betreuerMap[$betreuerRow->person_id][] = [$projektarbeit_id, $betreuerRow];
}
}
$count = 0;
// now iterate over the betreuerMap and build 1 email about all projektarbeiten and their new/changed termine
// $tupel = [$projektarbeit_id, $betreuerRow], each betreuer has 0..n [projektarbeit_id, changedAbgaben] tupel
forEach($betreuerMap as $betreuer_person_id => $tupelArr) {
// start the container
$abgabenString = '<div style="font-family: Arial, sans-serif; color: #333;">';
$result = $this->_ci->ProjektarbeitModel->getProjektbetreuerAnrede($betreuer_person_id);
$data = getData($result)[0];
$anrede = $data->anrede;
$anredeFillString = $data->anrede == "Herr" ? "r" : "";
$fullFormattedNameString = $data->first;
$relevantCounter = 0; // workaround to check if a betreuer needs to have any notification about relevant
// abgaben at all to avoid sending empty emails since we filter on certain conditions
forEach($tupelArr as $tupel) {
$projektarbeit_id = $tupel[0];
$betreuerRow = $tupel[1];
$changedAbgaben = $projektarbeiten[$projektarbeit_id];
$relevantAbgaben = array_values(array_filter($changedAbgaben, function($abgabetermin) use ($betreuerRow) {
if($abgabetermin->updatevon == null && $abgabetermin->insertvon != $betreuerRow->uid) {
return $abgabetermin;
} else if($abgabetermin->updatevon != null && $abgabetermin->updatevon != $betreuerRow->uid) {
return $abgabetermin;
}
}));
if(count($relevantAbgaben) == 0) {
continue;
}
$relevantCounter++;
// format the Student Name
$s = $relevantAbgaben[0];
$nameParts = [];
if (!empty($s->titelpre)) $nameParts[] = $s->titelpre;
$nameParts[] = $s->vorname;
$nameParts[] = $s->nachname;
if (!empty($s->titelpost)) $nameParts[] = $s->titelpost;
$studentFullName = implode(' ', $nameParts);
$projektarbeit_titel = $s->titel ?? 'Kein Titel vergeben';
// project header section
$abgabenString .= "
<div style='margin-top: 25px; padding: 12px; background-color: #f8f9fa; border-left: 4px solid #007bff; border-bottom: 1px solid #eee;'>
<strong style='font-size: 16px; color: #0056b3;'>Projekt: {$projektarbeit_titel}</strong><br/>
<div style='margin-top: 5px; font-size: 14px;'>
<strong>Studierende/r:</strong> {$studentFullName}
</div>
<span style='color: #666; font-size: 12px;'>
ID: {$projektarbeit_id} | Rolle: {$betreuerRow->betreuerart_kurzbz} |
Stg: {$s->stgtyp}{$s->stgkz} ({$s->studiensemester_kurzbz})
</span>
</div>";
// start table
$abgabenString .= '
<table style="width: 100%; border-collapse: collapse; margin-bottom: 25px;">
<thead>
<tr style="background-color: #eee; text-align: left;">
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 20%;">Zieldatum</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px;">Bezeichnung</th>
</tr>
</thead>
<tbody>';
foreach ($relevantAbgaben as $abgabe) {
$dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y');
$abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y');
$kurzbzLine = !empty($abgabe->kurzbz) ? "<br/><small style='color: #777; font-style: italic;'>{$abgabe->kurzbz}</small>" : "";
$abgabenString .= "
<tr>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$dateEmailFormatted}</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px;'>
<strong>{$abgabe->bezeichnung}</strong>{$kurzbzLine}
</td>
</tr>";
}
$abgabenString .= '</tbody></table>';
}
// close container
$abgabenString .= '</div>';
// done with building the change list, now send it
$betreuerRow = $tupelArr[0][1];
if($relevantCounter == 0) {
$this->_ci->logInfo('No Relevant Abgaben to notify Betreuer PersonID: "'.$betreuerRow->person_id.'".');
continue;
}
$path = $this->_ci->config->item('URL_MITARBEITER');
$url = CIS_ROOT.$path;
$body_fields = array(
'anrede' => $anrede,
'anredeFillString' => $anredeFillString,
'fullFormattedNameString' => $fullFormattedNameString,
'abgabenString' => $abgabenString,
'linkAbgabetool' => $url
);
$email = $betreuerRow->uid ? $betreuerRow->uid."@".DOMAIN : $betreuerRow->private_email;
if(!$email) {
$this->_ci->logInfo('Could not send Email for Betreuer PersonID: "'.$data->person_id.'".');
continue;
}
// send email with bundled info
sendSanchoMail(
'PAAChangesBetSM',
$body_fields,
$email,
$this->p->t('abgabetool', 'changedAbgabeterminev2')
);
$count++;
}
$this->_ci->logInfo($count . " Emails erfolgreich versandt");
$this->_ci->logInfo('End job FHC-Core->notifyBetreuerAboutChangedAbgaben');
}
public function notifyBetreuerMail() {
// send all new projektarbeit abgabe UPLOADS since the last job run to the related betreuer
// this job gathers all new or changed file uploads via field 'abgabedatum', enduploads still
// send an email directly after happening since they are kind of important
$this->_ci->logInfo('Start job FHC-Core->notifyBetreuerMail');
// dont filter for relevant types since this mail should gather all UPLOAD info
$interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL');
$result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSinceByAbgabedatum($interval);
$retval = getData($result);
// retval are paabgaben joined with projektarbeit and betreuer
if(count($retval) == 0) {
$this->logInfo("Keine Emails über neue Paabgaben an Betreuer versandt");
return;
}
// group contents per betreuer person_id
$betreuer_uids = [];
forEach($retval as $paabgabe) {
if(!isset($betreuer_uids[$paabgabe->person_id])) {
$betreuer_uids[$paabgabe->person_id] = [];
}
$betreuer_uids[$paabgabe->person_id][] = $paabgabe;
}
$count = 0;
forEach ($betreuer_uids as $person_id => $abgaben) {
// $person_id is from betreuer
$result = $this->_ci->ProjektarbeitModel->getProjektbetreuerAnrede($person_id);
$data = getData($result)[0];
$anrede = $data->anrede;
$anredeFillString = $data->anrede == "Herr" ? "r" : "";
$fullFormattedNameString = $data->first;
// sorting $abgaben array by datum
usort($abgaben, function ($a, $b) {
return strtotime($a->datum) <=> strtotime($b->datum);
});
$projektarbeit_titel = $abgaben[0]->titel;
// initialize the table and headers
$abgabenString = '
<table style="width: 100%; border-collapse: collapse; font-family: Arial, sans-serif; color: #333; margin-top: 15px; margin-bottom: 15px;">
<thead>
<tr style="background-color: #f2f2f2; text-align: left;">
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 15%;">Zieldatum</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 25%;">Studierende/r</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px;">Bezeichnung</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 15%;">Abgabedatum</th>
</tr>
</thead>
<tbody>';
foreach ($abgaben as $abgabe) {
// format the student name
$nameParts = [];
if (!empty($abgabe->titelpre)) $nameParts[] = $abgabe->titelpre;
$nameParts[] = $abgabe->vorname;
$nameParts[] = $abgabe->nachname;
if (!empty($abgabe->titelpost)) $nameParts[] = $abgabe->titelpost;
$studentFullName = implode(' ', $nameParts);
// format dates inline
$dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y');
$abgabedatumFormatted = (new DateTime($abgabe->abgabedatum))->format('d.m.Y');
// handle the optional Kurzbezeichnung
$kurzbzLine = !empty($abgabe->kurzbz) ? "<br/><small style='color: #666; font-style: italic;'>{$abgabe->kurzbz}</small>" : "";
$abgabenString .= "
<tr>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$dateEmailFormatted}</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$studentFullName}</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px;'>
<strong>{$abgabe->bezeichnung}</strong>{$kurzbzLine}
</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>{$abgabedatumFormatted}</td>
</tr>";
}
$abgabenString .= '</tbody></table>';
$path = $this->_ci->config->item('URL_MITARBEITER');
$url = CIS_ROOT.$path;
$body_fields = array(
'anrede' => $anrede,
'anredeFillString' => $anredeFillString,
'fullFormattedNameString' => $fullFormattedNameString,
'paTitel' => $projektarbeit_titel,
'abgabenString' => $abgabenString,
'linkAbgabetool' => $url
);
$result = $this->_ci->ProjektbetreuerModel->getBetreuerOfProjektarbeit($abgaben[0]->projektarbeit_id, $abgaben[0]->betreuerart_kurzbz);
$data = getData($result)[0];
$email = $data->uid ? $data->uid."@".DOMAIN : $data->private_email;
// in rare cases there are betreuer (often zweitbetreuer) without uid and without private email
if(!$email) {
$this->_ci->logInfo('Could not send Email for Betreuer PersonID: "'.$data->person_id.'".');
continue;
}
// send email with bundled info
sendSanchoMail(
'PaabgabeUpdatesBetSM',
$body_fields,
$email,
$this->p->t('abgabetool', 'changedAbgabeterminev2')
);
$count++;
}
$this->_ci->logInfo($count . " Emails erfolgreich versandt");
$this->_ci->logInfo('End job FHC-Core->notifyBetreuerMail');
}
public function notifyStudentMail()
{
// send all new projektarbeit abgabe since the last job run to the related student
$this->_ci->logInfo('Start job FHC-Core->notifyStudentMail');
$interval = $this->_ci->config->item('PAABGABE_EMAIL_JOB_INTERVAL');
$relevantTypes = $this->_ci->config->item('RELEVANT_PAABGABETYPEN_SAMMELMAIL_STUDENT');
$result = $this->_ci->PaabgabeModel->findAbgabenNewOrUpdatedSince($interval, $relevantTypes);
$retval = getData($result);
if(count($retval) == 0) {
$this->_ci->logInfo("Keine Emails an Studenten versandt");
return;
}
// group results per projektarbeit/student_uid
$student_uids = [];
forEach($retval as $paabgabe) {
if(!isset($student_uids[$paabgabe->student_uid])) {
$student_uids[$paabgabe->student_uid] = [];
}
$student_uids[$paabgabe->student_uid][] = $paabgabe;
}
$count = 0;
foreach ($student_uids as $uid => $abgaben) {
// $uid is the student's UID
$result = $this->_ci->StudentModel->getEmailAnredeForStudentUID($uid);
$data = getData($result)[0];
// $abgabe is the array of paabgabe objects
$anredeFillString = $data->anrede=="Herr"?"r":"";
$fullFormattedNameString = trim($data->titelpre." ".$data->vorname." ".$data->vornamen." ".$data->nachname." ".$data->titelpost);
// https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.spaceship-op
// php has spaceships 🚀🚀🚀🚀🚀
usort($abgaben, function($a, $b) {
return strtotime($a->datum) <=> strtotime($b->datum);
});
$projektarbeit_titel = $abgaben[0]->titel;
// initialize the table and headers
$abgabenString = '
<table style="width: 100%; border-collapse: collapse; font-family: Arial, sans-serif; color: #333; margin-top: 15px; margin-bottom: 15px;">
<thead>
<tr style="background-color: #f2f2f2; text-align: left;">
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px; width: 25%;">Zieldatum</th>
<th style="padding: 10px; border: 1px solid #ddd; font-size: 13px;">Bezeichnung / Hinweis</th>
</tr>
</thead>
<tbody>';
foreach ($abgaben as $abgabe) {
$dateEmailFormatted = (new DateTime($abgabe->datum))->format('d.m.Y');
// handle the optional Kurzbezeichnung
$kurzbzLine = !empty($abgabe->kurzbz) ? "<br/><small style='color: #666; font-style: italic;'>{$abgabe->kurzbz}</small>" : "";
$abgabenString .= "
<tr>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px; vertical-align: top;'>
{$dateEmailFormatted}
</td>
<td style='padding: 10px; border: 1px solid #ddd; font-size: 13px;'>
<strong>{$abgabe->bezeichnung}</strong>{$kurzbzLine}
</td>
</tr>";
}
$abgabenString .= '</tbody></table>';
$route = $this->_ci->config->item('URL_STUDENTS');
$url = CIS_ROOT.$route;
$body_fields = array(
'anrede' => $data->anrede,
'anredeFillString' => $anredeFillString,
'fullFormattedNameString' => $fullFormattedNameString,
'paTitel' => $projektarbeit_titel,
'abgabenString' => $abgabenString,
'linkAbgabetool' => $url
);
// send email with bundled info
sendSanchoMail(
'PaabgabeUpdatesSammelmail',
$body_fields,
$uid.'@'.DOMAIN,
$this->p->t('abgabetool', 'changedAbgabeterminev2')
);
$count++;
}
$this->_ci->logInfo($count . " Emails erfolgreich versandt");
$this->_ci->logInfo('End job FHC-Core->notifyStudentMail');
}
}
+88 -4
View File
@@ -200,13 +200,14 @@ class AntragJob extends JOB_Controller
}
/**
* Send reminder to Assistant for Wiedereinstieg Unterbrecher
* Send reminder to Assistant and to Student for Wiedereinstieg Unterbrecher
*
*/
public function sendReminderWiedereinstieg()
{
$now = new DateTime();
$modifier = $this->config->item('unterbrechung_job_remind_wiedereinstieg_date_modifier');
if (!$modifier)
return $this->logError('Konnte Job nicht starten: Config "unterbrechung_job_remind_wiedereinstieg_date_modifiers" nicht gesetzt');
@@ -230,6 +231,7 @@ class AntragJob extends JOB_Controller
$antraege = getData($result) ?: [];
$count = 0;
$countReminderStudent = 0;
foreach ($antraege as $antrag)
{
$res = $this->StudierendenantragModel->getStgAndSem($antrag->studierendenantrag_id);
@@ -257,10 +259,92 @@ class AntragJob extends JOB_Controller
$data['UID'] = $student->student_uid;
}
// NOTE(chris): Sancho mail
if(sendSanchoMail('Sancho_Mail_Antrag_U_Reminder', $data, $antrag->email, 'Reminder: Unterbrechung Wiedereinstieg'))
//Data für Email Student
$result = $this->PrestudentModel->load($antrag->prestudent_id);
$dataPrestudent = current(getData($result));
$person_id = $dataPrestudent->person_id;
$this->KontaktModel->addSelect('kontakt');
$result = $this->KontaktModel->loadWhere([
'person_id'=> $person_id,
'zustellung' => true,
'kontakttyp' => 'email'
]);
$email_student_privat = null;
$dataKontakt = getData($result);
if ($dataKontakt) {
$stud_private_zustell_emails = array_map(function($kontakt) {
return $kontakt->kontakt;
}, $dataKontakt);
$email_student_privat = implode(', ', $stud_private_zustell_emails);
}
$email_student_FH = $this->StudentModel->getEmailFH($this->StudentModel->getUID($antrag->prestudent_id));
//studiensemester
$result = $this->StudiensemesterModel->getByDate($datum->format('Y-m-d'));
if (hasData($result)) {
$dataSem = current(getData($result));
}
$studiensemester = $dataSem->studiensemester_kurzbz;
$studsemShort = substr($studiensemester, 0, 2);
if($studsemShort == "SS")
{
$data['studSemShort_Eng'] = "summer semester";
$data['meldenBis'] = "15.1.";
$data['meldenBis_Eng'] = "January 15";
}
elseif ($studsemShort == "WS") {
$data['studSemShort_Eng'] = "winter semester";
$data['meldenBis'] = "1.8.";
$data['meldenBis_Eng'] = "August 1";
}
else
{
$studsemShort = "SS/WS";
$data['studSemShort_Eng'] = "summer/winter semester";
$data['meldenBis'] = "15.1. (bei Einstieg ins SS) / 1.8. (bei Einstieg ins WS)";
$data['meldenBis_Eng'] = "January 15 (for sommer semester enrollment) / August 1 (for winter semester enrollment)";
}
$data['studSemShort'] = $studsemShort;
// NOTE(chris): Sancho mail Assistant
$sancho_assistant_sent = sendSanchoMail('Sancho_Mail_Antrag_U_Reminder', $data, $antrag->email, 'Reminder: Unterbrechung Wiedereinstieg');
if($sancho_assistant_sent)
{
$count++;
}
else
{
$this->logError('Error: failed to send Assistant Reminder studierendenantrag_id: ' . $antrag->studierendenantrag_id);
}
//Mail to Student
$sancho_student_sent = sendSanchoMail(
'Sancho_Mail_Antrag_U_Remind_Stud',
$data,
$email_student_FH,
'Reminder: Unterbrechung Wiedereinstieg',
'',
'',
'',
$email_student_privat);
if($sancho_student_sent)
{
$countReminderStudent++;
}
else
{
$this->logError('Error: failed to send Student Reminder studierendenantrag_id: ' . $antrag->studierendenantrag_id);
}
if($sancho_assistant_sent && $sancho_student_sent)
{
$this->StudierendenantragstatusModel->insert([
'studierendenantrag_id' => $antrag->studierendenantrag_id,
'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_REMINDERSENT,
@@ -268,7 +352,7 @@ class AntragJob extends JOB_Controller
]);
}
}
$this->logInfo($count . ' Reminder gesendet - Ende Job sendReminderWiedereinstieg');
$this->logInfo($count . ' Reminder an Assistenz und ' . $countReminderStudent . ' Reminder an Student gesendet - Ende Job sendReminderWiedereinstieg');
}
/**
@@ -22,6 +22,7 @@ class InfoCenter extends Auth_Controller
const REIHUNGSTESTABSOLVIERT_PAGE = 'reihungstestAbsolviert';
const ABGEWIESEN_PAGE = 'abgewiesen';
const AUFGENOMMEN_PAGE = 'aufgenommen';
const ONBOARDING_PAGE = 'onboarding';
const SHOW_DETAILS_PAGE = 'showDetails';
const SHOW_ZGV_DETAILS_PAGE = 'showZGVDetails';
const ZGV_UBERPRUEFUNG_PAGE = 'ZGVUeberpruefung';
@@ -116,6 +117,7 @@ class InfoCenter extends Auth_Controller
'index' => 'infocenter:r',
'freigegeben' => 'infocenter:r',
'abgewiesen' => 'infocenter:r',
'onboarding' => 'infocenter:r',
'aufgenommen' => 'infocenter:r',
'reihungstestAbsolviert' => 'infocenter:r',
'showDetails' => 'infocenter:r',
@@ -230,6 +232,13 @@ class InfoCenter extends Auth_Controller
$this->load->view('system/infocenter/infocenterAbgewiesen.php');
}
public function onboarding()
{
$this->_setNavigationMenu(self::ONBOARDING_PAGE); // define the navigation menu for this page
$this->load->view('system/infocenter/onboarding.php');
}
/**
* Aufgenommene page of the InfoCenter tool
@@ -1553,6 +1562,7 @@ class InfoCenter extends Auth_Controller
$reihungstestAbsolviertLink = site_url(self::INFOCENTER_URI.'/'.self::REIHUNGSTESTABSOLVIERT_PAGE);
$abgewiesenLink = site_url(self::INFOCENTER_URI.'/'.self::ABGEWIESEN_PAGE);
$aufgenommenLink = site_url(self::INFOCENTER_URI.'/'.self::AUFGENOMMEN_PAGE);
$onboardingLink = site_url(self::INFOCENTER_URI.'/'.self::ONBOARDING_PAGE);
$currentFilterId = $this->input->get(self::FILTER_ID);
if (isset($currentFilterId))
@@ -1561,6 +1571,7 @@ class InfoCenter extends Auth_Controller
$reihungstestAbsolviertLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId;
$abgewiesenLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId;
$aufgenommenLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId;
$onboardingLink .= '?'.self::PREV_FILTER_ID.'='.$currentFilterId;
}
$this->navigationlib->setSessionMenu(
@@ -1624,6 +1635,18 @@ class InfoCenter extends Auth_Controller
'', // target
40 // sort
),
'ohnePrestudent' => $this->navigationlib->oneLevel(
'Electronic Onboarding', // description
$onboardingLink, // link
null, // children
'users', // icon
null, // subscriptDescription
false, // expand
null, // subscriptLinkClass
null, // subscriptLinkValue
'', // target
50 // sort
),
)
);
}
@@ -1650,6 +1673,8 @@ class InfoCenter extends Auth_Controller
$link = site_url(self::ZGV_UEBERPRUEFUNG_URI);
if ($origin_page === self::ABGEWIESEN_PAGE)
$link = site_url(self::INFOCENTER_URI.'/'.self::ABGEWIESEN_PAGE);
if ($origin_page === self::ONBOARDING_PAGE)
$link = site_url(self::INFOCENTER_URI.'/'.self::ONBOARDING_PAGE);
if ($origin_page === self::AUFGENOMMEN_PAGE)
$link = site_url(self::INFOCENTER_URI.'/'.self::AUFGENOMMEN_PAGE);
@@ -1691,6 +1716,7 @@ class InfoCenter extends Auth_Controller
$freigegebenLink = site_url(self::INFOCENTER_URI.'/'.self::FREIGEGEBEN_PAGE);
$absolviertLink = site_url(self::INFOCENTER_URI.'/'.self::REIHUNGSTESTABSOLVIERT_PAGE);
$abgewiesenLink = site_url(self::INFOCENTER_URI.'/'.self::ABGEWIESEN_PAGE);
$onboardingLink = site_url(self::INFOCENTER_URI.'/'.self::ONBOARDING_PAGE);
$prevFilterId = $this->input->get(self::PREV_FILTER_ID);
if (isset($prevFilterId))
{
@@ -1767,6 +1793,24 @@ class InfoCenter extends Auth_Controller
)
);
}
if($page == self::ONBOARDING_PAGE)
{
$this->navigationlib->setSessionElementMenu(
'onboarding',
$this->navigationlib->oneLevel(
'Electronic Onboarding', // description
$onboardingLink, // link
null, // children
'users', // icon
null, // subscriptDescription
false, // expand
null, // subscriptLinkClass
null, // subscriptLinkValue
'', // target
50 // sort
)
);
}
}
/**
+22 -9
View File
@@ -70,20 +70,22 @@ abstract class Auth_Controller extends FHC_Controller
/**
* Checks for Permissions depending if the given person is a
* Mitarbeiter and/or Student
* If neither Student nor Mitarbeiter, default permissions are checked
* and exits/outputs an error if they are not met.
*
* @param integer $person_id
* @param array $permMa Perms if the person is a Mitarbeiter
* @param array $permStud Perms if the person is a Student
* @param array $permDefault Perms if the person is neither a Student nor a Mitarbeiter
*
* @return void
*/
protected function checkPermissionsForPerson($person_id, $permMa, $permStud)
protected function checkPermissionsForPerson($person_id, $permMa, $permStud, $permDefault = null)
{
$res = $this->hasPermissionsForPerson($person_id, $permMa, $permStud);
$res = $this->hasPermissionsForPerson($person_id, $permMa, $permStud, $permDefault);
if ($res) {
$perm = array_keys(array_flip(array_merge($res|1 ? $permMa : [], $res|2 ? $permStud : [])));
$perm = array_keys(array_flip(array_merge($res&1 ? $permMa : [], $res&2 ? $permStud : [], $res&4 ? $permDefault : [])));
$this->_outputAuthError([$this->router->method => $perm]);
}
}
@@ -108,16 +110,19 @@ abstract class Auth_Controller extends FHC_Controller
* Checks for Permissions depending if the given person is a
* Mitarbeiter and/or Student
* and returns the result.
*
* If neither Student nor Mitarbeiter, default permissions are checked
*
* @param integer $person_id
* @param array $permMa Perms if the person is a Mitarbeiter
* @param array $permStud Perms if the person is a Student
*
* @param array $permDefault Perms if the person is neither a Student nor a Mitarbeiter
* @return integer 0 if permission is granted
*/
protected function hasPermissionsForPerson($person_id, $permMa, $permStud)
protected function hasPermissionsForPerson($person_id, $permMa, $permStud, $permDefault)
{
$res = 3;
$res = 8;
$isMitarbeiter = false;
$isStudent = false;
$this->load->model('person/Person_model', 'PersonModel');
$this->PersonModel->addJoin('public.tbl_benutzer', 'person_id');
$this->PersonModel->addJoin('public.tbl_mitarbeiter', 'uid = mitarbeiter_uid');
@@ -125,7 +130,8 @@ abstract class Auth_Controller extends FHC_Controller
if (hasData($result)) {
if ($this->permissionlib->isEntitled(['a' => $permMa], 'a'))
return 0;
$res = 1;
$isMitarbeiter = true;
$res += 1;
}
$this->PersonModel->addJoin('public.tbl_prestudent', 'person_id');
$result = $this->PersonModel->load($person_id);
@@ -140,8 +146,15 @@ abstract class Auth_Controller extends FHC_Controller
return 0;
}
}
$isStudent = true;
$res += 2;
}
if (isset($permDefault) && !$isMitarbeiter && !$isStudent)
{
if ($this->permissionlib->isEntitled(['a' => $permDefault], 'a'))
return 0;
$res += 4;
}
return $res;
}
+1 -1
View File
@@ -35,7 +35,7 @@ class CI3_Events
});
self::$eventsSorted[$event] = true;
}
foreach (self::$events[$event] as $conf) {
$conf[1](...$args);
}
+28 -1
View File
@@ -266,7 +266,7 @@ class FHCAPI_Controller extends Auth_Controller
}
// ---------------------------------------------------------------
// Security
// Security Begin
// ---------------------------------------------------------------
/**
@@ -287,4 +287,31 @@ class FHCAPI_Controller extends Auth_Controller
'required_permissions' => $this->_rpsToString($requiredPermissions, $this->router->method)
], self::ERROR_TYPE_AUTH);
}
// ---------------------------------------------------------------
// Security End
// ---------------------------------------------------------------
/**
* Checks the client's total request size (Content-Length) against the minimum
* effective PHP limit (min of upload_max_filesize, post_max_size, memory_limit).
* This preempts failures that result in vague "missing parameters" errors on large files.
*
* @return void
*/
protected function checkUploadSize() {
// this number represents bytes
$content_length_bytes = (int)$this->input->server('CONTENT_LENGTH');
$content_length = $content_length_bytes / 1000000;
//get max serverside size upload -> this comes in megabytes
$max_upload = (int)(ini_get('upload_max_filesize'));
$max_post = (int)(ini_get('post_max_size'));
$memory_limit = (int)(ini_get('memory_limit'));
$max_upload_mb = min($max_upload, $max_post, $memory_limit); // smallest of 3 config values
if($content_length >= $max_upload_mb) {
$this->terminateWithError($this->p->t('global', 'filesizeExceeded'), 'general');
}
}
}
+47 -61
View File
@@ -8,7 +8,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
{
const DEFAULT_PERMISSION_R = 'admin:r';
const DEFAULT_PERMISSION_RW = 'admin:rw';
//public function __construct($zuordnung = 'person/Notizzuordnung_model')
public function __construct($permissions)
{
$default_permissions = [
@@ -97,13 +97,13 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
$this->terminateWithSuccess(getData($result) ?: []);
}
//Override function
protected function isBerechtigt($id, $typeId){
return $this->terminateWithError("in abstract function: define right in extension", self::ERROR_TYPE_GENERAL);
$this->terminateWithError("in abstract function: define right in extension", self::ERROR_TYPE_GENERAL);
}
public function loadNotiz()
@@ -112,7 +112,6 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$notiz_id = $this->input->post('notiz_id');
//$this->load->model('person/Notiz_model', 'NotizModel');
$this->NotizModel->addJoin('public.tbl_notiz_dokument', 'notiz_id', 'LEFT');
$this->NotizModel->addSelect('*');
$this->NotizModel->addSelect("TO_CHAR(CASE WHEN public.tbl_notiz.updateamum >= public.tbl_notiz.insertamum
@@ -143,14 +142,9 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$uid = getAuthUID();
if (isset($_POST['data']))
{
$data = json_decode($_POST['data']);
unset($_POST['data']);
foreach ($data as $k => $v) {
$_POST[$k] = $v;
}
}
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$this->form_validation->set_data($post_data);
//Form Validation
$this->form_validation->set_rules('titel', 'Titel', 'required', [
@@ -166,26 +160,25 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$titel = $this->input->post('titel');
$text = $this->input->post('text');
$erledigt = $this->input->post('erledigt');
$verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid;
$bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : null;
$type = $this->input->post('typeId');
$start = $this->input->post('start');
$ende = $this->input->post('ende');
$titel = $post_data['titel'];
$text = $post_data['text'];
$erledigt = $post_data['erledigt'];
$bearbeiter_uid = isset($post_data['bearbeiter']) ? $post_data['bearbeiter'] : null;
$type = $post_data['typeId'];
$start = isset($post_data['start']) ? $post_data['start'] : null;
$ende = isset($post_data['ende']) ? $post_data['ende'] : null;
// Start DB transaction
$this->db->trans_start();
//Save note
$result = $this->NotizModel->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $verfasser_uid,
"insertvon" => $verfasser_uid, 'start' => $start, 'ende' => $ende, 'bearbeiter_uid' => $bearbeiter_uid));
$result = $this->NotizModel->insert(array('titel' => $titel, 'text' => $text, 'erledigt' => $erledigt, 'verfasser_uid' => $uid,
"insertvon" => $uid, 'start' => $start, 'ende' => $ende, 'bearbeiter_uid' => $bearbeiter_uid));
if (isError($result))
{
$this->db->trans_rollback();
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$notiz_id = $result->retval;
@@ -220,7 +213,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result))
{
$this->db->trans_rollback();
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$dms_id_arr[] = $result->retval['dms_id'];
}
@@ -235,34 +228,28 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result))
{
$this->db->trans_rollback();
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
}
}
$this->db->trans_commit();
return $this->terminateWithSuccess($result);
$this->terminateWithSuccess($result);
}
public function updateNotiz()
{
$this->load->library('form_validation');
$this->load->library('DmsLib');
if (isset($_POST['data']))
{
$data = json_decode($_POST['data']);
unset($_POST['data']);
foreach ($data as $k => $v) {
$_POST[$k] = $v;
}
}
$json = $this->input->post('data');
$post_data = json_decode($json, true);
$notiz_id = $this->input->post('notiz_id');
$this->form_validation->set_data($post_data);
if(!$notiz_id)
{
$this->terminateWithError($this->p->t('ui','error_missingId',['id'=>'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
$this->form_validation->set_rules('notiz_id', 'Notiz ID', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'notiz_id'])
]);
//Form Validation
$this->form_validation->set_rules('titel', 'Titel', 'required', [
@@ -280,25 +267,23 @@ abstract class Notiz_Controller extends FHCAPI_Controller
//update Notiz
$uid = getAuthUID();
$titel = $this->input->post('titel');
$text = $this->input->post('text');
$verfasser_uid = isset($_POST['verfasser']) ? $_POST['verfasser'] : $uid;
$bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : $uid;
$erledigt = $this->input->post('erledigt');
$start = $this->input->post('start');
$ende = $this->input->post('ende');
$titel = $post_data['titel'];
$text = $post_data['text'];
$bearbeiter_uid = isset($post_data['bearbeiter']) ? $post_data['bearbeiter'] : $post_data['bearbeiter_uid'];
$erledigt = $post_data['erledigt'];
$start = $post_data['start'];
$ende = $post_data['ende'];
$result = $this->NotizModel->update(
[
'notiz_id' => $notiz_id
'notiz_id' => $post_data['notiz_id'],
],
[
'titel' => $titel,
'updatevon' => $uid,
'updateamum' => date('c'),
'text' => $text,
'verfasser_uid' => $verfasser_uid,
'bearbeiter_uid' => $bearbeiter_uid,
'bearbeiter_uid' => isEmptyString($bearbeiter_uid) ? null : $bearbeiter_uid,
'start' => $start,
'ende' => $ende,
'erledigt' => $erledigt
@@ -306,7 +291,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
//update(1) loading all dms-entries with this notiz_id
@@ -314,7 +299,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$this->load->model('person/Notizdokument_model', 'NotizdokumentModel');
$this->NotizdokumentModel->addJoin('campus.tbl_dms_version', 'dms_id');
$result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $notiz_id));
$result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $post_data['notiz_id']));
$result = $this->getDataOrTerminateWithError($result);
foreach ($result as $doc) {
$dms_id_arr[$doc->dms_id] = array(
@@ -351,7 +336,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$result = $this->getDataOrTerminateWithError($result);
$dms_id = $result['dms_id'];
$result = $this->NotizdokumentModel->insert(array('notiz_id' => $notiz_id, 'dms_id' => $dms_id));
$result = $this->NotizdokumentModel->insert(array('notiz_id' => $post_data['notiz_id'], 'dms_id' => $dms_id));
$this->getDataOrTerminateWithError($result);
}
@@ -365,7 +350,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$this->getDataOrTerminateWithError($result);
}
return $this->terminateWithSuccess($result);
$this->terminateWithSuccess($result);
}
public function deleteNotiz()
@@ -416,15 +401,15 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result))
{
$this->db->trans_rollback();
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if(!hasData($result))
{
return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
$this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
$this->db->trans_complete();
return $this->terminateWithSuccess(getData($result));
$this->terminateWithSuccess(getData($result));
}
public function loadDokumente()
@@ -432,6 +417,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
$notiz_id = $this->input->post('notiz_id');
$this->NotizModel->addSelect('campus.tbl_dms_version.*');
$this->NotizModel->addSelect($this->NotizModel->escape(base_url('content/notizdokdownload.php?id=')) . ' || public.tbl_notiz_dokument.dms_id AS preview');
$this->NotizModel->addJoin('public.tbl_notiz_dokument', 'ON (public.tbl_notiz_dokument.notiz_id = public.tbl_notiz.notiz_id)');
$this->NotizModel->addJoin('campus.tbl_dms_version', 'ON (public.tbl_notiz_dokument.dms_id = campus.tbl_dms_version.dms_id)');
@@ -440,14 +426,14 @@ abstract class Notiz_Controller extends FHCAPI_Controller
array('public.tbl_notiz.notiz_id' => $notiz_id)
);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if(!hasData($result))
{
return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
$this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result));
$this->terminateWithSuccess(getData($result));
}
public function getMitarbeiter($searchString)
@@ -457,7 +443,7 @@ abstract class Notiz_Controller extends FHCAPI_Controller
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess($result);
$this->terminateWithSuccess($result);
}
public function getCountNotes($person_id)
@@ -476,4 +462,4 @@ abstract class Notiz_Controller extends FHCAPI_Controller
return $this->terminateWithSuccess($anzahl->anzahl ?: 0);
}
}
}
+73 -18
View File
@@ -91,7 +91,7 @@ function var_dump_to_error_log($parameter)
var_dump($parameter); // KEEP IT!!!
$ob_get_contents = ob_get_contents();
ob_end_clean();
error_log(str_replace("\n", '', $ob_get_contents)); // KEEP IT!!!
error_log(str_replace("\n", '', $ob_get_contents) . ', referer: ' . "http".(!empty($_SERVER['HTTPS'])?"s":"")."://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']); // KEEP IT!!!
}
/**
@@ -408,22 +408,6 @@ function findResource($path, $resource, $subdir = false, $extraDir = null)
return null;
}
/**
* check if String can be converted to a date
*/
function isValidDate($dateString)
{
try
{
return (new DateTime($dateString)) !== false;
}
catch(Exception $e)
{
return false;
}
}
// ------------------------------------------------------------------------
// PHP functions that don't exist in older versions
// ------------------------------------------------------------------------
@@ -446,7 +430,8 @@ if (!function_exists('array_is_list')) {
// ------------------------------------------------------------------------
/**
* check if string can be converted to a date
* Check if the provided parameter is a string containing a valid date
* NOTE: the name is in the "snake case" format because othewise the CI form validation _cannot_ use it
*/
function is_valid_date($dateString)
{
@@ -515,3 +500,73 @@ function has_permissions_for_stg($studiengang_kz, $permissions = '')
return false;
}
/**
* check if an entry exists in the database
*/
function is_in_db($key, $model = '')
{
if (!$model)
return false;
$field = strstr($model, ":");
if ($field) {
$model = strstr($model, ":", true);
$field = substr($field, 1);
}
$CI =& get_instance();
$CI->load->model($model, $model);
if ($field) {
$result = $CI->$model->loadWhere([
$field => $key
]);
} else {
$result = $CI->$model->load($key);
}
return (isSuccess($result) && hasData($result));
}
/**
* is building an array for Dropdown Entry in Print Dropdown
* @param $id id for the Document to add to the Document Array
* @param $name title of the dropdownEntry
* @param $parameterUrl url of parameters xml, xsl, format etc as needed
* WITHOUT BASEURL eg. "xml=abschlusspruefung.rdf.php&xsl_stg_kz=$studiengang_kz&xsl=Bescheid&output=pdf"
* @param $uid default parameter, if null only parameterurl will be added
* additional needed parameter: put in the parameterUrl
* @param $alternativeBaseUrl: if baseUrl not pdfExport.php, put here alternative without ? char, eg. "zutrittskarte.php"
*
* @return Array
*/
function buildDropdownEntryPrintArray($id, $name, $parameterurl, $uid=null, $order=null, $alternativeBaseUrl=null)
{
//DEFAULT BASEURL
$baseurl = "pdfExport.php?";
$uidString = $uid ? "&uid=" . $uid : "";
if($alternativeBaseUrl)
{
return [
"id" => $id,
"type" => "documenturl",
"name" => $name,
"url" => $alternativeBaseUrl . "?" . $parameterurl . $uidString,
"order" => $order
];
}
else
return [
"id" => $id,
"type" => "documenturl",
"name" => $name,
"url" => $baseurl . $parameterurl . "&uid=" . $uid,
"order" => $order
];
}
+220 -1
View File
@@ -185,7 +185,15 @@ function generateJSModulesInclude($JSModules)
for ($tmpJSsCounter = 0; $tmpJSsCounter < count($tmpJSs); $tmpJSsCounter++)
{
$toPrint = sprintf($jsInclude, base_url($tmpJSs[$tmpJSsCounter].$cachetoken)).PHP_EOL;
if($ci->config->item('use_fhcomplete_build_version_in_path'))
{
$relurl = preg_replace('#public/#', 'public/' . $ci->config->item('fhcomplete_build_version') . '/', $tmpJSs[$tmpJSsCounter]);
$toPrint = sprintf($jsInclude, base_url($relurl)).PHP_EOL;
}
else
{
$toPrint = sprintf($jsInclude, base_url($tmpJSs[$tmpJSsCounter].$cachetoken)).PHP_EOL;
}
if ($tmpJSsCounter > 0) $toPrint = "\t\t".$toPrint;
@@ -246,3 +254,214 @@ function generateSkipLink($skipID)
$toPrint.='" class="fhcSkipLink" aria-label="Skip to main content"></a>';
echo $toPrint;
}
function absoluteJsImportUrl($relurl)
{
$ci =& get_instance();
$ci->load->config('javascript');
if($ci->config->item('use_fhcomplete_build_version_in_path'))
{
$url = base_url(preg_replace('#^public/#', 'public/' . $ci->config->item('fhcomplete_build_version') . '/', $relurl));
}
else
{
$url = base_url($relurl) . '?'. $ci->config->item('fhcomplete_build_version');
}
return $url;
}
/*
* Manipulate CI views includes Array to load
* - public/js/FhcApps.js via customJSs and
* - app customisation js and/or css from extensions via customJSModules
* if customJSModules contains at least one vuejs app and customisation files
* exist in extensions
*/
class ExtendableAppsHelper
{
private static $instance = null;
protected $extensions;
protected $customCSSs;
protected $customJSs;
protected $customJSModules;
protected $initialised;
protected $appscount;
protected $extCustomCSSs;
protected $extCustomJSs;
protected $extCustomJSModules;
private function __construct()
{
$this->extensions = array();
$this->customCSSs = null;
$this->customJSs = null;
$this->customJSModules = null;
$this->initialised = false;
$this->appscount = 0;
$this->extCustomCSSs = null;
$this->extCustomJSs = null;
$this->extCustomJSModules = null;
}
public static function getInstance()
{
if(self::$instance === null)
{
self::$instance = new ExtendableAppsHelper();
}
return self::$instance;
}
public function init($customCSSs, $customJSs, $customJSModules)
{
if($this->initialised)
{
return;
}
$this->customCSSs = $customCSSs;
$this->customJSs = $customJSs;
$this->customJSModules = $customJSModules;
$this->initialised = true;
if(!isset($this->customJSModules))
{
return;
}
if(!is_array($this->customJSModules))
{
$this->customJSModules = array($this->customJSModules);
}
if(count($this->customJSModules) < 1)
{
return;
}
$this->buildExtensionsList();
$this->prepareExtendedArrays();
}
public function getCustomCSSs()
{
if(is_null($this->extCustomCSSs))
{
return $this->customCSSs;
}
return $this->extCustomCSSs;
}
public function getCustomJSs()
{
if(is_null($this->extCustomJSs))
{
return $this->customJSs;
}
return $this->extCustomJSs;
}
public function getCustomJSModules()
{
if(is_null($this->extCustomJSModules))
{
return $this->customJSModules;
}
return $this->extCustomJSModules;
}
protected function buildExtensionsList()
{
$this->extensions = array();
$fsiterator = new FilesystemIterator(FHCPATH . 'application/extensions');
foreach ($fsiterator as $fsitem)
{
if(preg_match('/^FHC-Core-/', $fsitem->getBasename()))
{
$this->extensions[] = $fsitem->getBasename();
}
}
}
protected function prepareExtendedArrays()
{
$this->appscount = 0;
$this->initExtCustomCSSs();
$this->extCustomJSModules = array();
foreach($this->customJSModules as $item)
{
$matches = array();
if(preg_match('#^public/(extensions/FHC-Core-.+)?js/apps/(.*)\.js$#', $item, $matches))
{
$this->appscount++;
$fhcextension = $matches[1];
$app = $matches[2];
$extend_js_suffix = 'js/extend_app/' . $fhcextension . $app . '.js';
$extend_css_suffix = 'css/extend_app/' . $fhcextension . $app . '.css';
foreach($this->extensions as $extension)
{
$extend_js = 'public/extensions/' . $extension . '/' . $extend_js_suffix;
$extend_css = 'public/extensions/' . $extension . '/' . $extend_css_suffix;
if(is_readable(FHCPATH . $extend_js))
{
array_push($this->extCustomJSModules, $extend_js);
}
if(is_readable(FHCPATH . $extend_css))
{
array_push($this->extCustomCSSs, $extend_css);
}
}
}
array_push($this->extCustomJSModules, $item);
}
if($this->appscount > 0)
{
$this->addFhcAppsJs();
}
}
protected function initExtCustomCSSs()
{
if(!isset($this->customCSSs))
{
$this->extCustomCSSs = array();
}
elseif(!is_array($this->customCSSs))
{
$this->extCustomCSSs = array($this->customCSSs);
}
else
{
$this->extCustomCSSs = $this->customCSSs;
}
}
protected function addFhcAppsJs()
{
if(!isset($this->customJSs))
{
$this->extCustomJSs = array();
}
elseif(!is_array($this->customJSs))
{
$this->extCustomJSs = array($this->customJSs);
}
else
{
$this->extCustomJSs = $this->customJSs;
}
array_push($this->extCustomJSs, 'public/js/FhcApps.js');
}
}
@@ -41,3 +41,4 @@ if (!defined('BASEPATH')) exit('No direct script access allowed');
$lang['form_validation_has_write_permissions'] = 'You have no rights to edit {field} field.';
$lang['form_validation_is_valid_date'] = 'The date format is invalid or out of range.';
$lang['form_validation_has_permissions_for_stg'] = 'You have no rights for stg {field}.';
$lang['form_validation_is_in_db'] = '{field} does not exist.';
+1 -1
View File
@@ -128,7 +128,7 @@ class AntragLib
return $this->_ci->StudierendenantragstatusModel->resumeAntraegeForAbmeldungStgl($antrag_id);
}
// NOTE(chris): get last status that is not pause
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum');
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum', 'DESC');
$this->_ci->StudierendenantragstatusModel->addLimit(1);
$result = $this->_ci->StudierendenantragstatusModel->loadWhere([
'studierendenantrag_id' => $antrag_id,
+2 -1
View File
@@ -180,7 +180,8 @@ class DocsboxLib
}
// Just started or still working on it
elseif ($getStatusResponse->body->status == self::STATUS_WORKING
|| $getStatusResponse->body->status == self::STATUS_STARTED)
|| $getStatusResponse->body->status == self::STATUS_STARTED
|| $getStatusResponse->body->status == self::STATUS_QUEUED)
{
// go on!
}
+10 -2
View File
@@ -17,6 +17,7 @@ class LektorLib
$this->_ci->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$this->_ci->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->_ci->load->model('person/Benutzer_model', 'BenutzerModel');
$this->_ci->load->library('PhrasesLib', array('lehre'));
}
public function addLektorToLehreinheit($lehreinheit_id, $mitarbeiter_uid)
@@ -35,7 +36,7 @@ class LektorLib
if (isError($already_assigned)) return $already_assigned;
if (hasData($already_assigned)) return error('Lektor already assigned');
if (hasData($already_assigned)) return error($this->_ci->phraseslib->t("lehre", "bereitzugeteilt"));
$studiensemester_result = $this->_ci->StudiensemesterModel->loadWhere(array('studiensemester_kurzbz' => $lehreinheit->studiensemester_kurzbz));
if (isError($studiensemester_result)) return $studiensemester_result;
@@ -88,6 +89,7 @@ class LektorLib
$lehreinheit = getData($lehreinheit_result)[0];
//TODO kollision check, wird vorerst nicht implementiert -> nur über das FAS möglich
if (isset($new_data['mitarbeiter_uid']) && $new_data['mitarbeiter_uid'] !== $mitarbeiter_uid)
{
@@ -98,7 +100,13 @@ class LektorLib
$verplant = $this->_ci->StundenplandevModel->loadWhere(array('lehreinheit_id' => $lehreinheit_id, 'mitarbeiter_uid' => $mitarbeiter_uid));
if (hasData($verplant))
return error('Wechsel vom Mitarbeiter nicht möglich da er bereits verplant ist!');
return error($this->_ci->phraseslib->t("lehre", "lektorbereitsverplant"));
$lehreinheit_data = $this->_ci->LehreinheitmitarbeiterModel->loadWhere(array('mitarbeiter_uid' => $new_data['mitarbeiter_uid'], 'lehreinheit_id' => $lehreinheit_id));
if (hasData($lehreinheit_data))
return error($this->_ci->phraseslib->t("lehre", "bereitzugeteilt"));
}
$warning = '';
if (isset($new_data['semesterstunden']))
+16 -1
View File
@@ -50,6 +50,7 @@ class PermissionLib
const LOGINAS_PERSONIDS_BLACKLIST = 'permission_loginas_personids_blacklist';
private $_ci; // CI instance
private $access_rights; // current users access rights
private static $bb; // benutzerberechtigung
/**
@@ -61,6 +62,8 @@ class PermissionLib
// Loads CI instance
$this->_ci =& get_instance();
$this->access_rights = null;
$this->_ci->config->load('permission'); // Loads permission configuration
// If it's NOT called from command line
@@ -69,8 +72,10 @@ class PermissionLib
// API Caller rights initialization
$authObj = $this->_ci->authlib->getAuthObj();
self::$bb = new benutzerberechtigung();
if ($authObj)
if ($authObj) {
self::$bb->getBerechtigungen($authObj->{AuthLib::AO_USERNAME});
$this->access_rights = self::$bb->berechtigungen;
}
}
}
@@ -340,6 +345,16 @@ class PermissionLib
}
}
/**
* Returns the access rights for the current user
*
* @return array|null
*/
public function getAccessRights()
{
return $this->access_rights;
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
+237 -6
View File
@@ -35,6 +35,90 @@ class PrestudentLib
$this->_ci->load->model('organisation/Studiengang_model', 'StudiengangModel');
}
/**
* Sets initial prestudent entry, no status yet.
* @return object success or error
*/
public function setPrestudent(
$person_id,
$studiengang_kz,
$ausbildungscode,
$anmerkung,
$foerderrelevant
)
{
// Prestudent anlegen
$data = [
'aufmerksamdurch_kurzbz' => 'k.A.',
'person_id' => $person_id,
'studiengang_kz' => $studiengang_kz,
'ausbildungcode' => $ausbildungscode,
'anmerkung' => $anmerkung,
'reihungstestangetreten' => false,
'bismelden' => true,
'foerderrelevant' => $foerderrelevant,
'insertamum' => date('c'),
'insertvon' => getAuthUID()
];
// Wenn die Person schon im System erfasst ist, dann die ZGV des Datensatzes uebernehmen
$this->_ci->PrestudentModel->addSelect('public.tbl_prestudent.*, public.tbl_person.vorname, public.tbl_person.nachname');
$this->_ci->PrestudentModel->addJoin('public.tbl_person', 'person_id');
$this->_ci->PrestudentModel->addOrder('zgvmas_code');
$this->_ci->PrestudentModel->addOrder('zgv_code', 'DESC');
$this->_ci->PrestudentModel->addLimit(1);
$result = $this->_ci->PrestudentModel->loadWhere([
'person_id' => $person_id,
'zgv_code IS NOT NULL' => null
]);
if (isError($result)) return $result;
if (hasData($result)) {
$prestudent = getData($result)[0];
if ($prestudent->zgv_code) {
$data['zgv_code'] = $prestudent->zgv_code;
$data['zgvort'] = $prestudent->zgvort;
$data['zgvdatum'] = $prestudent->zgvdatum;
$data['zgvmas_code'] = $prestudent->zgvmas_code;
$data['zgvmaort'] = $prestudent->zgvmaort;
$data['zgvmadatum'] = $prestudent->zgvmadatum;
}
}
// Prestudent speichern
return $this->_ci->PrestudentModel->insert($data);
}
/**
* Sets first status of a prestudent.!
* @return object success or error
*/
public function setFirstStatus(
$prestudent_id,
$status_kurzbz,
$studiensemester_kurzbz,
$ausbildungssemester = null,
$orgform_kurzbz = null,
$studienplan_id = null
)
{
// Prestudent Rolle Anlegen
$data = [
'prestudent_id' => $prestudent_id,
'status_kurzbz' => $status_kurzbz,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'ausbildungssemester' => $ausbildungssemester ?: 0,
'orgform_kurzbz' => $orgform_kurzbz ?: null,
'studienplan_id' => $studienplan_id ?: null,
'datum' => date('Y-m-d'),
'insertamum' => date('c'),
'insertvon' => getAuthUID()
];
return $this->_ci->PrestudentstatusModel->insert($data);
}
public function setAbbrecher(
$prestudent_id,
$studiensemester_kurzbz,
@@ -603,9 +687,6 @@ class PrestudentLib
$now = date('c');
$today = date('Y-m-d');
$jahr = mb_substr($studiensemester_kurzbz, 4, 2);
// Genererate Personenkennzeichen
$personenkennzeichen = $this->_ci->StudentModel->generateMatrikelnummer2(
$student_data->studiengang_kz,
@@ -615,8 +696,9 @@ class PrestudentLib
if (isError($personenkennzeichen))
return $personenkennzeichen;
$personenkennzeichen = getData($personenkennzeichen);
$jahr = mb_substr($personenkennzeichen, 0, 2);
// Generate UID
$uid = $this->_ci->StudentModel->generateUID(
$student_data->kurzbz,
@@ -641,7 +723,7 @@ class PrestudentLib
// Generate Alias
$alias = '';
$alias = null;
if (!defined('GENERATE_ALIAS_STUDENT')
|| GENERATE_ALIAS_STUDENT === true
) {
@@ -889,6 +971,155 @@ class PrestudentLib
);
}
/**
* Creates an incoming, saves necessary data for an incoming.
* @param $prestudent_id existing prestudent, for which incoming entry is created
* @param $studiengang_kz Studiengang assigned to incoming
* @param $studiensemester_kurzbz start semester for incoming
* @return object success if incoming successfully saved, or error
*/
public function setFirstIncoming($prestudent_id, $studiengang_kz, $studiensemester_kurzbz, $orgform_kurzbz, $studienplan_id)
{
// Verband and Ausbildungssemester for incoming
$authUID = getAuthUID();
$incomingVerband = 'I';
$incomingAusbildungssemester = '0';
// get prestudent
$this->_ci->PrestudentModel->addJoin('public.tbl_person p', 'person_id');
$this->_ci->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz');
$result = $this->_ci->PrestudentModel->load($prestudent_id);
if (isError($result)) return $result;
if (!hasData($result)) return error('No prestudent');
$student_data = getData($result)[0];
$result = $this->setFirstStatus(
$prestudent_id,
$this->_ci->PrestudentstatusModel::STATUS_INCOMING,
$studiensemester_kurzbz,
$incomingAusbildungssemester,
$orgform_kurzbz,
$studienplan_id
);
if (isError($result)) return $result;
if (!hasData($result)) return error('Error when adding prestudentstatus');
// generate Personenkennzeichen
$result = $this->_ci->StudentModel->generateMatrikelnummer2($studiengang_kz, $studiensemester_kurzbz);
if (isError($result)) return $result;
if (!hasData($result)) return error('No personenkennzeichen could be generated');
$personenkennzeichen = getData($result);
$jahr = mb_substr($personenkennzeichen, 0, 2);
$stg = mb_substr($personenkennzeichen, 3, 4);
$nachname_clean = mb_strtolower(sanitizeProblemChars($student_data->nachname));
$vorname_clean = mb_strtolower(sanitizeProblemChars($student_data->vorname));
$nachname_clean = str_replace(' ','_', $nachname_clean);
$vorname_clean = str_replace(' ','_', $vorname_clean);
// get Studiengang data
$result = $this->_ci->StudiengangModel->load(ltrim($stg, '0'));
if (isError($result)) return $result;
if (!hasData($result)) return error('No Studiengang');
$stgObj = getData($result)[0];
// gernerate uid
$result = $this->_ci->StudentModel->generateUID($stgObj->kurzbz, $jahr, $stgObj->typ, $personenkennzeichen, $vorname_clean, $nachname_clean);
if (isError($result)) return $result;
if (!hasData($result)) return error("UID could not be generated");
$uid = getData($result);
//Benutzerdatensatz anlegen
$benutzer = [
'uid' => $uid,
'person_id' => $student_data->person_id,
'aktiv' => true,
'aktivierungscode' => $this->_ci->BenutzerModel->generateActivationkey()
];
// Generate Alias
$alias = '';
if (!defined('GENERATE_ALIAS_STUDENT') || GENERATE_ALIAS_STUDENT === true)
{
$result = $this->_ci->BenutzerModel->generateAliasFromName($student_data->vorname, $student_data->nachname);
if (isError($result))
return $result;
$alias = getData($result);
}
$benutzer['alias'] = $alias;
$benutzer['insertamum'] = date('Y-m-d H:i:s');
$benutzer['insertvon'] = $authUID;
$result = $this->_ci->BenutzerModel->insert($benutzer);
if (isError($result)) return $result;
// Studentendatensatz anlegen
$student = [
'student_uid' => $uid,
'matrikelnr' => $personenkennzeichen,
'prestudent_id' => $prestudent_id,
'studiengang_kz' => $studiengang_kz,
'semester' => $incomingAusbildungssemester,
'verband' => $incomingVerband,
'gruppe' => ' '
];
$result = $this->_ci->LehrverbandModel->loadWhere([
'studiengang_kz' => $student['studiengang_kz'],
'semester' => $student['semester'],
'verband' => $student['verband'],
'gruppe' => $student['gruppe']
]);
if (isError($result)) return $result;
if (!hasData($result))
{
// Add Lehrverband if it does not exist
$result = $this->_ci->LehrverbandModel->insert([
'studiengang_kz' => $student_data->studiengang_kz,
'semester' => $student['semester'],
'verband' => $student['verband'],
'gruppe' => $student['gruppe'],
'bezeichnung' => 'Incoming',
'aktiv' => true
]);
if (isError($result)) return $result;
}
// add student
$student['insertamum'] = date('Y-m-d H:i:s');
$student['insertvon'] = $authUID;
$result = $this->_ci->StudentModel->insert($student);
if (isError($result)) return $result;
// Add Studentlehrverband
$result = $this->_ci->StudentlehrverbandModel->insert([
'student_uid' => $uid,
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'studiengang_kz' => $student_data->studiengang_kz,
'semester' => $incomingAusbildungssemester,
'verband' => $incomingVerband,
'gruppe' => ' ',
'insertamum' => date('Y-m-d H:i:s'),
'insertvon' => $authUID
]);
if (isError($result))
return $result;
return success($prestudent_id);
}
protected function setBasic($authUID, $now, $status_kurzbz, $prestudent_id, $studiensemester_kurzbz, $ausbildungssemester, $statusgrund_id = null)
{
$result = $this->_ci->PrestudentstatusModel->getLastStatus($prestudent_id);
+53
View File
@@ -263,6 +263,59 @@ class ProfilLib{
$element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN;
return $element;
}, $mailverteiler_res);
$this->ci->load->model("crm/Student_model", "StudentModel");
$this->ci->StudentModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_student.student_uid");
$this->ci->StudentModel->addJoin("tbl_person", "tbl_benutzer.person_id = tbl_person.person_id");
$this->ci->StudentModel->addJoin("tbl_studiengang", "tbl_student.studiengang_kz = tbl_studiengang.studiengang_kz");
$this->ci->StudentModel->addSelect("matr_nr, semester, verband, gruppe, kurzbzlang");
$studentResult = $this->ci->StudentModel->loadWhere(["student_uid" => $uid]);
if (isError($studentResult)) {
return error(getData($studentResult));
}
$studentResultData = getData($studentResult);
$studentData = null;
if (is_array($studentResultData) && count($studentResultData)) {
$studentData = $studentResultData[0];
}
if ($studentData && $studentData->matr_nr) {
$this->ci->load->library("phrasesLib", ["profil"], "phrases");
$standardCourseVerteiler = trim($studentData->kurzbzlang) . "_STD";
$mailverteiler_res[] = [
"beschreibung" => $this->ci->phrases->t('profil', 'alleStudentenVon') . " " . $standardCourseVerteiler,
"gruppe_kurzbz" => $standardCourseVerteiler,
"mailto" => "mailto:" . strtolower($standardCourseVerteiler) . "@" . DOMAIN,
];
$semesterVerteiler = trim($studentData->kurzbzlang) . trim($studentData->semester);
$mailverteiler_res[] = [
"beschreibung" => $this->ci->phrases->t('profil', 'alleStudentenVon') . " " . $semesterVerteiler,
"gruppe_kurzbz" => $semesterVerteiler,
"mailto" => "mailto:" . strtolower($semesterVerteiler) . "@" . DOMAIN,
];
if ($studentData->verband && strlen(trim($studentData->verband))) {
$verbandVerteiler = $semesterVerteiler . trim($studentData->verband);
$mailverteiler_res[] = [
"beschreibung" => $this->ci->phrases->t('profil', 'alleStudentenVon') . " " . $verbandVerteiler,
"gruppe_kurzbz" => $verbandVerteiler,
"mailto" => "mailto:" . strtolower($verbandVerteiler) . "@" . DOMAIN,
];
if ($studentData->gruppe && strlen(trim($studentData->gruppe))) {
$gruppeVerteiler = $verbandVerteiler . trim($studentData->gruppe);
$mailverteiler_res[] = [
"beschreibung" => $this->ci->phrases->t('profil', 'alleStudentenVon') . " " . $gruppeVerteiler,
"gruppe_kurzbz" => $gruppeVerteiler,
"mailto" => "mailto:" . strtolower($gruppeVerteiler) . "@" . DOMAIN,
];
}
}
}
return $mailverteiler_res;
}
@@ -49,7 +49,7 @@ class DashboardLib
public function getMergedConfig($dashboard_id, $uid)
{
$defaultconfig = $this->getDefaultConfig($dashboard_id, $uid);
$defaultconfig = $this->getDefaultConfig($dashboard_id);
$userconfig = $this->getUserConfig($dashboard_id, $uid);
$mergedconfig = array_replace_recursive($defaultconfig, $userconfig);
@@ -57,14 +57,31 @@ class DashboardLib
return $mergedconfig;
}
public function getDefaultConfig($dashboard_id, $uid)
public function getDefaultConfig($dashboard_id)
{
$res_presets = $this->_ci->DashboardPresetModel->getPresets($dashboard_id, $uid);
$funktion_kurzbzs = [];
$rights = $this->_ci->permissionlib->getAccessRights();
if ($rights)
$funktion_kurzbzs = array_unique(array_map(function ($right) {
return $right->funktion_kurzbz;
}, $rights));
$this->_ci->DashboardPresetModel->db
->group_start()
->where_in('funktion_kurzbz', $funktion_kurzbzs)
->or_where('funktion_kurzbz IS NULL')
->group_end();
$this->_ci->DashboardPresetModel->addOrder('funktion_kurzbz', 'DESC');
$result = $this->_ci->DashboardPresetModel->loadWhere([
'dashboard_id' => $dashboard_id
]);
$defaultconfig = array();
if (hasData($res_presets))
if (hasData($result))
{
$presets = getData($res_presets);
$presets = getData($result);
foreach ($presets as $presetobj)
{
$preset = json_decode($presetobj->preset, true);
@@ -137,8 +154,10 @@ class DashboardLib
$dashboard = $this->getDashboardByKurzbz($dashboard_kurzbz);
$funktion_kurzbz = ($section === self::SECTION_IF_FUNKTION_KURZBZ_IS_NULL) ? null : $section;
$result = $this->_ci->DashboardPresetModel
->getPresetByDashboardAndFunktion($dashboard->dashboard_id, $funktion_kurzbz);
$result = $this->_ci->DashboardPresetModel->loadWhere([
'dashboard_id' => $dashboard->dashboard_id,
'funktion_kurzbz' => $funktion_kurzbz
]);
if (hasData($result))
{
@@ -195,11 +214,11 @@ class DashboardLib
{
foreach ($addwigets as $widget)
{
if(!isset($widget->widgetid))
if(!isset($widget['widgetid']))
{
$widget->widgetid = $this->generateWidgetId($dashboard_kurzbz);
$widget['widgetid'] = $this->generateWidgetId($dashboard_kurzbz);
}
$this->addWidgetToWidgets($widgets, $section, $widget, $widget->widgetid);
$this->addWidgetToWidgets($widgets, $section, $widget, $widget['widgetid']);
}
}
@@ -3,6 +3,7 @@ namespace vertragsbestandteil;
use Exception;
use vertragsbestandteil\VertragsbestandteilStunden;
use vertragsbestandteil\VertragsbestandteilLohnguide;
/**
* Description of VertragsbestandteilFactory
@@ -22,6 +23,7 @@ class VertragsbestandteilFactory
const VERTRAGSBESTANDTEIL_URLAUBSANSPRUCH = 'urlaubsanspruch';
const VERTRAGSBESTANDTEIL_ZEITAUFZEICHNUNG = 'zeitaufzeichnung';
const VERTRAGSBESTANDTEIL_LEHRE = 'lehre';
const VERTRAGSBESTANDTEIL_LOHNGUIDE = 'lohnguide';
public static function getVertragsbestandteil($data, $fromdb=false)
{
@@ -69,6 +71,11 @@ class VertragsbestandteilFactory
$vertragsbestandteil = new VertragsbestandteilZeitaufzeichnung();
$vertragsbestandteil->hydrateByStdClass($data, $fromdb);
break;
case self::VERTRAGSBESTANDTEIL_LOHNGUIDE:
$vertragsbestandteil = new VertragsbestandteilLohnguide();
$vertragsbestandteil->hydrateByStdClass($data, $fromdb);
break;
default:
throw new Exception('Unknown vertragsbestandteiltyp_kurzbz '
@@ -127,6 +134,12 @@ class VertragsbestandteilFactory
$vertragsbestandteildbmodel = $CI->VertragsbestandteilZeitaufzeichnung_model;
break;
case self::VERTRAGSBESTANDTEIL_LOHNGUIDE:
$CI->load->model('vertragsbestandteil/VertragsbestandteilLohnguide_model',
'VertragsbestandteilLohnguide_model');
$vertragsbestandteildbmodel = $CI->VertragsbestandteilLohnguide_model;
break;
default:
throw new Exception('Unknown vertragsbestandteil_kurzbz '
. $vertragsbestandteil_kurzbz);
@@ -10,6 +10,7 @@ require_once __DIR__ . '/VertragsbestandteilKuendigungsfrist.php';
require_once __DIR__ . '/VertragsbestandteilUrlaubsanspruch.php';
require_once __DIR__ . '/VertragsbestandteilFreitext.php';
require_once __DIR__ . '/VertragsbestandteilKarenz.php';
require_once __DIR__ . '/VertragsbestandteilLohnguide.php';
require_once __DIR__ . '/VertragsbestandteilFactory.php';
require_once __DIR__ . '/OverlapChecker.php';
@@ -0,0 +1,155 @@
<?php
namespace vertragsbestandteil;
use vertragsbestandteil\Vertragsbestandteil;
use vertragsbestandteil\VertragsbestandteilFactory;
class VertragsbestandteilLohnguide extends Vertragsbestandteil
{
protected $stellenbezeichnung;
protected $vordienstzeit;
protected $fachrichtung_kurzbz;
protected $modellstelle_kurzbz;
protected $kommentar_person;
protected $kommentar_modellstelle;
public function __construct()
{
parent::__construct();
$this->setVertragsbestandteiltyp_kurzbz(
VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_LOHNGUIDE);
}
public function getStellenbezeichnung()
{
return $this->stellenbezeichnung;
}
public function setStellenbezeichnung($stellenbezeichnung): self
{
$this->markDirty('stellenbezeichnung', $this->stellenbezeichnung, $stellenbezeichnung);
$this->stellenbezeichnung = $stellenbezeichnung;
return $this;
}
public function getVordienstzeit()
{
return $this->vordienstzeit;
}
public function setVordienstzeit($vordienstzeit): self
{
$this->markDirty('vordienstzeit', $this->vordienstzeit, $vordienstzeit);
$this->vordienstzeit = $vordienstzeit;
return $this;
}
public function getFachrichtung_kurzbz()
{
return $this->fachrichtung_kurzbz;
}
public function setFachrichtung_kurzbz($fachrichtung_kurzbz): self
{
$this->markDirty('fachrichtung_kurzbz', $this->fachrichtung_kurzbz, $fachrichtung_kurzbz);
$this->fachrichtung_kurzbz = $fachrichtung_kurzbz;
return $this;
}
public function getModellstelle_kurzbz()
{
return $this->modellstelle_kurzbz;
}
public function setModellstelle_kurzbz($modellstelle_kurzbz): self
{
$this->markDirty('modellstelle_kurzbz', $this->modellstelle_kurzbz, $modellstelle_kurzbz);
$this->modellstelle_kurzbz = $modellstelle_kurzbz;
return $this;
}
public function getKommentar_person()
{
return $this->kommentar_person;
}
public function setKommentar_person($kommentar_person): self
{
$this->markDirty('kommentar_person', $this->kommentar_person, $kommentar_person);
$this->kommentar_person = $kommentar_person;
return $this;
}
public function getKommentar_modellstelle()
{
return $this->kommentar_modellstelle;
}
public function setKommentar_modellstelle($kommentar_modellstelle): self
{
$this->markDirty('kommentar_modellstelle', $this->kommentar_modellstelle, $kommentar_modellstelle);
$this->kommentar_modellstelle = $kommentar_modellstelle;
return $this;
}
public function hydrateByStdClass($data, $fromdb=false)
{
parent::hydrateByStdClass($data, $fromdb);
$this->fromdb = $fromdb;
isset($data->fachrichtung_kurzbz) && $this->setFachrichtung_kurzbz($data->fachrichtung_kurzbz);
isset($data->stellenbezeichnung) && $this->setStellenbezeichnung($data->stellenbezeichnung);
isset($data->vordienstzeit) && $this->setVordienstzeit($data->vordienstzeit);
isset($data->modellstelle_kurzbz) && $this->setModellstelle_kurzbz($data->modellstelle_kurzbz);
isset($data->kommentar_person) && $this->setKommentar_person($data->kommentar_person);
isset($data->kommentar_modellstelle) && $this->setKommentar_modellstelle($data->kommentar_modellstelle);
$this->fromdb = false;
}
public function toStdClass(): \stdClass
{
$tmp = array(
'vertragsbestandteil_id' => $this->getVertragsbestandteil_id(),
'stellenbezeichnung' => $this->getStellenbezeichnung(),
'vordienstzeit' => $this->getVordienstzeit(),
'fachrichtung_kurzbz' => $this->getFachrichtung_kurzbz(),
'modellstelle_kurzbz' => $this->getModellstelle_kurzbz(),
'kommentar_person' => $this->getKommentar_person(),
'kommentar_modellstelle' => $this->getKommentar_modellstelle(),
);
$tmp = array_filter($tmp, function($k) {
return in_array($k, $this->modifiedcolumns);
}, ARRAY_FILTER_USE_KEY);
return (object) $tmp;
}
public function __toString()
{
$txt = <<<EOTXT
modellstelle_kurzbz: {$this->getModellstelle_kurzbz()}
EOTXT;
return parent::__toString() . $txt;
}
/* public function validate()
{
if( !(filter_var($this->tage, FILTER_VALIDATE_INT,
array(
'options' => array(
'min_range' => 1,
'max_range' => 50
)
)
)) ) {
$this->validationerrors[] = 'Urlaubsanspruch muss eine Tagesanzahl im Bereich 1 bis 50 sein.';
}
return parent::validate();
} */
}
@@ -402,6 +402,26 @@ class Vertrag_model extends DB_Model
return $this->loadWhere(array('mitarbeiter_uid' => $mitarbeiter_uid, 'lehreinheit_id' => $lehreinheit_id));
}
public function getVertragById($vertrag_id)
{
$this->addSelect(
'tbl_vertrag.vertrag_id, vertragstyp_kurzbz, vertragsstunden, vertragsstunden_studiensemester_kurzbz, status.vertragsstatus_kurzbz,
status.bezeichnung AS vertragsstatus, tbl_vertrag.betrag, lema.semesterstunden, lema.stundensatz'
);
$this->addJoin('lehre.tbl_lehreinheitmitarbeiter lema', 'tbl_vertrag.vertrag_id = lema.vertrag_id', 'LEFT');
$this->addJoin('
(
SELECT DISTINCT ON(vst.vertrag_id) vst.vertrag_id,
bezeichnung,
tbl_vertragsstatus.vertragsstatus_kurzbz
FROM lehre.tbl_vertrag_vertragsstatus vst
JOIN lehre.tbl_vertragsstatus USING(vertragsstatus_kurzbz)
ORDER BY vst.vertrag_id, datum DESC
) as status', 'status.vertrag_id = lehre.tbl_vertrag.vertrag_id', 'LEFT');
return $this->loadWhere(['tbl_vertrag.vertrag_id' => $vertrag_id]);
}
public function cancelVertrag($vertrag_id, $mitarbeiter_uid)
{
$vertrag = $this->load($vertrag_id);
@@ -470,6 +490,175 @@ class Vertrag_model extends DB_Model
return $bezeichnung;
}
/**
* Loads all Contracts of a Person
* @param $person_id
* @return array of objects
*/
public function loadContractsOfPerson($person_id)
{
$query = "
SELECT
*,
tbl_vertrag.bezeichnung as bezeichnung,
tbl_vertragstyp.bezeichnung as vertragstyp_bezeichnung,
tbl_vertrag.vertragsdatum,
(SELECT bezeichnung FROM lehre.tbl_vertragsstatus
JOIN lehre.tbl_vertrag_vertragsstatus USING(vertragsstatus_kurzbz)
WHERE vertrag_id=tbl_vertrag.vertrag_id ORDER BY datum desc limit 1) as status, anmerkung,
CASE
WHEN EXISTS (
SELECT 1
FROM lehre.tbl_vertrag_vertragsstatus
WHERE vertrag_id = tbl_vertrag.vertrag_id
AND vertragsstatus_kurzbz = 'abgerechnet'
) THEN true
ELSE false
END AS isAbgerechnet
FROM
lehre.tbl_vertrag
LEFT JOIN lehre.tbl_vertragstyp USING(vertragstyp_kurzbz)
WHERE person_id= ?";
return $this->execQuery($query, array($person_id));
}
/**
* Loads all Contracts of a Person that are not assigned yet
* @param $person_id
* @return array of objects
*/
public function loadContractsOfPersonNotAssigned($person_id)
{
$query = "
SELECT
'Lehrauftrag' as type,
lehreinheit_id,
mitarbeiter_uid,
null as pruefung_id,
null as projektarbeit_id,
(tbl_lehreinheitmitarbeiter.semesterstunden*tbl_lehreinheitmitarbeiter.stundensatz) as betrag1,
tbl_lehreinheit.studiensemester_kurzbz,
null as betreuerart_kurzbz,
( SELECT
upper(tbl_studiengang.typ || tbl_studiengang.kurzbz) || tbl_lehrveranstaltung.semester || '-' || tbl_lehrveranstaltung.kurzbz || '-' || tbl_lehreinheit.lehrform_kurzbz
FROM
lehre.tbl_lehrveranstaltung
JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE
lehrveranstaltung_id=tbl_lehreinheit.lehrveranstaltung_id)
as bezeichnung
FROM
lehre.tbl_lehreinheitmitarbeiter
JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
WHERE
mitarbeiter_uid IN (SELECT uid FROM public.tbl_benutzer WHERE person_id=?)
AND vertrag_id IS NULL
UNION
SELECT
'Betreuung' as type,
tbl_projektarbeit.lehreinheit_id as lehreinheit_id,
null as mitarbeiter_uid,
null::integer as pruefung_id,
projektarbeit_id,
(tbl_projektbetreuer.stunden*tbl_projektbetreuer.stundensatz) as betrag1,
tbl_lehreinheit.studiensemester_kurzbz,
tbl_projektbetreuer.betreuerart_kurzbz,
(SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid)
as bezeichnung
FROM
lehre.tbl_projektbetreuer
JOIN lehre.tbl_projektarbeit USING(projektarbeit_id)
JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
WHERE
tbl_projektbetreuer.person_id=?
AND vertrag_id IS NULL
";
return $this->execQuery($query, array($person_id, $person_id));
}
/**
* Loads all Contracts of a Person that are assigned yet
* @param $person_id, $vertrag_id
* @return array of objects
*/
public function loadContractsOfPersonAssigned($person_id, $vertrag_id)
{
$query = "
SELECT
'Lehrauftrag' as type,
lehreinheit_id,
mitarbeiter_uid,
null as pruefung_id,
null as projektarbeit_id,
(tbl_lehreinheitmitarbeiter.semesterstunden * tbl_lehreinheitmitarbeiter.stundensatz) as betrag,
tbl_lehreinheit.studiensemester_kurzbz,
null as betreuerart_kurzbz,
( SELECT
upper(tbl_studiengang.typ || tbl_studiengang.kurzbz) || tbl_lehrveranstaltung.semester || '-' || tbl_lehrveranstaltung.kurzbz || '-' || tbl_lehreinheit.lehrform_kurzbz
FROM
lehre.tbl_lehrveranstaltung
JOIN public.tbl_studiengang USING(studiengang_kz)
WHERE
lehrveranstaltung_id=tbl_lehreinheit.lehrveranstaltung_id)
as bezeichnung, vertrag_id
FROM
lehre.tbl_lehreinheitmitarbeiter
JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
WHERE
mitarbeiter_uid IN (SELECT uid FROM public.tbl_benutzer WHERE person_id=?)
AND vertrag_id = ?
UNION
SELECT
'Betreuung' as type,
tbl_projektarbeit.lehreinheit_id as lehreinheit_id,
null as mitarbeiter_uid,
null::integer as pruefung_id,
projektarbeit_id,
(tbl_projektbetreuer.stunden * tbl_projektbetreuer.stundensatz) as betrag,
tbl_lehreinheit.studiensemester_kurzbz,
tbl_projektbetreuer.betreuerart_kurzbz,
(SELECT nachname || ' ' || vorname FROM public.tbl_person JOIN public.tbl_benutzer USING(person_id) WHERE uid=tbl_projektarbeit.student_uid)
as bezeichnung, vertrag_id
FROM
lehre.tbl_projektbetreuer
JOIN lehre.tbl_projektarbeit USING(projektarbeit_id)
JOIN lehre.tbl_lehreinheit USING(lehreinheit_id)
WHERE
tbl_projektbetreuer.person_id=?
AND vertrag_id = ?
";
return $this->execQuery($query, array($person_id, $vertrag_id, $person_id, $vertrag_id));
}
/**
* Returns all stati of a contract
*
* @param $vertrag_id
* @return array
*/
public function getStatiOfContract($vertrag_id)
{
$query = "
SELECT
*,
tbl_vertrag_vertragsstatus.datum,
tbl_vertrag_vertragsstatus.insertamum,
tbl_vertrag_vertragsstatus.updateamum
FROM
lehre.tbl_vertrag_vertragsstatus
JOIN lehre.tbl_vertragsstatus USING(vertragsstatus_kurzbz)
WHERE
tbl_vertrag_vertragsstatus.vertrag_id = ?
ORDER BY tbl_vertrag_vertragsstatus.datum DESC";
return $this->execQuery($query, array($vertrag_id));
}
private function _updateVertragRelevant($vertrag_id)
{
$this->LehreinheitmitarbeiterModel->update(
@@ -11,4 +11,5 @@ class Vertragstyp_model extends DB_Model
$this->dbTable = 'lehre.tbl_vertragstyp';
$this->pk = 'vertragstyp_kurzbz';
}
}
@@ -190,4 +190,6 @@ class Vertragvertragsstatus_model extends DB_Model
return $this->loadWhere($condition);
}
}

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