Compare commits

...

1966 Commits

Author SHA1 Message Date
ma0048 0cfae22d3d anrechnungen schreibberechtigt ueberpruefungen backendseitig 2025-03-04 15:48:06 +01:00
kindlm dd2a13d92d Korrektur DMS-Link 2025-02-19 18:02:30 +01:00
kindlm 2946d59e7a Merge remote-tracking branch 'origin/master' 2025-02-19 18:01:46 +01:00
Andreas Österreicher 7c57a145bd Merge branch 'hotfix-55802/Composer_dead_github_repository' 2025-02-19 15:49:48 +01:00
Andreas Österreicher 661be92fed Merge branch 'bug-54831/Logs_Viewer_Filter_Error' 2025-02-19 15:40:25 +01:00
Paolo 37f86f651e Fixed string casting of the condition for the filter component
Fixed CSS for the error box in the logs viewer filter
2025-02-19 15:37:51 +01:00
Andreas Österreicher bbd70749fe Projektexport angepasst damit die Überschriften aufgrund der
Beschreibung erstellt werden anstatt auf Basis der Bezeichnung da diese
öfter abgeschnitten werden und es dadurch gleich benannte Spalten gibt
und dadurch eine nicht korrekt angezeigt wird
2025-02-19 11:41:46 +01:00
kindlm a557cd8d7c Merge remote-tracking branch 'origin/master' 2025-02-17 16:50:26 +01:00
kindlm b89eef0525 Minor Bug/Typo-fixes in testtool
- Soundtest aus testseite.php ausgeblendet
- Studiengangsname nach Login aus Studienordnung
- Bei Übersicht wird nun auch Text angezeigt, wenn ein Bild ausgegeben wird
2025-02-17 16:50:07 +01:00
Andreas Österreicher 470eac7d3c Merge branch 'feature-46784/cronjob_reihungstest_warteliste_anpassen' 2025-02-14 08:18:16 +01:00
Andreas Österreicher f25a969a6b Merge branch 'feature-33683/digi_anw_core_ss2025' 2025-02-11 13:19:30 +01:00
Johann Hoffmann deea005f5b recommit anw related core changes without wrongfully merged branches tail of feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2025-02-10 14:24:15 +01:00
Andreas Österreicher 40d2a657c6 Merge branch 'feature-28394/zeiterfassung_50_tage_ansicht_als_vorgesetzter_fuer_mitarbeiter' 2025-02-05 14:07:44 +01:00
Andreas Österreicher a1841a0071 Merge branch 'Monika70-AnzahlStudenten' 2025-02-04 17:05:17 +01:00
Andreas Österreicher 1436d12a53 Added Default Config NICHT_ZUGELASSENE 2025-02-04 17:03:19 +01:00
Andreas Österreicher b177420cb1 Merge branch 'AnzahlStudenten' of https://github.com/Monika70/FHC-Core into Monika70-AnzahlStudenten 2025-02-04 16:56:44 +01:00
Andreas Österreicher faeb0fbf4b Merge branch 'master' of github.com:FH-Complete/FHC-Core 2025-02-04 16:48:27 +01:00
Andreas Österreicher 749c147f8e Phrase für Unruly angepasst 2025-02-04 16:48:01 +01:00
ma0048 c56c71a508 - fixed bug 2025-02-04 12:05:15 +01:00
kindlm 0059bc11f3 Merge remote-tracking branch 'origin/master' 2025-02-03 10:42:06 +01:00
kindlm fbd02e02f1 Rufzeichen bei Phrase entfernt 2025-02-03 10:41:41 +01:00
Andreas Österreicher ecbc1c8d09 Merge branch 'sonstiges-55231/bfi-anrechnung-infobox-ausblenden' 2025-01-30 14:56:24 +01:00
Andreas Österreicher 07194cfaff - Index für lehre.tbl_anrechnungen hinzugefügt um Ladezeiten zu verbessern
- Bugfix fuer Detailseite der Lehrenden
2025-01-30 14:54:16 +01:00
Cristina 3eb1f7b06b Added array 'display_infobox' to config file anrechnung.php and adapted code to display only if set to true 2025-01-30 12:08:28 +01:00
Cristina f2917b9ed7 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-01-30 10:23:56 +01:00
Szabo Mónika 51ba1d3fb9 Update lehrstunde.rdf.php
Studenten mit den in der vilesci.config.inc.php hinterlegten Noten sollten nicht zur AnzahlStudenten im Tempus gezählt werden.
Config Eintrag:
//Studierende mit diesen Noten werden von der AnzahlStudenten im Tempus abgezogen
define('NICHT_ZUGELASSENE',serialize(array(6, 20, NULL)));
2025-01-30 09:35:06 +01:00
Harald Bamberger 5b12e5eea7 Merge branch 'feature-5534/Gehaltsgraph_Valorisierung' 2025-01-28 18:37:18 +01:00
Harald Bamberger e068abd124 rename functions since they manipulate data for using it in a chart 2025-01-28 18:35:25 +01:00
Harald Bamberger d7cbe475bf Merge branch 'master' into feature-5534/Gehaltsgraph_Valorisierung 2025-01-28 17:39:19 +01:00
Harald Bamberger 402691b5cd Merge branch 'feature-53903/PV21_Valorisierungs_akutelle_Liste_ausgeben_ohne_Valorisierungskonfiguration' 2025-01-28 16:40:35 +01:00
Harald Bamberger 6a2a4c22b3 Merge branch 'master' into feature-53903/PV21_Valorisierungs_akutelle_Liste_ausgeben_ohne_Valorisierungskonfiguration 2025-01-28 16:14:39 +01:00
Paolo 0426e3498f Hotfix: replaced the dead github repository from https://github.com/tomazdragar/SimpleCropper.git to https://github.com/deveshsinghal22/SimpleCropper.git 2025-01-28 15:45:40 +01:00
Cristina 9a4211c980 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2025-01-28 13:58:14 +01:00
Harald Bamberger 4cd1bc3d63 Merge branch 'feature-18073/No-Reply-for-Sanchomails' 2025-01-28 13:05:53 +01:00
Harald Bamberger 4258e60b8b Merge branch 'master' into feature-18073/No-Reply-for-Sanchomails 2025-01-28 13:03:53 +01:00
Harald Bamberger 7f6744047f check in ci mail config if constants in global config are defined 2025-01-28 11:26:01 +01:00
Harald Bamberger 39c2e44719 sancho default sender konfigurierbar machen 2025-01-28 10:22:30 +01:00
Harald Bamberger d6abfbbc23 fix typo 2025-01-23 16:33:03 +01:00
Harald Bamberger 87220e1789 move tbl_valorisierung_* to core since they are used in vertragsbestandteillib and gehaltsbestandteillib 2025-01-23 16:13:47 +01:00
Paolo d2cce86131 - controllers/api/frontend/v1/Filter->applyFilterFields validate filterFields as an array
- FilterCmptLib->applyFilterFields evaluate each elements of filterFields as an array
2025-01-23 15:40:56 +01:00
Harald Bamberger c5d79f750e add parameter withvalorisationhistory to use valorisation history or not 2025-01-23 15:31:17 +01:00
Harald Bamberger af79090de0 modify to consider valorisation history, TODO cleanup valorisation tables dependency on FHC-Core-Personalverwaltung Extension 2025-01-22 17:18:22 +01:00
Harald Bamberger 8ce4b452ec use encryption parameters in lamda function and return replacement string 2025-01-22 17:16:47 +01:00
Harald Bamberger 4c46a5f5c7 modify regex to match optional table alias and ignore column alias equal to column name 2025-01-22 15:09:20 +01:00
Harald Bamberger 781e2dbd15 Merge branch 'feature-54841/DVs_Abhaengigkeit_zu_SAP_Extension_beseitigen' 2025-01-21 14:29:05 +01:00
Harald Bamberger d9532d7607 Merge branch 'master' into feature-54841/DVs_Abhaengigkeit_zu_SAP_Extension_beseitigen 2025-01-21 13:40:26 +01:00
Werner Masik 1853e44cf3 add valorized data for chart display 2025-01-21 12:58:09 +01:00
Alexei Karpenko e65322965f sancho mail: added config for haeder/footer image path, renamed custom mail config entries to sancho mail config entries, images are always attached inline (when using Code Igniter) 2025-01-20 16:24:56 +01:00
Harald Bamberger 899c36c52c default sancho image comes from global config now 2025-01-20 15:10:52 +01:00
Harald Bamberger 71d1a808f8 Merge branch 'master' into feature-18073/No-Reply-for-Sanchomails 2025-01-20 13:36:17 +01:00
Andreas Österreicher 1489706027 Merge branch 'Monika70-Export' 2025-01-16 13:22:51 +01:00
Andreas Österreicher 103df5afe5 Merge branch 'Export' of https://github.com/Monika70/FHC-Core into Monika70-Export 2025-01-16 13:21:14 +01:00
Andreas Österreicher ba2b41f63a Merge branch 'feature-55289/pep_fine_tuning' 2025-01-16 13:12:26 +01:00
ma0048 f381ef229e - index tbl_lehrveranstaltung_faktor_lvid hinzugefuegt
- sortierung gleichgezogen
2025-01-16 10:38:01 +01:00
Alexei Karpenko ece4f4a8b5 sancho mails: enabled removing of header/footer and custom header/footer images in code igniter code, legacy code: global ids for images are created only if config is set 2025-01-15 16:52:11 +01:00
Szabo Mónika f1234c0b99 Update studentenexportextended.xls.php
Zusätzliche Spalte Person_id hinzufügen
2025-01-15 14:37:06 +01:00
Harald Bamberger fd67974d55 fix typo 2025-01-15 13:35:58 +01:00
Harald Bamberger a1a9e96bc0 permission basis/gehaelter 2025-01-15 13:34:16 +01:00
Andreas Österreicher aab0f339ab Merge branch 'feature-55316/international_skills_credits_entfernen_neue_massnahmen' 2025-01-15 13:06:04 +01:00
Harald Bamberger d4bb06c4f6 Merge branch 'feature-54920/DB_Model_encrypted_columns_spaltenname_enthaelt_anderen_spaltennamen' 2025-01-15 09:20:54 +01:00
Harald Bamberger 0770ec2bd8 Merge branch 'master' into feature-54920/DB_Model_encrypted_columns_spaltenname_enthaelt_anderen_spaltennamen 2025-01-15 09:03:41 +01:00
Alexei Karpenko 13d86edcfc sancho mails: added CUSTOM_MAIL_USE_IMAGES config for sending mails without header/footer, removed option to hide mail html 2025-01-14 17:24:40 +01:00
ma0048 50aca4a545 - umbenennung auf internatinal credits 2025-01-14 11:00:26 +01:00
Alexei Karpenko 6c858141fd deleted mailtest file 2025-01-13 16:22:45 +01:00
Alexei Karpenko 6b169d4183 sancho mail: configuration of header/footer and sender is possible 2025-01-11 15:43:30 +01:00
Harald Bamberger 46914e8a65 bugfix wenn mehrere karenzen im abgefragten zeitraum vorhanden sind 2025-01-07 14:38:08 +01:00
ma0048 8bc1aec764 - info mail auch senden, wenn in niedriger Prio bereits student ist 2024-12-18 14:46:26 +01:00
Andreas Österreicher a802e67faf Merge branch 'pep_deploy' 2024-12-16 13:57:15 +01:00
Andreas Österreicher 2c91756a36 Added missing APP PEP to checksystem 2024-12-16 13:29:55 +01:00
Harald Bamberger 0d2882d8aa Merge branch 'feature-25999/SearchbarStudent' 2024-12-13 12:11:12 +01:00
Harald Bamberger f62108f1d4 change concatenation of verband, use contact email in Stv search result, use dummy image when viewing anothers profile and foto is null or foto_sperre is not false 2024-12-13 12:09:16 +01:00
ma0048 746f8ab35a Merge branch 'feature-54822/filtercomponent_custom_headerfilter' into pep_deploy 2024-12-13 11:51:11 +01:00
ma0048 70b44c2202 Merge branch 'feature-40717/pep_faktor' into pep_deploy
# Conflicts:
#	public/js/components/filter/Filter.js
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2024-12-13 11:50:53 +01:00
ma0048 c0d2474ad2 -dbupdate gegencheck eingebaut
- delete restrict auf cascade geändert
2024-12-13 11:42:00 +01:00
Harald Bamberger 5a174e554a use studentStv in Studentenverwaltung config, add aktiv to student and studentStv result, use studentStv in searchbar component, add searchbar_inaktiv css class, use aktiv to render inactive studentStv results with css class searchbar_inaktiv 2024-12-13 11:25:02 +01:00
ma0048 3451741327 - ON DELETE RESTRICT auf ON DELETE CASCADE bei bei den notizen
- sql angepast
2024-12-13 11:03:46 +01:00
SimonGschnell a3840d4c77 update(Searchbar/Student):shows dummy image if the student has foto_spere true 2024-12-13 10:47:34 +01:00
SimonGschnell 9a1777d1aa fix(_student searchfunction):fixes the sql logic for non active students 2024-12-12 15:35:56 +01:00
Harald Bamberger 4a86a48969 Merge branch 'master' into feature-25999/SearchbarStudent 2024-12-12 15:27:08 +01:00
Andreas Österreicher 1f01c55d71 LVPlan Feedback Link auf Startseite entfernt 2024-12-12 15:06:02 +01:00
Harald Bamberger 80222b7186 Merge branch 'master' into feature-25999/SearchbarStudent 2024-12-12 14:55:41 +01:00
Harald Bamberger d0266e7ef0 add vuejs3_dev to composer.json and ci javascript config file to switch between vuejs dev and prod version, alter FHC-Footer to use new config 2024-12-12 14:49:15 +01:00
Harald Bamberger 3039fd2a1e Merge branch 'master' into feature-25999/SearchbarStudent 2024-12-12 13:57:03 +01:00
ma0048 5b3ffcfc9a - faktor berechtigung angepasst 2024-12-12 12:37:24 +01:00
Andreas Österreicher 03d8205722 Merge branch 'feature-46905/LV_plan_feedback_Link_aendern' 2024-12-12 11:30:00 +01:00
SimonGschnell df8d4de50b fix(SearchbarLib/_student): the cis search does not include students that are not aktiv and has a seperate search function for the student search for the Cis and the studentverwaltung 2024-12-12 09:42:38 +01:00
Harald Bamberger 9af3f1ec0f Merge branch 'feature-25999/LvMenuFix' 2024-12-11 17:50:03 +01:00
SimonGschnell 85d59f18be refactor(searchbar/Student): studiengang/verband/email are queried for the display in the searchbar component 2024-12-11 15:30:41 +01:00
ma0048 6a1e518da1 - defaultheaderfilter function in eigenes file verschoben 2024-12-11 13:44:19 +01:00
ma0048 8127091e2e - tags werden im fas nicht angezeigt
- class für tags hinzugefuegt
- prop confirmLimit hinzugefuegt
2024-12-11 13:25:38 +01:00
SimonGschnell a357001648 feature(Searchbar/StudentenSuche): adds student to the searchbar options and adds shadow to the searchbar 2024-12-11 12:34:58 +01:00
Harald Bamberger bfc6e86f05 Merge branch 'master' into feature-54920/DB_Model_encrypted_columns_spaltenname_enthaelt_anderen_spaltennamen 2024-12-11 11:54:23 +01:00
Harald Bamberger 3c8bb37a36 Merge branch 'master' into feature-54920/DB_Model_encrypted_columns_spaltenname_enthaelt_anderen_spaltennamen 2024-12-11 11:52:50 +01:00
SimonGschnell 2567db7725 fix(LvMenu.js): fixes layout of MenuPunkt if multiple moodle links are available 2024-12-11 11:28:40 +01:00
Andreas Österreicher 034e1397e8 Merge branch 'feature-52814/infocenter_infocentermitarbeiter_spalte_beim_loeschen_des_dokuments' 2024-12-11 08:36:27 +01:00
Andreas Österreicher 35ded7950f Merge branch 'feature-46974/neuer_filter_ueber_ueberfaellige_buchungen' 2024-12-11 08:00:54 +01:00
Andreas Österreicher a6a74cd1e0 Merge branch 'feature-40413/testtool_sperren_bei_namen_mit_hochkomma' 2024-12-11 07:52:27 +01:00
Andreas Österreicher bae48fa175 Merge branch 'master' into feature-40413/testtool_sperren_bei_namen_mit_hochkomma 2024-12-11 07:13:20 +01:00
Andreas Österreicher 94f4761163 Merge branch 'bug-54917/Gruppenmanagement_Berechtigung' 2024-12-11 07:07:44 +01:00
Alexei Karpenko cc99d2b378 Gruppenmanagement: added checks so only Gruppenmanager can edit groups 2024-12-10 12:03:58 +01:00
Alexei Karpenko ce2d69fc82 Vertragsbestandteil Model: check if sap sync table present before executing select for sap organisationseinheit 2024-12-06 13:05:35 +01:00
Andreas Österreicher 07ee3e1f4e Import der Leistungsstipendien angepasst. Neue Spaltenreihenfolge, Keine
automatische Gegenbuchung, Import der Bankdaten
2024-12-06 12:50:58 +01:00
Harald Bamberger 3cea79cb28 Merge branch 'feature-25999/C4_cleanup_rc' 2024-12-04 12:44:08 +01:00
Harald Bamberger e159dc44dc Merge branch 'master' into feature-25999/C4_cleanup_rc 2024-12-04 12:43:06 +01:00
Andreas Österreicher 055cea2002 Termin3 entfernt aus Default Checksystem 2024-12-04 11:25:49 +01:00
Harald Bamberger f105bdb36a revert FhcApi.js to current master 2024-12-04 11:09:37 +01:00
Harald Bamberger 1b445005af remove addMeta debug info 2024-12-04 09:28:59 +01:00
Harald Bamberger 2fee03ebcc remove sprachen menu from main nav 2024-12-04 09:17:15 +01:00
Harald Bamberger d30ba24d2f add config cis_send_profil_update_mails, use it in profil update controllers 2024-12-04 09:15:44 +01:00
ma0048 631010821b - check bei projectstunden ob stunden eingetragen sind 2024-12-03 17:08:03 +01:00
ma0048 b34a7bfabc - custom filter tabulator 2024-12-03 16:13:48 +01:00
ma0048 6a1af1b2dd - fuer lehre tab planungsstatus hinzugefuegt
- config fuer planungsstatus
- tags ohne notiz setzen
2024-12-03 15:31:32 +01:00
Harald Bamberger 6f69046b71 use regex with word boundaries to be more specific when replacing 2024-12-03 13:44:24 +01:00
ma0048 19b56ff252 - tags
- phrases
- stundensatzbydatum
- filter nur count
2024-12-03 12:36:54 +01:00
Harald Bamberger af2f3348b4 Merge branch 'master' into feature-25999/C4_cleanup 2024-12-03 07:37:22 +01:00
Johann Hoffmann 41ad440cd4 update newsWidget template & css, fixed carousel css transition; 2024-12-02 16:41:42 +01:00
ma0048 1a1ed49f8b - styling für neuen tag
- hover effekt
- tagicon statt plus
2024-12-02 13:09:38 +01:00
Cris d67e240b06 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-12-02 11:01:45 +01:00
Johann Hoffmann bf5e8e9c0e Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_anwesenheiten_widget 2024-12-02 10:57:40 +01:00
Andreas Österreicher e63234e7bc Gegencheck und Anwesenheit App eingefügt 2024-12-02 10:09:09 +01:00
Johann Hoffmann 1ca0f35d29 news widget template carousel with menu update; 2024-11-29 15:24:33 +01:00
SimonGschnell 1336860ecd feature(Dashboard Transitions): uses Vue's built-in Transition component to add transitions to the widget config elements 2024-11-29 13:23:51 +01:00
Harald Bamberger 278e5d8abd Merge branch 'master' into feature-25999/C4_cleanup 2024-11-29 13:04:08 +01:00
SimonGschnell 95e59007cc refactor(Settings/NavUser Collapsibles): closes the collapsibles if the user clicks outside of the elements 2024-11-29 12:29:59 +01:00
SimonGschnell 857d4d7282 refactor(Calendar indicator):adds Vue transition to the Calendar indicator through Vue's built-in component 2024-11-29 11:50:27 +01:00
Harald Bamberger 7a7c91b67b readd lines of code that were lost during merging 2024-11-29 11:19:57 +01:00
SimonGschnell 9cf6036926 refactor(Paginatino.js): makes the pagionation component responsive on mobile displays 2024-11-29 10:57:14 +01:00
Andreas Österreicher 11eae29dab Merge branch 'feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp' 2024-11-28 14:04:50 +01:00
Andreas Österreicher 0f476b4e46 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-11-28 14:02:41 +01:00
Andreas Österreicher 677d6e97d6 Config zur Steuerung für welche Studiengaenge die Digit. Anwesenheiten
sichtbar sein sollen (Testbetrieb)
2024-11-28 13:38:25 +01:00
SimonGschnell 021a140dd3 refactor(LvInfo.js): also adds a Profil View link to the lektor name 2024-11-28 13:09:41 +01:00
SimonGschnell 4f8ca679fb fix(Calendar/Week/Day/Page.js): removes the calendar indicator when moving the mouse outside of the calendar 2024-11-28 12:52:24 +01:00
SimonGschnell 9dfa8d13a6 feature(Mylv/Info.js): adds Profil view links to the Lektoren in MyLv Info and fixes the dupplicate lektoren names 2024-11-28 12:46:23 +01:00
SimonGschnell 71c39edd66 fix(Cis/Sprachen.js): fixes classes of the Sprachen component inside of the Nav Menu when toggled 2024-11-28 10:53:00 +01:00
Johann Hoffmann 1346466f79 Merge branch 'master' into feature-25999/C4_anwesenheiten_widget 2024-11-28 10:43:57 +01:00
Johann Hoffmann beb40cfcc9 Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_anwesenheiten_widget 2024-11-28 10:22:57 +01:00
Andreas Österreicher 0a4d8bb1f6 Falsch verschachtelte Phrase korrigiert 2024-11-28 08:43:25 +01:00
Cris b2477bb603 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-11-27 17:32:27 +01:00
Johann Hoffmann 39f1f825a5 fhcApi extendable & reactive; provide reactive viewdata from dashboard to widgets by inject/provide reworked news xslt in db; css change since overflow-auto is in xslt now; WIP anw widget; 2024-11-27 16:30:54 +01:00
SimonGschnell 6e1943928a feature(Cms/Content_types/Raum_contentmittitel.js): wraps the h1 title of the content with a link to the Reservierungen of that room 2024-11-27 15:04:56 +01:00
Andreas Österreicher 490a658e6d Merge branch 'feature-8482/Pruefungsprotokoll_zur_Einsicht_exportieren' 2024-11-27 13:45:30 +01:00
Andreas Österreicher fd91a4cb85 Merge branch 'master' into feature-8482/Pruefungsprotokoll_zur_Einsicht_exportieren 2024-11-27 13:44:24 +01:00
SimonGschnell 800d7ba005 refactor(Cis.css fhc-entry styles): switches the background-colors of the fhc-entry class between selected and not selected 2024-11-27 13:04:52 +01:00
SimonGschnell 89539d59fd refactor(components/Cis/Sprachen.js): refactors the Sprachen component with different styles and stores the user_langauge in the global properties of the Vue application by managing a reactive state in the phrasen plugin 2024-11-27 11:50:19 +01:00
Johann Hoffmann 1ba857b524 only show digi anw in cis_menu_lv when corresponding lva is from BIF/257 for testphase 2024-11-26 17:12:11 +01:00
SimonGschnell 0ebc6e820c refactor(Calendar/Page/Event style): change the margins of an event, so that the border of the event is visible 2024-11-26 16:27:48 +01:00
SimonGschnell 24740d055e feature(Sprache/Phrasen aendern): creates a Cis Sprachen component that lists all available Sprachen from the database and lets the user change the currently active language and persist it in the database 2024-11-26 16:26:29 +01:00
Johann Hoffmann c02c1e9955 hinweis "testphase -> keine benotung" phrase 2024-11-26 15:59:42 +01:00
Andreas Österreicher c32f65bc1e Reihungstestangetreten Check aus BIS-Bewerbermeldung entfernt 2024-11-26 12:49:21 +01:00
SimonGschnell 82f1a70de5 fix(Calender/Day/Page.js): ausgewaehlte Event wird resetet wenn man den darauffolgenden oder vorherigen Tag auswaehlt 2024-11-26 09:25:24 +01:00
SimonGschnell 8983af4aef refactor(Stundenplan_model/getStundenplanQuery):removes wrong comments 2024-11-25 19:59:39 +01:00
Harald Bamberger 290da9f2c0 Merge branch 'master' into feature-25999/C4_cleanup 2024-11-25 17:09:53 +01:00
Harald Bamberger 7fe3a7c8f5 Merge branch 'feature-25999/C4_cleanup_rc' 2024-11-25 16:33:27 +01:00
Harald Bamberger 766bec887a check if constant CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN is defined 2024-11-25 16:29:41 +01:00
SimonGschnell 90bdb68175 fix(Stundenplan_model/getStundenplanQuery):changes how the OR sql statments are added to the query 2024-11-25 15:24:36 +01:00
Harald Bamberger 0bec551174 lowercase search in searchfunction fhcapifactory path 2024-11-25 14:24:04 +01:00
Harald Bamberger f90f5154a0 remove searchdummy function and dummyapi 2024-11-25 13:57:25 +01:00
Harald Bamberger 2ed24ca60f remove unneeded controllers, views and vuejs apps 2024-11-25 13:48:33 +01:00
SimonGschnell 699595e891 refactor(DashboardWidget/Stundenplan.js):adds the template for the MonthPage when the Month of the calendar is visible 2024-11-25 13:34:36 +01:00
SimonGschnell 43fbd1d8f1 refactor(Calendar/Day/Page.js): moves the content to the parent, so that different views can display different content 2024-11-25 13:28:55 +01:00
SimonGschnell 36c129fcaf reafactor(Calendar/Day/Page.js-Calendar/Week/Page.js): refactors styles of elements for easier readability 2024-11-25 11:41:22 +01:00
Harald Bamberger df0ed6715c add renderif to default room action if no content id is defined 2024-11-25 11:31:13 +01:00
Harald Bamberger 6f1e61fa00 move contentid of cis4 menu root to ci config, remove unused controller components CisVue, modify CISVUE-Header to use config for cis4 menu root content id 2024-11-22 15:16:27 +01:00
SimonGschnell 1297a8a23a reafactor(Calendar/Day/Page.js): refactors styles of elements for easier readability 2024-11-22 15:02:42 +01:00
Harald Bamberger 8e51071997 readd v-bind item removing it breaks dashboard customize view instead of plus signs a ghost widget is shown 2024-11-22 14:50:16 +01:00
Johann Hoffmann ecab3ea4d9 remove hardcoded h1 tag, keep the title h1 tag; more cleanup; 2024-11-22 11:43:05 +01:00
Andreas Österreicher 14169fafd0 Wording korrigiert 2024-11-22 11:42:24 +01:00
Johann Hoffmann e2b42de6b3 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-22 10:27:12 +01:00
Johann Hoffmann f4d16af68e change eye watering cms css from green background & white font to white background and black font - as it should be 2024-11-22 10:26:47 +01:00
SimonGschnell ab15a8675c Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-22 10:25:22 +01:00
SimonGschnell 20abd6aa05 fix(LvMenu): makes non available menu punkte disabled and non interactable 2024-11-22 10:25:02 +01:00
Johann Hoffmann 4bd4301873 more template cleanup profil 2024-11-22 10:15:31 +01:00
Andreas Österreicher fa3d36e99e Added check if Constant CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN is
available at all
2024-11-22 08:46:42 +01:00
Johann Hoffmann 16cfb0a3eb template cleanup profil 2024-11-21 17:32:34 +01:00
Johann Hoffmann 1a6b30588d MyLvApp & Components template & property definition cleanup 2024-11-21 16:11:02 +01:00
Harald Bamberger fc5ea9f4db remove unused xmlns:fo add xsl:output method html 2024-11-21 15:59:42 +01:00
Johann Hoffmann 61728f3044 dashboard & widgets: template cleanup; property definiton cleanup; delete unwrapInjectedRef -> resolved since vue3.3; 2024-11-21 15:43:35 +01:00
Johann Hoffmann a349a179d0 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-21 15:22:09 +01:00
Johann Hoffmann d400f34e0f missing phrasen 2024-11-21 15:21:33 +01:00
Harald Bamberger cdc9e08cd0 cleanup C4 dbupdates 2024-11-21 15:14:13 +01:00
Harald Bamberger 8eb7d18ff9 remove C4 Menu from checksystem 2024-11-21 14:04:35 +01:00
Johann Hoffmann 920bd845f8 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-21 13:28:10 +01:00
Johann Hoffmann 933ca20e65 tabulator in cms content -> sanitize table header contructs breaking tabulator; 2024-11-21 13:27:39 +01:00
SimonGschnell 763d038b4c fix(api/v1/Stundenplan/getStundenplan): fetches groups and studentlehrverbaende based on the date interval of the current and previous semesters 2024-11-21 12:19:22 +01:00
Harald Bamberger 6946028d76 Merge branch 'master' into feature-25999/C4_cleanup 2024-11-21 11:39:50 +01:00
kindlm 222f31c464 Merge remote-tracking branch 'origin/master' 2024-11-20 16:01:07 +01:00
kindlm 155e8da35a Ampel Übersicht tablesorter with filter + date-sort bugfix 2024-11-20 16:00:57 +01:00
Cris 95ebc442a4 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-11-20 13:58:27 +01:00
Johann Hoffmann a5dd639404 stundenplan header offset class conditionally depending on fhc-calendar widget property 2024-11-20 11:14:55 +01:00
SimonGschnell 7466e414f8 Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-20 10:36:04 +01:00
SimonGschnell 3896aa73ea fix(Raum_information Calendar): passt die RaumInformations Seite auf die Aenderungen des Calenders an 2024-11-20 10:35:51 +01:00
Harald Bamberger f6319aa845 add new searchoptions to display search results correct again 2024-11-20 09:29:43 +01:00
Harald Bamberger 9420e22b2a optimise scrolling behavior of search results and responsive layout of search results 2024-11-19 18:13:15 +01:00
Johann Hoffmann 778149880f Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-19 17:46:32 +01:00
Johann Hoffmann 2c98438096 add cis4link to widget setup; show link icon in dashboard item header; remove links from widget contents; 2024-11-19 17:46:11 +01:00
Harald Bamberger a2bdca5551 fix typo 2024-11-19 17:44:44 +01:00
Harald Bamberger 05c52e41eb search only for active orgunits and rooms, also search room description 2024-11-19 17:33:57 +01:00
Johann Hoffmann 00406c50a5 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-19 17:09:58 +01:00
Johann Hoffmann 5e9e08d65e calendar scrollbar css fix; 2024-11-19 17:08:39 +01:00
Johann Hoffmann d8af18673c always show card header of widgets as in editMode but enable certain tools only when actually in editMode. editMode is active for dashboard not for section; less paddings overall in dashboard; deleted Section headers and put cog besides personal greeting; reformatted name var for greeting into generic viewData property; 2024-11-19 17:07:05 +01:00
Harald Bamberger c32046002d add buffer to height calculation 2024-11-19 16:24:36 +01:00
Harald Bamberger df054a7088 Merge branch 'feature-25999/C4_cleanup_rc' into feature-25999/C4_cleanup 2024-11-19 16:18:45 +01:00
Harald Bamberger 4e4e8a0a5c improve responsive layout of search results 2024-11-19 16:16:46 +01:00
Johann Hoffmann ad7b43f8a8 Merge remote-tracking branch 'origin/feature-25999/C4_cleanup' into feature-25999/C4_cleanup 2024-11-19 13:35:30 +01:00
Johann Hoffmann f82c669475 provide/inject editModeIsActive from section.js -> currently used in bookmark widget to move redundant config modal into actual widget when said mode is on; 2024-11-19 13:35:06 +01:00
SimonGschnell d2466b032a Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-19 12:51:50 +01:00
SimonGschnell 8d01995722 refactor(Studenplan Query):queries all studiensemester from start_date to end_date and matches the gruppen and studentlehrverbaende to the associated studiensemester in the query 2024-11-19 12:51:12 +01:00
Johann Hoffmann 3cb9e5b4f8 stpl widget title & show no LVA found on empty days; limit news widget content img max-width by css class; 2024-11-19 12:38:32 +01:00
SimonGschnell 5d5b2e5bc4 fix(FHCAPI_Controller): adjusts the php doc types of parameters 2024-11-19 11:35:20 +01:00
Johann Hoffmann 4cb3521361 Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-19 10:36:34 +01:00
Johann Hoffmann 46ef02b54d deactivate drag mode when widget config modal is opened 2024-11-19 10:33:39 +01:00
Harald Bamberger 9c6509b32a Merge branch 'feature-25999/C4_cleanup_tablewidget' into feature-25999/C4_cleanup 2024-11-19 10:18:26 +01:00
Harald Bamberger d6bdad27b2 move room specific stuff to searchconfig, add renderif method to be able to render actions conditionally via config, remove additional prop selectedtypes 2024-11-19 10:17:10 +01:00
SimonGschnell 4aed321b5e refactor(Calendar Tagesansicht): changes how the logic for opening a modal or showing the lvMenu next to the calendar is handled 2024-11-19 10:11:49 +01:00
Harald Bamberger 06dab52461 Merge branch 'feature-25999/C4_cleanup_tablewidget' into feature-25999/C4_cleanup 2024-11-19 08:48:06 +01:00
Harald Bamberger 6fc7fd7788 Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_cleanup_tablewidget 2024-11-19 08:44:24 +01:00
Harald Bamberger 13e77c8154 Merge branch 'master' into feature-25999/C4_cleanup 2024-11-19 08:43:05 +01:00
Johann Hoffmann b6a5e9b845 load stsemArray from Prestudentstati for select options; 2024-11-18 16:09:16 +01:00
Harald Bamberger ad31e73212 reset Tabulator fontsize, combine page headings 2024-11-18 11:59:40 +01:00
Harald Bamberger 5596c12af9 use deleteRow instead of getRow and delete to avoid console log error 2024-11-18 11:53:17 +01:00
Harald Bamberger e044641600 use deleteRow instead of getRow and delete to avoid console log error 2024-11-18 11:50:51 +01:00
Harald Bamberger 65c9d5a84c adminZeitverfuegbarkeiten reset tabulator fontsize 2024-11-18 10:47:08 +01:00
Harald Bamberger 545a9c31e4 tablewidget footer buttons add missing btn css class 2024-11-18 10:29:28 +01:00
Harald Bamberger 2b98a35f59 bs5 accordion-button class added 2024-11-18 10:20:13 +01:00
SimonGschnell 96ec9aa8aa fix(Calender Style): changes the hover style for fhc-entries to have a brighter color than the selectedEvent itself 2024-11-18 09:32:49 +01:00
Harald Bamberger 1b8980a0e2 add css classe with bs3 legacy colors for bg-success and bg-warning and use them in acceptLehrauftrag cis page 2024-11-15 15:58:26 +01:00
Harald Bamberger 1e5d7e01af reset font-size for tabulator on vilesci page 2024-11-15 15:57:00 +01:00
Harald Bamberger 78f216f9ad fix syntax error 2024-11-15 15:55:42 +01:00
Harald Bamberger 16cba022e2 add css class to be able to reset tabulator fontsize to 14px for vilesci pages, set active and focus class for filter buttons to new combined button, add css rules to make tooltips on cells in unselectable rows work again 2024-11-15 15:21:46 +01:00
Harald Bamberger 488847984e change property downloadTitle to titleDownload for Tabulator 5, call tabulator redraw at the end of tableInit callback to ensure renderStart callbacks are run 2024-11-15 15:19:09 +01:00
Harald Bamberger daf432fe8d port changes made for BS3 => BS5 to version of current master to get rid of many whitespace and code formating changes and only have functional changes 2024-11-15 15:14:15 +01:00
Johann Hoffmann 3146f0795f Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-15 14:12:00 +01:00
Johann Hoffmann 87657a18f1 apply max width only to sanitized p blocks, not column default 2024-11-15 14:10:47 +01:00
Johann Hoffmann 6e8aea7feb Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-15 14:04:53 +01:00
Johann Hoffmann d9f33a279d apply html sanitization on legacy cms tables intended to be rendered with tabulator 5; clears nested tables, reformats rext nodes and unordered lists to fit into tabulator cells; 2024-11-15 14:02:05 +01:00
SimonGschnell fdcef8bdab feature(Calendar): keeps track of the selected Event in a shared state and highlights the selected Event over different calendar views 2024-11-15 12:52:24 +01:00
SimonGschnell 65d0e89f06 refactor(Stundenplan events css): moves the class definitions of the events to the slot templates and adds little animations 2024-11-15 11:48:55 +01:00
SimonGschnell 45fca04029 feature(Calendar Tagesansicht):based on the window with decides wether to display the lvMenu in a Modal or next to the calendar 2024-11-15 11:18:15 +01:00
SimonGschnell ef21936975 fix(Calendar scroll):ensures the calendar scroll watcher always triggers by also passing the current focusDate of the Calendar 2024-11-15 09:52:40 +01:00
Harald Bamberger 6b828179b0 revert lehrveranstaltung.class.php lehreinheit.class.php to current master since additional functions were ported to codeigniter models and are no longer used 2024-11-14 16:13:11 +01:00
SimonGschnell ebedb30c29 refactor(Stundenplan Tagesansicht):dynamically loads the lvMenu of the first Lv of the day and hightlights the selected LV of the day 2024-11-14 14:40:18 +01:00
Johann Hoffmann 8da27a5c77 stpl widget shows selected day + next 7 days 2024-11-14 13:12:56 +01:00
SimonGschnell 681fb18222 fix(Stundenplan): readds the loadEvents and deletes the template error 2024-11-14 11:15:02 +01:00
SimonGschnell f159d6e2a7 fix(Grid CSS): remove unused css rules and css classes 2024-11-14 11:07:58 +01:00
Johann Hoffmann 3fff0c5325 Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-13 18:59:33 +01:00
Johann Hoffmann 160294bea4 removed grey section background and added fading thing seperator line for every section after the first 2024-11-13 18:39:19 +01:00
Johann Hoffmann a682d6e5ae overflow-y scroll changed to overflow-y auto -> avoid unnecessary scrollbars 2024-11-13 18:14:58 +01:00
Johann Hoffmann 9042f9b83b change fh logo visibility breakpoint class md -> sm; editable flag in profile based on looking at own profile or being an admin; scrollbar calc in profil app; 2024-11-13 17:27:50 +01:00
Johann Hoffmann cad2756613 Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-13 15:21:33 +01:00
Johann Hoffmann 2fd39a9d18 defined active color variable for lvl 2 buttons and use in css class fhc-active for language Buttons. It is yet another shade of grey. 2024-11-13 15:19:42 +01:00
SimonGschnell 329a418be3 Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-13 14:53:49 +01:00
SimonGschnell e3cbbfa365 feature(Calendar Tagesansicht): LvInfo und LvMenu wird neben der Tagesansicht angezeigt wenn man eine Lv auswaehlt 2024-11-13 14:52:46 +01:00
Johann Hoffmann c85790b637 Merge branch 'feature-53416/stundenplan_eine_lva' into feature-25999/C4_cleanup 2024-11-13 14:14:34 +01:00
Johann Hoffmann 5d524c5fda fix dashboard alert css by adding primevue3 in $includeArray in Dashboard view file 2024-11-13 14:14:11 +01:00
Johann Hoffmann 6613b0ea40 remove console.log 2024-11-13 14:08:58 +01:00
Johann Hoffmann a94d8d8fa5 calendar minimized only using slot; showing whole week in stundeplan widget tagesansicht grouped by day; everything in past has 0.5 opacity 2024-11-13 13:57:37 +01:00
Andreas Österreicher 3c966e00ba Merge branch 'feature-47976/KU_Linz_Statistik_Austria_Export_BPK' 2024-11-13 12:11:35 +01:00
Johann Hoffmann e43a890aff Merge branch 'feature-25999/C4_cleanup' into feature-53416/stundenplan_eine_lva
# Conflicts:
#	public/js/apps/Cis/Stundenplan.js
#	public/js/components/DashboardWidget/Stundenplan.js
2024-11-13 11:17:43 +01:00
SimonGschnell 59f8f91af9 feature(Calendar Tagesansicht): Calender wird ausgegraut wenn keine LVs an diesen Tag vorhanden sind 2024-11-13 11:00:08 +01:00
Johann Hoffmann b0cd599999 WIP stundenplan widget tagesansicht 2024-11-13 10:41:50 +01:00
SimonGschnell c244b3ad1b fix(Stundenplan): template error 2024-11-12 12:55:14 +01:00
ma0048 6b04dff4a3 - start tab tags hinzugefuegt 2024-11-12 11:47:16 +01:00
Harald Bamberger f265e20dce Merge branch 'feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp' into feature-25999/C4_cleanup 2024-11-12 11:21:16 +01:00
Harald Bamberger c691d155c9 remove dependecy to legacy phrases from LvMenu controller, add legacy phrases needed in LvMenu controller 2024-11-12 11:05:13 +01:00
SimonGschnell 3046c29ae2 fix(Calendar): does not display events on the calendar when sliding the carusel to avoid showing overlapping events 2024-11-12 09:57:10 +01:00
SimonGschnell 6cf7a8e35e fix(Calendar scroll): extends the id of the scroll anchor to include hour/day/week and changes the logic to search for the anchor depend on the week or day view 2024-11-12 09:48:03 +01:00
SimonGschnell 35691b39c4 fix(Calendar scroll): fixes the scroll feature for the Calendar 2024-11-11 16:15:14 +01:00
Johann Hoffmann 85bec1e0e3 section spacing; dashboard widgets section backgrounds; set scrollbar width css variable via new helper in FhcApp (Dashboard); WIP stundenplan alle Termine einer LV -> c4 link in bfi addon adapted; 2024-11-11 15:49:03 +01:00
SimonGschnell 094a3ed56a feature(Calendar): scrolls to the first event of the day if the prop scrollTime is passed to Calendar component 2024-11-11 15:46:09 +01:00
SimonGschnell bd1ce9fa63 refactor(Calendar Header): refactors view buttons in the calendar header 2024-11-11 14:57:34 +01:00
SimonGschnell bd54399cfd fix(Calendar Header): adds responsiveness to the calendar header and the view button group next to the header 2024-11-11 14:57:28 +01:00
SimonGschnell b7e89ab557 fix(Stundenplan hour lines): fixes the hour lines from disapearing on smaller viewports by using a box-shadow instead 2024-11-11 11:27:23 +01:00
SimonGschnell 0e49dfaba0 refactor(Calendar day view): changes the classes for fhc-calendar-day-page so that the width is divided in calendar and content 2024-11-11 10:40:58 +01:00
Johann Hoffmann 96335a7979 moved email template to fhtw addon; einheiten column visibility default false since pausen are not represented; backend code cleanup; phrase fix; 2024-11-11 09:56:43 +01:00
ma0048 355652cdb1 - added sql for tags 2024-11-11 07:51:52 +01:00
ma0048 45bc65d32a - Tags testversion
- header tooltips
- lehre spalte markieren wenn altes semester
- legende-tab hinzugefuegt
2024-11-11 07:33:49 +01:00
SimonGschnell ca7ded38d2 refactor(Stundenplan indicator): uses a 5 minute interval for the Stundenplan indicator 2024-11-08 16:08:08 +01:00
SimonGschnell f304e79ee0 feature(Stundenplan): adds Tagesansicht for the Stundenplan 2024-11-08 15:18:10 +01:00
SimonGschnell 68042c1c77 Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-08 14:14:54 +01:00
SimonGschnell b9690988e5 refactor(Stundenplan): uses named slots for week-view template 2024-11-08 10:53:02 +01:00
Harald Bamberger 1691c75a84 replace dependencies on legacy code with ci model functions 2024-11-07 19:18:08 +01:00
SimonGschnell f4176b86ee refactor(js helpers): moves ObjectUtils from composables to the js helpers folder and changes its import statements 2024-11-07 15:00:25 +01:00
SimonGschnell da70c77a2b feature(DateHelpers.js): creates a js helper file to create, handle and manipulate js dates 2024-11-07 15:00:18 +01:00
SimonGschnell 6732063e6a Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-11-07 13:15:08 +01:00
SimonGschnell b65d17e7ae refactor(LvModal): uses the right format for the date and adds padding to date numbers which are single digits 2024-11-07 13:14:40 +01:00
Andreas Österreicher f68d18f0a8 Stundenplan Bugfix to also load Entries of Semester and Verband 2024-11-07 10:25:42 +01:00
SimonGschnell 4f2992fbe2 fix(Cis profil menu): fixes the layout of the collapsible in the mobile view 2024-11-07 10:21:39 +01:00
Harald Bamberger 2b516d40c9 remove controllers, views and libraries for CisHtml since not used 2024-11-05 17:46:42 +01:00
Harald Bamberger 39cedfe6a0 remove controllers, views and libraries for CisHmvc since not used 2024-11-05 16:48:30 +01:00
SimonGschnell 8316290b31 fix(Cis Navbar Collapsibles): closes other colapsibles when opening another 2024-11-05 15:54:26 +01:00
SimonGschnell 7653bc3e29 fix(Menu User Dropdown): rearranges html elements to make dropdown scroll 2024-11-05 12:03:44 +01:00
SimonGschnell 37dffbba19 fix(Dashboard widget Url): adds validation method for both input fields and fixes confirm delete dialog 2024-11-05 11:32:02 +01:00
Harald Bamberger a9fe52d3c6 Merge branch 'feature-25999/C4_cleanup_merge_anrechnungen_bs5' into feature-25999/C4_cleanup 2024-11-05 07:59:21 +01:00
Harald Bamberger 20e0e2e910 Merge branch 'feature-25999/C4_cleanup' into feature-25999/C4_cleanup_merge_anrechnungen_bs5 2024-11-04 15:59:14 +01:00
Andreas Österreicher 835adca419 Debugging option entfernt 2024-11-04 15:42:47 +01:00
Harald Bamberger 50880c696b use getAuthUID function instead of get_uid, use new permission basis/cis and switch to Auth_Controller where possible 2024-11-04 15:41:02 +01:00
Harald Bamberger a65e94bc8a fix phrases variable name because of switch from mixin to plugin 2024-11-04 15:38:04 +01:00
Harald Bamberger 20715d6ef5 add permission basis/cis 2024-11-04 15:36:46 +01:00
Harald Bamberger c31cef349c add phrases from legacy code for news extra aside content 2024-11-04 15:35:35 +01:00
SimonGschnell 50a67a8e88 feature(Dashboard Bookmark): checks whether the link is a valid URL, displays fhcAlert otherwise 2024-11-04 14:37:09 +01:00
SimonGschnell eafbdcfffe refactor(Cis Menu): changes method name and checks if the CIS4_MENU_ENTRY constant is defined 2024-11-04 13:39:13 +01:00
ma0048 9c637b8575 - added model 2024-11-04 12:20:52 +01:00
SimonGschnell 86ee48888a fix(Cis Menu): adds Zahlungen to Mein Studium 2024-11-04 12:09:26 +01:00
SimonGschnell 9e45394deb fix(Cis MyLv): uses the moodle course bezeichnung for multiple moodle links 2024-11-04 12:09:12 +01:00
SimonGschnell ad068ffe5f different property name for the different moodle courses names 2024-11-04 09:07:35 +01:00
Harald Bamberger 93ac45308f Merge branch 'feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5' into feature-25999/C4_cleanup 2024-10-31 16:00:12 +01:00
SimonGschnell 34c6c63c74 Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-10-31 14:24:19 +01:00
SimonGschnell f820a0148a adapts the LV view to incorporate a dropdown if a lehrveranstaltung has multiple moodle links 2024-10-31 14:22:46 +01:00
Harald Bamberger e78c2e1bf7 Merge branch 'master' into feature-25999/C4_cleanup 2024-10-30 17:19:01 +01:00
Harald Bamberger d4f3fbfc79 Merge branch 'master' into feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5 2024-10-30 16:45:07 +01:00
SimonGschnell c5b81c22f9 adds the target for the lv menu in the studenplan modal and also replaces the tablesorter tables with tabulator5 in other content views 2024-10-30 11:31:39 +01:00
SimonGschnell 837cc191bf adds another link regex for the link string '../cms/content?content_id=...' and adds the library content to the CIS4 Menu content 2024-10-30 10:49:27 +01:00
Alexei Karpenko 9b4fb2ac2c bpk job: enabled getting vBPKs with new API version 0.8 2024-10-29 16:28:17 +01:00
SimonGschnell 6b991c514e refactors the room actions in the searchbar 2024-10-29 15:49:56 +01:00
SimonGschnell bdfea1763d adds gaps to the LvMenu 2024-10-29 15:38:10 +01:00
SimonGschnell 587a193a6b refactors the LvMenu Modal 2024-10-29 15:18:53 +01:00
Johann Hoffmann ec9e73180d primevue custom tooltip directive zIndex config retrieval fix; studentByLva tabulator height calc abort if no dataTable rendered; phrases fix; 2024-10-29 15:13:00 +01:00
SimonGschnell ff367339ea makes MyLv more responsive 2024-10-29 14:31:20 +01:00
Harald Bamberger ae80c3415d betraege im Gehaltsbestandteil als string mit . als komma konvertieren, um zu verhindern, dass locale spezifische Betraege in der verschluesselten DB Spalte gespeichert werden 2024-10-29 10:37:00 +01:00
Harald Bamberger 1e55b13546 force use of insertamum column from antrag table 2024-10-28 15:58:20 +01:00
SimonGschnell b9ccafe9db uses the cis.php file for the anrechnungen url 2024-10-28 15:57:33 +01:00
SimonGschnell 5f078a76c6 renders the right header (cis or fhtw) conditionally based on the CIS4 constant 2024-10-28 14:54:26 +01:00
SimonGschnell 3eb2100b3d Merge branch 'feature-25999/C4_cleanup' of github.com:FH-Complete/FHC-Core into feature-25999/C4_cleanup 2024-10-28 14:16:07 +01:00
SimonGschnell fbf0417269 only adds the Events file from addons which are actually active and refactors the Lv Information into its own component 2024-10-28 14:15:45 +01:00
SimonGschnell b801401d2b only shows the Week modus of the calendar if it is not a widget and opens the MyLV links as new tabs instead of showing them in the modal 2024-10-28 13:25:41 +01:00
Johann Hoffmann 46c4a30408 css fix & header file import remove 2024-10-28 11:36:49 +01:00
Johann Hoffmann 6fc5714fdf removed language flags; anw phrasen added; added names to apps for easier devtools debugging; 2024-10-25 16:34:57 +02:00
Johann Hoffmann 74cf0ad173 use vue header & tooltip translations 2024-10-25 15:58:37 +02:00
Johann Hoffmann e387671e09 added set language feature; phrasen plugin with optional reload if non responsive phrasen are used; stundenplan header mode & buttons reworked 2024-10-24 17:46:42 +02:00
Johann Hoffmann 32137479e9 activate email to assistenz on upload; redraw table in case of tabulator scroll bug; navigation.php $root var for Cis4 preperation 2024-10-24 15:07:08 +02:00
Harald Bamberger 2398ca1962 Merge branch 'feature-52916/Unterbrecher_in_serie' 2024-10-24 11:15:36 +02:00
cgfhtw 9eb91574c3 semester 2024-10-24 11:08:22 +02:00
cgfhtw 2edfd1febc Unterbrecher in serie problematik 2024-10-24 11:03:28 +02:00
Harald Bamberger 4789bfab42 add columns gehaltsbestandteil_von and gehaltsbestandteil_bis to hr.tbl_gehaltshistorie 2024-10-24 07:57:54 +02:00
ma0048 e89beb610d - infocentermitarbeiter spalte deleted by user wird ignoriert 2024-10-23 13:33:50 +02:00
Johann Hoffmann 805ed20a18 Merge branch 'feature-52360/C4_fh_logo_remove_and_extend_searchbar_mobile' into feature-52734/C4_moodle_link_stpl_widget_stpl_mylva 2024-10-22 17:52:57 +02:00
Harald Bamberger f59bdf812a add phrase mark_person_as_unruly 2024-10-22 17:18:02 +02:00
Harald Bamberger 384de674c0 Merge branch 'feature-40896/kennzeichnung_unruly_person' 2024-10-22 16:50:53 +02:00
Harald Bamberger fa0fe2a952 hide unruly option in AbmeldungStg for the moment 2024-10-22 16:49:56 +02:00
Harald Bamberger 8ba2a6852b Merge branch 'master' into feature-40896/kennzeichnung_unruly_person 2024-10-22 11:04:07 +02:00
Harald Bamberger c763e332d8 Merge branch 'feature-52735/C4_stundenplan_query_fix' into feature-25999/C4_cleanup 2024-10-21 17:16:21 +02:00
Johann Hoffmann f3851da10d add bootstrap class to only show fh logo in header on medium and greater displays; adjusted nav-user-btn css under mobile breakpoint to just take space of contained img and let searchbar flex growth apply to leftover width; 2024-10-21 16:02:54 +02:00
Johann Hoffmann 2e3bc855aa Merge branch 'feature-25999/C4_cleanup' into feature-52735/C4_stundenplan_query_fix 2024-10-21 13:51:21 +02:00
Johann Hoffmann 728e2f9b3a fix getStundenplanQuery query building if benutzer gruppen are empty; 2024-10-21 13:48:32 +02:00
Harald Bamberger 690080035a fix umlauts in variable name 2024-10-21 13:05:47 +02:00
Johann Hoffmann d8c4c6506a Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-10-21 10:21:42 +02:00
Harald Bamberger 9cd59a1250 add header version switch depending on CIS4 defined 2024-10-18 17:16:12 +02:00
Harald Bamberger 289c99a5a1 fix another 2 file permissions erroneously commited as a21a292da6 2024-10-18 17:03:40 +02:00
Harald Bamberger cf77a60b35 remove application/controllers/components/Antrag/* since not present in master any more 2024-10-18 16:57:03 +02:00
Harald Bamberger 0775fae67d remove unnecessary comment 2024-10-18 16:49:52 +02:00
Harald Bamberger 071b0c72dc Merge branch 'master' into feature-25999/C4_cleanup 2024-10-18 15:45:42 +02:00
Harald Bamberger 44b81d9dff Merge branch 'feature-25999/C4' into feature-25999/C4_cleanup 2024-10-18 15:44:39 +02:00
Johann Hoffmann 7ce426abc2 tooltip css fix; added missing phrase; 2024-10-18 15:14:13 +02:00
Andreas Österreicher 501784aba1 Zusätzliche Reihungsteststufen hinzugefügt 2024-10-18 14:24:16 +02:00
SimonGschnell 8ba370d3a7 makes the active menu punkt bold instead of underlined 2024-10-18 11:58:14 +02:00
SimonGschnell 59df85b05e adds Zeugnisse und Documents unter dem Mein Studium Menu Punkt 2024-10-18 11:55:20 +02:00
SimonGschnell 909b9f5f5a Merge branch 'feature-25999/C4' of github.com:FH-Complete/FHC-Core into feature-25999/C4 2024-10-18 11:19:18 +02:00
SimonGschnell 236c4bbdfc adds placeholders to the empty dashboard fields, that can be used to add new widgets to the dashboard 2024-10-18 11:18:36 +02:00
Harald Bamberger 755e8dd222 add provide to vuejs plugins FhcAlert, FhcApi and Phrasen so they are also useable with inject in composition api 2024-10-17 16:37:27 +02:00
Harald Bamberger c80e943b3b readd erroneously deleted folder addons/template commited as 56080f6681 2024-10-17 15:55:05 +02:00
Harald Bamberger d4494836b1 fix file permissions erroneously commited as a21a292da6 2024-10-17 15:34:00 +02:00
Johann Hoffmann a04b2725f9 csv download lektor table as is; cis_menu_lv link hidden behind berechtigungen check; every tabulator now calculates remaining height by accessing window.visibleViewport.height and tabulator dataset element in order to get virtual DOM behaviour for faster rendering and better UX; filter component now emits uuid on created() lifecycle; 2024-10-17 15:04:03 +02:00
Harald Bamberger 0ab1ec1fc8 Merge branch 'master' into feature-25999/C4 2024-10-17 14:49:43 +02:00
SimonGschnell e475fe568e adds the dashboard menu punkt and adds greeting to the dashboard view 2024-10-17 09:58:28 +02:00
Cris 38bf664b02 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-10-16 09:41:12 +02:00
Harald Bamberger 24ce443e95 nur die letzte komm oder zusaetzlichen komm Pruefung einer LV beruecksichtigen 2024-10-15 17:40:11 +02:00
Harald Bamberger 439ae5113d fix unterbrechung erstellen nicht möglich wenn ein abgelehnter unterbrechungsantrag existiert 2024-10-15 13:59:11 +02:00
Cris d913bf40d8 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-10-15 12:07:08 +02:00
Harald Bamberger 14aa98c223 Merge branch 'master' into feature-25999/C4 2024-10-15 10:46:17 +02:00
Harald Bamberger e2cee7ffa3 Merge branch 'master' into feature-25999/C4 2024-10-15 10:44:56 +02:00
Andreas Österreicher 5774cb78c9 Merge branch 'feature-40816/Plausicheck_Anpassungen' 2024-10-15 10:28:38 +02:00
Harald Bamberger 27e3f1d1bc take status rejected into account when calculating available semster slots for unterbrechung 2024-10-14 15:40:25 +02:00
Alexei Karpenko 301466f944 Merge branch 'master' into feature-40816/Plausicheck_Anpassungen 2024-10-14 15:20:16 +02:00
SimonGschnell 9ed08fb40c default value for hasConfig is false and the emit update for the URL dashboard widget and only loads the config component if the dashboard widget actually has a config 2024-10-14 13:36:31 +02:00
Alexei Karpenko 2893f2ec5a bugfix lvplan feedback link stpl_detail: correct html 2024-10-14 13:21:19 +02:00
SimonGschnell b0e96fbab1 replaces the emits to injections to avoid repassing the emits between intermediate parent elements 2024-10-14 11:42:30 +02:00
SimonGschnell 0528f3b262 checks the size of the arrays before using the current method and does not allow mitarbeiter to access the student stundenplan 2024-10-14 11:32:23 +02:00
SimonGschnell 462857080b makes the parent menu point active if the child menu points gets closed 2024-10-14 11:06:48 +02:00
Johann Hoffmann c67e78d135 phrasen rewording; formatter change; fix save changed anwesenheiten StudentByLvaComponent.js; 2024-10-14 10:42:49 +02:00
SimonGschnell 4f9591fc3b fix the z-index of the week stundenplan header 2024-10-14 10:36:46 +02:00
SimonGschnell c444e27d0d adds more styling and fixes little bug in the currentHour Stundenplan indicator 2024-10-14 10:34:01 +02:00
SimonGschnell ed1d4b1a50 regex replaces old content links with new CIS4 controller links and adopts the Menu Entry links to not refresh the page when closing the Menu point 2024-10-14 10:17:20 +02:00
SimonGschnell 9fd02460ce doesnt refresh the page when the menu entry gets closed, does redirect if the menu entry gets opened 2024-10-14 09:48:54 +02:00
Alexei Karpenko 1c61217891 lvplan: changed feedback phrase and Link 2024-10-13 13:34:07 +02:00
SimonGschnell f9e72832c9 adds time inidication on stundenplan on mouse position 2024-10-11 12:33:06 +02:00
SimonGschnell 5359539a09 makes Stundenplan query BLAZINGLY fast 2024-10-10 20:59:55 +02:00
SimonGschnell d2ed82cb37 calculates the total amout of hours with an array filter instead of statically inserting all hours 2024-10-10 13:27:26 +02:00
SimonGschnell f3fa2fa2dd adds the hour gutter for the stundenplan with absolute positioned divs instead of a linear gradient 2024-10-10 13:12:01 +02:00
cgfhtw 469867e98c Studstatus: status "EmailVersandt" is not an active status 2024-10-10 12:37:57 +02:00
SimonGschnell bf8085f642 starts the stundenplan from hour 7 instead of hour 0 2024-10-10 11:24:26 +02:00
Johann Hoffmann 9be5dc3f73 phrasen; tooltips; 2024-10-10 09:47:40 +02:00
Andreas Österreicher 9ca59f7928 Paragraph Verweis korrigiert für Master Plagiatsprüfung 2024-10-09 15:22:41 +02:00
Harald Bamberger b3258e017c add column path_kurzbz to view vw_oe_path 2024-10-09 13:14:54 +02:00
Harald Bamberger 1da045f58e Merge branch 'feature-40953/LV-Template_Uebersichtsseite' 2024-10-08 16:38:50 +02:00
Harald Bamberger 3c4b4b6a58 recht lehre/lehrveranstaltung auch am api endpunkt 2024-10-08 16:38:16 +02:00
Harald Bamberger 455d154b63 recht lehre/lehrveranstaltung statt basis/vilesci, schriftgröße verkleinern, menuepunkt in vilesci, headerfilter angepasst 2024-10-08 16:19:57 +02:00
SimonGschnell 4d50d4380b little bug fix 2024-10-08 13:54:58 +02:00
SimonGschnell 45ff067379 makes the url match to the Menu entries better 2024-10-08 13:47:48 +02:00
SimonGschnell ebebf8af6d changes calendar mode to button-group instead of select 2024-10-08 13:29:43 +02:00
SimonGschnell 79c8edc6cf makes the calendar week mode header align and highlights the week or day in the Month view depenedent if there is a week view available 2024-10-08 13:20:06 +02:00
Harald Bamberger a2f70be7e4 Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite 2024-10-08 09:28:56 +02:00
Johann Hoffmann 008bbedd98 phrase 2024-10-07 16:22:27 +02:00
SimonGschnell e75872adaa lets the user change the view of the calendar in the header with a select and highlights the date fields to change the view of the current calendar 2024-10-07 14:49:02 +02:00
kindlm 41a10320f8 Bugfix LV-Teile Vorrückung, wenn Von-Semester leer
Umbenennung Lehreinheit in LV-Teil
2024-10-04 13:51:48 +02:00
SimonGschnell 25a64cbcae fixes cis4 Menu for longest matching urls 2024-10-04 12:04:54 +02:00
Johann Hoffmann 772fe616ff remove unused unruly code nr2; 2024-10-03 13:27:05 +02:00
Johann Hoffmann a9d0f177da remove unused unruly code; 2024-10-03 13:25:02 +02:00
Johann Hoffmann ef0e3f3a66 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-10-03 11:24:48 +02:00
Andreas Österreicher 35043ad0ec Merge branch 'bug-48771/messages_list_limit' 2024-10-03 11:19:47 +02:00
ma0048 9dbb5291f4 - added limit 2024-10-03 11:17:09 +02:00
Johann Hoffmann dbf5935897 check correct grund phrase to trigger unruly api request; 2024-10-03 11:14:52 +02:00
Andreas Österreicher c754291c6d Merge branch 'feature-20228/erfassung_internationalisierungsmassnahmen_beurteilung' 2024-10-03 10:42:00 +02:00
Johann Hoffmann ed6eb18c4d fetch termine from vw_stundenplan, not tbl_stundenplan; LE_ID DD chagned to refs (WIP MA_UID DD & Termin DD); removed console.logs(); fhcAlert fix; now find closest termin with absolute value of timeDiff; 2024-10-02 18:04:30 +02:00
SimonGschnell 8042f3ae0b makes the menu point active with the url matches 2024-10-02 14:22:34 +02:00
ma0048 317796c919 - legende und phrasen hinzugefuegt 2024-10-02 14:13:44 +02:00
SimonGschnell e8f38bfcf6 sets the events to null before fetching the new events to reactivate the loading spinner 2024-10-02 13:28:18 +02:00
SimonGschnell 7f9352b820 prototyp fuer die Stundenplan query fuer Studierende 2024-10-02 13:25:39 +02:00
SimonGschnell c461480d1d stundenplanQuery optimization 2024-10-02 10:35:58 +02:00
SimonGschnell 567dd816be better descriptions for the cis4_root_menu sql queries 2024-10-01 13:54:53 +02:00
SimonGschnell 76facc40b9 changes the layout for the LvMenu to a flex instead of a grid 2024-10-01 12:14:34 +02:00
Johann Hoffmann ce058df3a5 Student Component Performance Fix (dont subquery person and anwesenheiten_user table on every anw_user row, just do the entschuldigung offen/abgelehnt logic in client before rendering); entschuldigung tab route; pagination on student entschuldigung page aswell; added config for einheiten länge to calculate/show; mitarbeiter selection in case of admin & lektor in same account behaving as expected; added index creation to initial sql scripts; 2024-09-30 17:25:51 +02:00
SimonGschnell 23b7d18906 gives the content_childs of the CIS4_ROOT the correct ordering 2024-09-30 14:24:48 +02:00
SimonGschnell fa8aec2c2e adds the MyLv and the Stundenplan Menupunkt to the sql inserts and changes the content for the Dokumente redirect 2024-09-30 14:13:00 +02:00
SimonGschnell 6f0f3890f9 doesnt show the footer in the editProfil modal when opening a ProfilUpdate 2024-09-30 13:43:26 +02:00
SimonGschnell 8f617c6222 fixes littel bug with the edit-profil modal in the StudentProfil 2024-09-30 13:20:14 +02:00
SimonGschnell f38b0cf78f changes all the Headers from the CISHTML-Header to the CISVUE-Header 2024-09-30 11:58:20 +02:00
SimonGschnell 964f6c689c removes debugging prints 2024-09-30 11:44:31 +02:00
SimonGschnell 4a5a019841 loads the menu for the CISVUE-Header in the server side and not in the client side 2024-09-30 11:33:55 +02:00
SimonGschnell 24a2b4ba2f fixes the bug where the Menu is still selected in the LvModal after clicking on the back button 2024-09-30 11:20:20 +02:00
SimonGschnell 8c6f9d1bc4 loads the menu for the CISVUE-Header in the server side instead of the client side 2024-09-30 11:14:34 +02:00
SimonGschnell 0e385e8628 makes the menu of the CISVUE-Header also sticky now 2024-09-30 10:30:11 +02:00
SimonGschnell bbed90c814 moves the searchbar from the mobile view to the top of the header 2024-09-30 10:26:23 +02:00
SimonGschnell c0596c08c5 changes the header for the Dashboard to the CISVUE-Header and passes the selectedTypes props to fix the CISVUE Header search 2024-09-30 09:43:26 +02:00
SimonGschnell d1070656ac CIS4 MENU sql update COMPLETE 2024-09-27 13:38:29 +02:00
SimonGschnell 23badc3404 CIS4 MENU sql update WIP 2024-09-27 12:20:37 +02:00
ma0048 0f708f4934 - added app pep
- phrases
- added error
- added model
2024-09-27 11:23:54 +02:00
SimonGschnell 73a2bf59f3 resolves buggs with the checkActiveUrl method 2024-09-27 10:44:09 +02:00
Harald Bamberger be412abebc Merge branch 'master' into feature-40896/kennzeichnung_unruly_person 2024-09-26 16:16:24 +02:00
SimonGschnell bc6bc930fe moves the news titel to the component and adds css classes for darker dropdown buttons for the different menu levels 2024-09-26 12:05:44 +02:00
SimonGschnell b174818ed2 updates the active state of the menu based on the changed url 2024-09-25 15:02:35 +02:00
SimonGschnell b0a78658cf also makes the menu points active which redirect to an url hash 2024-09-25 13:35:41 +02:00
SimonGschnell a1fade0489 fixes the recursive function to find a child content_id 2024-09-25 12:25:19 +02:00
Harald Bamberger 2fc0827d49 revert erroneously merged pull request 2024-09-25 11:22:59 +02:00
SimonGschnell 951d5bb2c7 all the parents of an active child are also active 2024-09-25 10:46:09 +02:00
SimonGschnell 3c050438b3 makes the dropdown button of the menu points darker to make them more visible 2024-09-25 09:26:08 +02:00
Christian Paminger 90931232d9 Merge pull request #49 from FortySeeds/master
Enable HTTP-Basic Auth for Demo and Testing
2024-09-25 05:57:13 +02:00
Christian Paminger 427a301d1a Merge branch 'FH-Complete:master' into master 2024-09-25 05:51:11 +02:00
Christian Paminger f66c3466ed Extend HTTP-Basic-Auth for Demo-Mode and easier testing 2024-09-25 05:40:04 +02:00
SimonGschnell 7ed7ce1bb9 active Menu Entry logic for CISVUE 2024-09-24 14:57:41 +02:00
Andreas Österreicher b184cee975 Offset für das Laden von Geschaeftsjahren hinzugefügt 2024-09-24 12:40:12 +02:00
ma0048 419f608322 - benotung international skills hinzugefügt
- phrase
2024-09-24 12:05:09 +02:00
Andreas Österreicher 5d70f72cc2 Merge branch 'feature-40348/UHSTAT_1_Unbekannte_Eltern' 2024-09-24 11:22:34 +02:00
KarpAlex 5057b2d761 bugfix unbekannte Eltern: unknown can always be chosen, and it is valid. Only if Land des Abschlusses in austria, austrian max Bildung options can be chosen 2024-09-23 18:27:19 +02:00
SimonGschnell 470192aabd fixes some bugs in the View/Entry.php for the Menu 2024-09-23 15:14:31 +02:00
SimonGschnell 45d350a76e changes the header for the news and puts the LV title in the card header / removes the lines of the lehrveranstaltungs optionenen 2024-09-23 13:24:58 +02:00
Alexei Karpenko 3b20f5e45c Plausichecks: removed check BewerberNichtZumRtAngetreten 2024-09-20 16:12:14 +02:00
Alexei Karpenko 2d3643d1f0 Bismeldestichtag: added method for getting next Meldestichtag, loading data only after tabulator is ready 2024-09-20 16:04:27 +02:00
Johann Hoffmann effad6f62d only fetch person_id, vorname, nachname & unruly from tbl_person on checkUnruly() 2024-09-20 15:16:20 +02:00
SimonGschnell 98c85f1241 little changes to the view for the content 2024-09-20 14:20:44 +02:00
Johann Hoffmann 958c897467 changed unruly html from a tags to p tags since they messed with styles somehow 2024-09-20 13:54:32 +02:00
Johann Hoffmann a2e4704223 developing new components in lektor ui for ux improvements; anw function now explicitely in extension schema 2024-09-20 13:12:50 +02:00
SimonGschnell 9343d1ee0c refactor Content_types template 2024-09-20 11:26:08 +02:00
SimonGschnell ca4865011d adds missing parameters to the getContent function 2024-09-20 11:21:59 +02:00
SimonGschnell 693313a23b renames/reuses lv-modal and fixes bugs associated with the modal 2024-09-19 09:35:36 +02:00
SimonGschnell b9fd95741d moves the CalendarModal into the Stundenplan component instead of the Calendar component and changes the start_time and end_time computed properties 2024-09-18 14:40:58 +02:00
SimonGschnell 5877411db8 also loads the stundenplan data when the component is created 2024-09-18 13:52:49 +02:00
SimonGschnell f7b3af4939 makes the studiengang_semester reactive using computed when providing the value 2024-09-18 13:17:14 +02:00
SimonGschnell 164fc4b132 converts the dropdown of the lehrveranstaltungs optionen into a list inside the lv card 2024-09-18 12:52:55 +02:00
Andreas Österreicher e6eea06900 Merge branch 'feature-40348/UHSTAT1_unbekannte_Eltern' 2024-09-18 12:41:05 +02:00
Andreas Österreicher f499110bbf Merge branch 'feature-41046/wartende_anschreiben_onetimemessages_abgewiesene_werden_nicht_ausgefiltert' 2024-09-18 12:28:50 +02:00
Andreas Österreicher d0281bb3b4 Merge branch 'feature-47888/projektarbeit_endabgabe' 2024-09-18 12:24:37 +02:00
SimonGschnell 910a467fcc changes the stundenplan widget to use the new api endpoints that query the stundenplan events 2024-09-18 11:44:47 +02:00
ma0048 91174ca974 - schickt message, nur wenn wartender der letzte status ist 2024-09-17 15:35:00 +02:00
Johann Hoffmann 79ea8c4521 renamed unrulyPerson api to checkPerson; built in logic into infoCenterDetails to trigger a number of checks about any changed data in the info center (in this case unruly) and update the page accordingly; Also fixed a bug when saving stammdaten without kontakt entries; 2024-09-17 14:09:49 +02:00
SimonGschnell 6edc411a95 adds the LvMenu as dropdown options to the MyLV 2024-09-17 12:34:47 +02:00
SimonGschnell 5ca639101c fixes Month display of LVs 2024-09-17 11:39:39 +02:00
ma0048 7c85e981f9 - absteigende sortierung endabgabe 2024-09-17 11:17:44 +02:00
SimonGschnell d931aad11c solves reactive data problem in CalendarModal 2024-09-17 09:41:17 +02:00
SimonGschnell 61e6ad063a solves Telefon displaying as null for some benutzer 2024-09-17 09:28:11 +02:00
Cris 2f0514092a Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-09-16 16:20:12 +02:00
SimonGschnell e1c395146b refactors the LvMenu into its own component and removes debugging prints 2024-09-16 14:55:26 +02:00
Harald Bamberger 363a014298 Merge branch 'feature-39161/PV21_Valorisierung' 2024-09-16 09:17:51 +02:00
SimonGschnell 4836ed8de0 adds LvMenu to the CalendarModel WIP 2024-09-13 13:44:53 +02:00
SimonGschnell b30156a65f catches errors better in Profil 2024-09-13 12:42:57 +02:00
Harald Bamberger d6966b24fe Merge branch 'master' into feature-39161/PV21_Valorisierung 2024-09-13 12:39:05 +02:00
SimonGschnell 88c38c9228 fixes ProfilUpdate bugs 2024-09-13 12:37:13 +02:00
SimonGschnell cf1cb44afa refactors old ProfilUpdate controller functions 2024-09-13 12:27:07 +02:00
SimonGschnell 2b9406b172 resolves zustellnungs value bug and removes debugging prints 2024-09-13 11:15:46 +02:00
Johann Hoffmann 27c312d7d3 filterPerson unrulyPerson api & person model 2024-09-12 15:42:21 +02:00
SimonGschnell 29fac520f3 component was setting the topic false when trying to delete a kontakt or an adresse 2024-09-12 12:04:42 +02:00
SimonGschnell 1208c6829c when an error happenes to editProfil Modal will also be closed then 2024-09-12 11:53:13 +02:00
SimonGschnell 1de8c00990 fixes an error where the payload i treated like an object but is an associative array in the controller 2024-09-12 11:45:54 +02:00
SimonGschnell e247621f95 fixes the profilBearbeiten phrase and does update the topic correctly when adding a new kontakt/addresse in the profil 2024-09-12 10:47:31 +02:00
SimonGschnell cfea7e10f2 adds the reservierungen overview action for the search result with a room object and removes debugging prints 2024-09-11 14:51:52 +02:00
SimonGschnell 6cf3896d49 fixes Calendar.js 2024-09-11 14:38:00 +02:00
Andreas Österreicher b2dbe65739 Berechtigungen korrigiert beim Setzen von Unruly People 2024-09-11 14:32:47 +02:00
SimonGschnell cf4105dcb3 Merge branch 'feature-25999/C4_copy' into feature-25999/C4 2024-09-11 14:07:25 +02:00
SimonGschnell b79a3bd5e9 Merge branch 'master' into feature-25999/C4 2024-09-11 14:06:49 +02:00
SimonGschnell 04aaefd5d8 refetches the Stundenplan events also for the Stundenplan and not only for the roomplan 2024-09-11 14:00:53 +02:00
SimonGschnell aef267186f removes typo and debugging print from Calendar.js 2024-09-11 13:56:39 +02:00
SimonGschnell d80761d952 Merge branch 'feature-39912/Room_planning_calendar' into feature-25999/C4_copy 2024-09-11 13:54:45 +02:00
SimonGschnell 8860d9a598 adds quick fix for the query builder error that comes up when fetching content 2024-09-11 11:26:04 +02:00
SimonGschnell f2a57f85a8 fixes the errors with the stundenplan/reservierungen data query 2024-09-11 10:19:46 +02:00
SimonGschnell ac35ba3e27 puts the logic that adds the object informtion to the json reponse in the controllers instead of the models 2024-09-11 09:50:04 +02:00
SimonGschnell 1de658ace6 fixes the query for the reservierungen in the stundenplan and in the raum informations 2024-09-11 09:32:28 +02:00
SimonGschnell 715b8075b8 reworks the query for the reservierungen stundenplan/room 2024-09-10 12:30:40 +02:00
Andreas Österreicher 555e74b8cd Projektexport ist jetzt auch möglich wenn aktuell keine Projekte
zugeordnet sind
2024-09-10 11:48:43 +02:00
Johann Hoffmann 79d23a4557 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp
# Conflicts:
#	public/js/components/Form/Upload/Dms.js
2024-09-10 11:25:19 +02:00
Johann Hoffmann 6bc58c00b7 unruly controller benutzerrechte; studstatus unruly api fix; 2024-09-10 10:50:02 +02:00
Johann Hoffmann d9f5646ad1 Merge branch 'master' into feature-40896/kennzeichnung_unruly_person
# Conflicts:
#	application/models/crm/Prestudentstatus_model.php
#	public/js/api/fhcapifactory.js
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2024-09-10 10:17:55 +02:00
Johann Hoffmann 888e3878bd studstatus unruly als grund 2024-09-09 17:16:05 +02:00
SimonGschnell 7b110aaf50 adds the needed phrase to the api/frontend/v1/Cms Controller 2024-09-09 14:16:37 +02:00
SimonGschnell 7a63301f08 puts profil settings ul outside of the sticky container 2024-09-09 13:49:38 +02:00
Harald Bamberger 5f50d9f0ec Merge branch 'feature-40311/Stundenplan_widget' into feature-25999/C4 2024-09-09 13:26:03 +02:00
SimonGschnell 26a0521379 fixes fhcapi 2024-09-09 13:12:11 +02:00
Harald Bamberger 996a49105b Merge branch 'feature-40309/Cis_News_widget' into feature-25999/C4 2024-09-09 13:03:47 +02:00
Harald Bamberger ff51d3964f Merge branch 'feature-40842/DashboardAmpeln' into feature-25999/C4 2024-09-09 12:56:55 +02:00
Harald Bamberger c2c30b86a1 Merge branch 'feature-40841/SearchBarChanges' into feature-25999/C4 2024-09-09 12:02:09 +02:00
Harald Bamberger 97b34d98fb Merge branch 'feature-41133/side_menu_sticky' into feature-25999/C4 2024-09-09 11:51:34 +02:00
Harald Bamberger 1f4628720a Merge branch 'feature-39911/Suche_um_raeume_erweitern' into feature-25999/C4 2024-09-09 11:50:27 +02:00
Harald Bamberger a8141e5dac Merge branch 'master' into feature-25999/C4 2024-09-09 11:45:10 +02:00
Johann Hoffmann 33122a0708 WIP performance testing & UI upgrades 2024-09-09 10:49:21 +02:00
Cris 92abfb8b58 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-09-09 10:26:07 +02:00
SimonGschnell ec8b3ccb6f adds the organisations bezeichnung through a subquery to the lehrveranstaltungs events 2024-09-06 13:11:22 +02:00
SimonGschnell 122673d291 gets rid of the stunden dependency and uses the beginn and ende property of the queried events 2024-09-06 11:20:20 +02:00
SimonGschnell 8376e8b92d bundles the room_events and the reservierungen api calls together with Promise.allSettled 2024-09-06 11:02:14 +02:00
Harald Bamberger 493405951d zusaetzlicher Filter bei Handyverwaltung nach beendeten DVs 2024-09-05 16:31:56 +02:00
SimonGschnell f9b69fe08c changes how the reservierungen are fetched from the database to have the same information as the room events 2024-09-05 14:57:57 +02:00
SimonGschnell e33162d20e changes the structure of the JSON data from the stundenplan 2024-09-04 14:59:56 +02:00
Cris 0e39cfd4e3 Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite 2024-09-04 11:01:01 +02:00
Cris fda03b88df Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-09-04 11:00:24 +02:00
Cris f74ccb0513 Removed column Lehreinheitgruppen 2024-09-04 10:59:46 +02:00
Cris 6076d59c4b Removed Group by Organisationseinheit
Instead added Organisationseinheit as column for filtering reasons.
Column is invisible by default.
2024-09-04 10:59:25 +02:00
SimonGschnell 87f82b7f5d also adds the stundenplan information as object in the response of the endpoint 2024-09-03 12:07:13 +02:00
SimonGschnell f19c1b4eaf adds the lector and the gruppe as objects to the endpoint result instead of just strings 2024-09-02 14:47:40 +02:00
SimonGschnell 8c5ca521ac adopts the side menu for the desktop and mobile view 2024-09-02 10:42:01 +02:00
ma0048 7dc7816123 - fas neuer filter ueberfaellige buchungen 2024-08-30 08:21:35 +02:00
Johann Hoffmann d03678e3dc WIP 2024-08-27 15:30:17 +02:00
Andreas Österreicher ec6efc5c2b Added studiengang_kz to Akadgrad DropDown 2024-08-21 16:54:22 +02:00
Cris f2be396e7a Adapted to use new fhcApi.getUri method 2024-08-21 13:53:49 +02:00
Cris 0c4d1afded Merge branch 'master' into feature-40953/LV-Template_Uebersichtsseite
# Conflicts:
#	system/phrasesupdate.php
2024-08-21 13:46:41 +02:00
Cris 67a48c6f75 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-08-21 13:44:32 +02:00
Cris 7fb7263424 Added phrases for LV Templates Overview 2024-08-21 13:34:11 +02:00
Cris e5e4bb2ea1 Added Component LvTemplateUebersicht.js 2024-08-21 13:32:37 +02:00
Cris fc8c748bc4 Added View LvTemplateUebersicht.php 2024-08-21 13:32:14 +02:00
Cris eb308b78ef Added App LvTemplates.js 2024-08-21 13:28:56 +02:00
Cris 6168a6b806 Added Controller LvTemplateUebersicht.php 2024-08-21 13:26:20 +02:00
Cris d07f19d893 Added api Controller Studiensemester.php + methods getAll and getAktNext 2024-08-21 13:23:26 +02:00
Cris bff5d4ffbe Added api Controller Lehrveranstaltung.php + method getTemplateLvTree 2024-08-21 13:22:15 +02:00
Cris 4dc698a6be Added navigation menu item 'Lehrveranstaltungen' > 'LV Template Uebersicht' 2024-08-21 13:17:54 +02:00
Cris 3963358d95 Added getTemplateLvTree method to Lehrveranstaltung_model.php
This method gets all Templates and unions with all Lehrveranstaltungen of given Studiensemester and Oes, that are assigned to
a template. This data structure can be used for nested tabulator data tree.
2024-08-21 13:16:22 +02:00
cgfhtw a2f9fba896 Bugfix: Favorites: Correct loading procedure for Prestudent-Subverbände 2024-08-21 12:50:58 +02:00
Andreas Österreicher 97b171176a Merge branch 'feature-44041/AntragJob_Abmeldungen_durch_Stg_config_mismatch' 2024-08-19 13:33:38 +02:00
cgfhtw a594ddeb75 AntragJob: Abmeldungen durch Stg config mismatch 2024-08-19 13:08:12 +02:00
Harald Bamberger ebd5aebd33 Merge branch 'feature-39579/Studierendenverwaltung_stabilisieren' 2024-08-14 13:59:18 +02:00
cgfhtw f771b54f10 StV: Favorites use now correct API return functions 2024-08-14 09:16:11 +02:00
cgfhtw 67398607d8 dbupdate entry 2024-08-14 09:11:14 +02:00
cgfhtw d33163aae8 Add stv_favorites to variablenames 2024-08-14 09:09:13 +02:00
Harald Bamberger 2c6212f75f fix reuse of for multiple purposes overwriting each other 2024-08-14 07:36:14 +02:00
KarpAlex 30396b3f0e Merge remote-tracking branch 'origin/feature-40728/Issues_logik_auslagern_in_eigene_library' into feature-39161/PV21_Valorisierung 2024-08-13 18:32:15 +02:00
Harald Bamberger 336cfa8667 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' 2024-08-13 17:27:28 +02:00
Alexei Karpenko 8a9e040554 added Gehaltstyp model 2024-08-13 16:57:05 +02:00
Harald Bamberger 2bd578edb3 remove unused Abstract_Searchbar_Controller 2024-08-13 16:42:09 +02:00
SimonGschnell 3a466e8e0f puts nav-toggle and nav-menu-items in a sticky container 2024-08-13 15:27:51 +02:00
SimonGschnell 8bc8c67f8d better comments 2024-08-13 15:10:23 +02:00
SimonGschnell 36bd1795ed makes the cis4 side menu sticky 2024-08-13 15:04:44 +02:00
cgfhtw 308412b5a3 Bugfix Creditpoints 2024-08-13 15:00:13 +02:00
cgfhtw e24c610bf1 Studiensemester now: change getAkt to getNearest 2024-08-13 14:59:54 +02:00
cgfhtw 2e3576b06e Bugfix: Advance Status: object in array 2024-08-13 14:34:53 +02:00
cgfhtw 98f335ec00 mising fileextension on import in Prompt.js 2024-08-13 14:30:25 +02:00
cgfhtw 50a96b3e4f Prestudent History: Wrong Function for Permissioncheck 2024-08-13 14:20:40 +02:00
Harald Bamberger 5d169e188a move permissions from abstract to concrete Notiz Controller 2024-08-13 14:12:55 +02:00
cgfhtw 4fc61c342c Prestudent Permissions 2024-08-13 13:52:04 +02:00
cgfhtw f8f352fe65 Students Permissions 2024-08-13 13:41:35 +02:00
cgfhtw a988ff20c8 Notiz Permissions 2024-08-13 13:38:09 +02:00
cgfhtw 6fb050fa58 Tab Config Permissions 2024-08-13 13:32:29 +02:00
cgfhtw f9a41b9685 Studienplan & Studiensemester => Auth Controller 2024-08-13 13:25:10 +02:00
cgfhtw e5217afc09 ZGV Ausstellungsstaat 2024-08-13 13:10:11 +02:00
cgfhtw 3d07aa3bd0 UDFs Prestudent aktivieren 2024-08-13 11:29:24 +02:00
cgfhtw 761ec96662 Bugfix: uft8 json & codequality 2024-08-13 11:20:32 +02:00
cgfhtw ed69d3a061 Prestudenttab einzelne Felder ausblenden 2024-08-13 11:05:35 +02:00
cgfhtw db8e2bfb69 Interessent hinzufügen und Notenkarteireiter ausblenden 2024-08-13 11:01:49 +02:00
cgfhtw 307ee8fb56 Berechtigungscheck f. Studentenverwaltung Controller 2024-08-13 09:00:49 +02:00
cgfhtw d025359f72 Berechtigungscheck Verbandstree 2024-08-13 08:51:01 +02:00
cgfhtw 9ac9ab6818 Berechtigungscheck Studentenliste 2024-08-12 16:02:06 +02:00
cgfhtw a45fd217d9 Berechtigungscheck Details 2024-08-12 15:59:23 +02:00
cgfhtw d3025dc4a8 Berechtigungscheck Kontakt 2024-08-12 15:59:15 +02:00
SimonGschnell cce58fdc31 removes debugging prints 2024-08-12 14:24:37 +02:00
Johann Hoffmann 8232224b21 LvMenu.php added codeigniter phrasen object to params; Using ci_phrases in Events.php for cis4 menu; 2024-08-12 14:20:42 +02:00
Harald Bamberger 38e1308865 revert change on already deprcated file 2024-08-12 14:12:01 +02:00
SimonGschnell 73dd89e5af adds phrasen library to LvMenu 2024-08-12 14:09:21 +02:00
cgfhtw 054e59a891 Bugfixes PrestudentLib 2024-08-12 12:22:43 +02:00
cgfhtw 097a507c9a Bugfix: missing data in showFeedback function 2024-08-12 09:54:23 +02:00
cgfhtw 47ddebf7c4 Bugfix: wrong variablename 2024-08-12 09:54:00 +02:00
cgfhtw d19a47d4b2 Bugfix: missing load->library 2024-08-12 09:47:13 +02:00
cgfhtw fea7ed8f76 copy pasta 2024-08-12 09:45:34 +02:00
cgfhtw 0a150a60bb improved error message 2024-08-12 09:44:12 +02:00
cgfhtw 781b4b31cd Bugfix: misspelled function call 2024-08-12 09:43:45 +02:00
cgfhtw fe7b05cce2 Merge branch 'master' into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-08-12 08:34:32 +02:00
KarpAlex 20ed9ffc41 UHSTAT Formular: added "unknown" options to every input 2024-08-11 21:59:13 +02:00
SimonGschnell d7abc41137 adds digitaleAnwesenheiten menu point 2024-08-09 13:32:00 +02:00
cgfhtw c378ec4347 Remove unnecessary comments 2024-08-09 13:26:07 +02:00
cgfhtw 7e302adf53 Bugfix in Prestudent model 2024-08-09 13:25:42 +02:00
cgfhtw 02c12c6a54 Bugfixes in PrestudentstatusCheckLib 2024-08-09 13:25:21 +02:00
cgfhtw d57bd7d7ba Bugfixes in Students Controller 2024-08-09 13:24:39 +02:00
cgfhtw 59e501e52b use new FHCAPI features in UDF controller 2024-08-09 13:23:41 +02:00
ma0048 6f0575304c - ent/sperren mit hochkomma bug fixed 2024-08-09 11:54:01 +02:00
cgfhtw 8b1ade86ac revert wrong changes from "adapt function toolbarInteressent, Phrases" 2024-08-08 16:39:47 +02:00
cgfhtw ffabd681c8 setFirstStudent logic 2024-08-08 16:24:23 +02:00
cgfhtw f1a2ef25c7 Remove unused functions 2024-08-08 12:45:36 +02:00
ma0068 b54449012b implement version without processLehrverband for setAbbrecher and setUnterbrecher 2024-08-08 11:30:56 +02:00
cgfhtw 0f75b269c3 remove comment 2024-08-07 16:55:20 +02:00
cgfhtw 8fbd680ebd correct rolle_doesnt_exist validation in addStudent 2024-08-07 16:25:56 +02:00
cgfhtw dad5127d4c addStudent validation 2024-08-07 16:19:30 +02:00
cgfhtw ac29247783 checkIfLastBewerberAndAufgenommenerShareSemesters 2024-08-07 16:19:15 +02:00
cgfhtw 59314ae0aa correct rolle exists check 2024-08-07 15:56:07 +02:00
cgfhtw 24d74dd332 correct student check 2024-08-07 15:51:19 +02:00
SimonGschnell ba2c450bd2 uses the codeigniter querybuilder to construct the active ampeln query 2024-08-07 15:43:20 +02:00
cgfhtw 0621073f8d correct checkIfExistingAufgenommenerstatus 2024-08-07 15:40:11 +02:00
cgfhtw 1fc7f9d3e8 correct checkIfExistingBewerberstatus 2024-08-07 15:37:43 +02:00
SimonGschnell 3f86961bda adds parameter to ampeln deadline/overdue phrase 2024-08-07 15:21:22 +02:00
cgfhtw 05e0d219f4 Codequality 2024-08-07 14:32:44 +02:00
cgfhtw 8b590dc58a optimizing Ampel Widget 2024-08-07 14:23:35 +02:00
SimonGschnell a6bef31862 corrects filter styling problem 2024-08-07 12:00:24 +02:00
cgfhtw e7a29dc21a Identation 2024-08-07 11:56:00 +02:00
SimonGschnell ceb8eb9671 corrects the way how to active ampeln check whether an ampel was bestaetigt or not and adds the Ampel_Benutzer_Bestaetigt_model 2024-08-07 11:52:50 +02:00
cgfhtw e89677c36d Comments 2024-08-07 11:08:39 +02:00
cgfhtw 4b7e445a25 Bugfixes: Eventobject as parameter 2024-08-07 09:53:40 +02:00
SimonGschnell 47a4b63172 changes the zustellungs warning for the Profil Adressen/Kontakte 2024-08-07 09:53:37 +02:00
cgfhtw 911eb66c4a Missing : 2024-08-07 09:44:28 +02:00
cgfhtw 428a56cfd0 Cleanup MultiStatus Component & Dropdown Component 2024-08-07 09:41:36 +02:00
cgfhtw 9af8117749 add statusgrund_id 2024-08-06 16:53:48 +02:00
cgfhtw baa7417c22 Status: Wartender 2024-08-06 16:49:11 +02:00
cgfhtw 6dd779b421 Status Abgewiesener 2024-08-06 16:47:12 +02:00
cgfhtw b3e105908b Fix Status Absolvent & Bewerber 2024-08-06 16:41:38 +02:00
cgfhtw f87277e1f2 Status: Aufgenommener & code reuse 2024-08-06 16:35:59 +02:00
cgfhtw 749b29a239 Status: Bewerber 2024-08-06 16:30:50 +02:00
cgfhtw 942e8a9229 Status: Absolvent 2024-08-06 16:27:45 +02:00
cgfhtw 09a0536921 Status Diplomand 2024-08-06 16:24:38 +02:00
cgfhtw 21e69c6d94 Status: Unterbrecher & Student 2024-08-06 16:19:35 +02:00
cgfhtw 07400e7551 change all setAbbrecher to setAbbrecherNeu and rename 2024-08-06 14:49:20 +02:00
SimonGschnell 46a0706057 updates roomEvents on change:range / groups the results of a studenplan query 2024-08-06 14:29:24 +02:00
cgfhtw e6676e8868 setAbbrecherNeu 2024-08-06 14:26:52 +02:00
cgfhtw 9b034a6753 Status cleanup 2024-08-06 14:21:53 +02:00
cgfhtw ee78a94aa2 codesniff Prestudentstatus_model 2024-08-06 14:20:22 +02:00
cgfhtw 34db041ac4 Status Frontend cleanup 2024-08-06 14:19:54 +02:00
Cris 7abe95ba5f Adapted LvsByStudienplan query to retrieve also Lehreinheitgruppen 2024-08-06 10:48:20 +02:00
ma0068 50b15b9506 codesniff libs 2024-08-06 09:47:39 +02:00
ma0068 235a8a73e9 codessniff studentlehrverband_model 2024-08-06 08:49:23 +02:00
ma0068 a728d20b70 codesniff Models 2024-08-06 08:42:20 +02:00
ma0068 a78976b136 codesniff Status.php 2024-08-06 08:21:02 +02:00
ma0068 437fd64a6f refactor setFunctions and processStudentlehrverband 2024-08-05 16:52:46 +02:00
SimonGschnell f0db878623 changes the headers from the news template from h5 to h2 but adds the bootstrap h5 class 2024-08-05 11:48:57 +02:00
Cris b0821be465 Added methods getLastOrAktStudienjahr / getAktOrNextStudienjahr to retrieve the last or next Studienjahr during the summer term 2024-08-05 10:52:15 +02:00
SimonGschnell e44c1bccb3 adds shorthands with getDataOrTerminateWithError and adds also form_validation 2024-08-05 09:17:04 +02:00
SimonGschnell b350c9da56 refactors the news controller 2024-08-02 14:46:22 +02:00
cgfhtw a555067c43 Prepare for Translated fields in DB_Model 2024-08-02 14:24:50 +02:00
ma0068 90162ed2c9 refactor generate alias, add transaction to addStatus 2024-08-02 13:55:46 +02:00
SimonGschnell c5f57a0689 adds the bestaetigt property of the ampel when fetching all the active ampeln 2024-08-02 12:52:21 +02:00
SimonGschnell 3bb87ef8d3 corrects the translation of the ampel queries 2024-08-02 11:44:58 +02:00
SimonGschnell 4811f223b9 corrects little typo 2024-08-02 11:01:32 +02:00
SimonGschnell e6ba291549 adds the translation of the beschreibung and the buttontext in the Ampel_model and not in the Ampel controller 2024-08-02 11:00:11 +02:00
SimonGschnell 9e1bd2b64d adds form_validation 2024-08-02 10:36:34 +02:00
chfhtw fb6bca0ffb Merge pull request #46 from FH-Complete/feature-41134/bookmark_dashboardWidget
Feature 41134/bookmark dashboard widget
2024-08-02 09:59:51 +02:00
SimonGschnell 2de307682c convert identation to tabs 2024-08-02 09:26:39 +02:00
ma0068 9dc421e789 Form Validations addStudent 2024-08-02 08:25:53 +02:00
SimonGschnell 1d4f03e3f1 adds single phrase 2024-08-02 08:24:57 +02:00
SimonGschnell d4e33eb1df refactor 2024-08-01 15:04:18 +02:00
SimonGschnell 4317d5ebe9 tab spaces/ catch alerts 2024-08-01 14:16:20 +02:00
Cris 9bec0c61de Merge branch 'master' into feature-40319/SWB_Software-und-Lizenzanforderung
# Conflicts:
#	system/phrasesupdate.php
2024-08-01 13:55:51 +02:00
Cris d301a66f57 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-08-01 13:53:58 +02:00
Cris 3213c051b3 Adapted getLvsByStudienplan query to get by given Lehrveranstaltungen 2024-08-01 13:48:06 +02:00
cgfhtw 6f0e46ac57 Status: Max Semester 2024-08-01 12:57:06 +02:00
ma0068 f2180257c5 adapt validation changeStatus 2024-08-01 12:45:55 +02:00
SimonGschnell 6fcc8cf7e8 code review changes 2024-08-01 11:49:14 +02:00
ma0068 96b8d49ef2 add changeStatus to PermissionChecks 2024-08-01 08:52:38 +02:00
ma0068 0be45703b5 validation checks changeStatus 2024-08-01 08:43:59 +02:00
cgfhtw e548e17776 Status insert/edit: Orgform in Mischform Stg 2024-07-31 15:09:09 +02:00
SimonGschnell bd7e45547f adds Phrasen to the Stundenplan dashboard widget 2024-07-31 14:51:43 +02:00
Johann Hoffmann c9471c344d added unruly person boolean column to tbl_person; studStatus/leitung added a checkbox to mark persons as unruly unrelated to studstatus datastate; 2024-07-31 14:37:26 +02:00
SimonGschnell 3641047963 adds bookmark phrasen and makes the data shared between the dashboard widget and the configuration view of the widget 2024-07-31 13:51:34 +02:00
cgfhtw cf440ffb43 Shared Data in Widget Component and Widget Config Component 2024-07-31 13:13:16 +02:00
SimonGschnell c2be0a4790 adds content to Url.js 2024-07-31 12:41:03 +02:00
Cris 085ca2a16d Adapted getLvsByStudienplan query to get all LVs, not only VZ 2024-07-31 11:44:42 +02:00
cgfhtw 009360a127 Confirm Status Message 2024-07-31 09:45:20 +02:00
SimonGschnell 8c84a63757 corrects how both the ampel and the ui phrasen are loaded 2024-07-31 09:40:50 +02:00
ma0068 3d27c68dee adapt functions toolbarInteressent, Phrases 2024-07-31 09:06:42 +02:00
cgfhtw 10444e31ce Add Comment 2024-07-30 16:39:59 +02:00
cgfhtw 8492a0aa13 Advance Status 2024-07-30 16:37:39 +02:00
Cris 6f216dbe52 Added phrases to Softwarebereitstellung 2024-07-30 15:38:36 +02:00
Cris 49bd14496a Adapted db query to get Lehrveranstaltungen via Studienplan instead of Lehreinheit 2024-07-30 15:38:02 +02:00
Cris 414a0d7d6e Changed filter SoftwareManagement to display column anzahl_lizenzen 2024-07-30 15:36:16 +02:00
SimonGschnell 39574c1b3a adds delete endpoint for the dashboard bookmark widget 2024-07-30 15:27:24 +02:00
SimonGschnell 198b866268 adds fhcalert when confirming an ampel 2024-07-30 12:37:05 +02:00
SimonGschnell 02cf36c17c adds Phrasen to the dashboard ampel-widget 2024-07-30 12:25:26 +02:00
cgfhtw b423fff074 Status Delete: cleanup 2024-07-30 11:49:00 +02:00
cgfhtw 96b9571ee1 Delete Status: correct confirm 2024-07-30 11:40:57 +02:00
cgfhtw 25d6d9b59e Finish Status delete & correct updateLehrverbandForInsertAndUpdate 2024-07-30 11:36:43 +02:00
SimonGschnell 284cf711fd adds the sql scripts to create dashboard.tbl_bookmark and dashboard.tbl_bookmark_sequence 2024-07-30 11:26:22 +02:00
cgfhtw 1a4f04cb81 Dropdown close & style improvements 2024-07-30 11:16:32 +02:00
cgfhtw dd23bc26a2 Improvements: Status delete 2024-07-30 09:57:37 +02:00
cgfhtw 8a637f3fa9 Fix List Reload Bug 2024-07-30 09:54:46 +02:00
Harald Bamberger d0f3cee7de add permissions for vw_oe_path 2024-07-29 18:11:13 +02:00
Harald Bamberger e6684a0116 add db view that contains oe path 2024-07-29 17:41:24 +02:00
ma0068 f2b81ea68c Bug: Anzeige Statusgrund 2024-07-29 13:58:20 +02:00
SimonGschnell f4210e7671 fixes the Vue component layout for the ampeln dashboardwidget 2024-07-29 13:44:17 +02:00
SimonGschnell 2c45478877 fixes the fetched ampeln in the ampelWidget 2024-07-29 13:17:29 +02:00
ma0068 e81856afb9 Phrases confirmChangeStatus 2024-07-29 11:58:42 +02:00
Alexei Karpenko 88b5fbc4c9 PlausicheckResolverLib: resolving of issues without explicit resolver can also be used in extensions 2024-07-28 19:40:10 +02:00
Alexei Karpenko f1d1c3cbfd issueresolver: improved yet another comment 2024-07-28 19:34:58 +02:00
Alexei Karpenko 6680e9b882 issueresolver: improved another comment 2024-07-28 19:15:27 +02:00
Alexei Karpenko 31a21954d9 issueresolver: improved comment 2024-07-28 19:12:40 +02:00
SimonGschnell 65b71191a0 adds +1 to month in getMonth() function because the month index of a javascript date starts with 0, additional cleanup in Ampel.js Widgett 2024-07-26 15:41:21 +02:00
ma0068 fbcd1bd7de update prestudentlib 2024-07-26 15:01:21 +02:00
SimonGschnell fb30a8e009 translates the ampel queries in separate private function 2024-07-26 14:07:56 +02:00
cgfhtw d4db49e09e Status->isLastStatus corrected 2024-07-26 12:04:20 +02:00
ma0068 32a20f4783 ChangeStatusLogic in component Dropdown 2024-07-26 11:56:52 +02:00
cgfhtw 57e4f585fe Bugfixes Status edit 2024-07-26 11:29:08 +02:00
cgfhtw 916cecca73 Disable Confirm Button if preconditions not met 2024-07-26 09:51:35 +02:00
cgfhtw d286c3784d Popup for Status Confirm 2024-07-26 09:47:15 +02:00
cgfhtw dec08f5eb1 Update/Cleanup ConfirmStatus Endpoint 2024-07-26 09:17:26 +02:00
cgfhtw 0534ab4ac2 corrected Studienpläne Query 2024-07-25 15:51:30 +02:00
SimonGschnell ca6e3a8463 adds endpoint to query all user ampeln that were assigned after the start_working_date with the appropriate beschreibungs translations 2024-07-25 15:16:01 +02:00
cgfhtw e1b179a248 More secure status list 2024-07-25 15:12:59 +02:00
cgfhtw 5ab9acfe89 Dynamic Status List 2024-07-25 15:11:08 +02:00
cgfhtw 3809e6f994 MultiStatus Modal: +Wartender & SkipCheckPermissions & reload Studienpläne on Student change 2024-07-25 14:50:40 +02:00
cgfhtw 60fc774ade Multistatus cleanup 2024-07-25 13:57:00 +02:00
cgfhtw 7250154748 Multistatus Modal as own Component 2024-07-25 13:35:47 +02:00
ma0068 df6f4a07d6 dynamic toolbarStudent 2024-07-25 13:18:13 +02:00
ma0068 a3377a77fa update functions changeStatus, part 1, fix tags 2024-07-25 10:46:45 +02:00
Alexei Karpenko abc74b09b3 Merge branch 'master' into feature-40728/Issues_logik_auslagern_in_eigene_library 2024-07-24 21:15:40 +02:00
cgfhtw 7f0373e0e9 bewerbung_abgeschicktamum rechte 2024-07-24 16:08:46 +02:00
ma0068 df39272544 update dynamic Toolbar Interessent with bootstrap dropdown-menu-right 2024-07-24 15:38:26 +02:00
cgfhtw 70dff47f26 Rearrange/Rename functions & outsource shared code into a subfunction 2024-07-24 15:18:16 +02:00
cgfhtw e42e015410 Status update function 2024-07-24 15:04:19 +02:00
SimonGschnell 0849e795a0 also adds the horizontal line under the heading 2024-07-24 14:59:02 +02:00
SimonGschnell 012cbe9a25 pulls the header out of the content div which makes the headings smaller in the content view with a specific css 2024-07-24 14:57:11 +02:00
SimonGschnell e9d45b6532 removes the old way a modal was shown in the news widget of the dashboard 2024-07-24 14:51:04 +02:00
SimonGschnell 94df440f88 adds a heading to the Content and the News View again 2024-07-24 14:49:58 +02:00
SimonGschnell 4e929f4cce Merge branch 'feature-25999/C4' into feature-40309/Cis_News_widget 2024-07-24 14:40:15 +02:00
SimonGschnell 563f5e5f9e merging C4 2024-07-24 14:37:16 +02:00
SimonGschnell 1e3146d33f dashboardAmpeln 2024-07-24 13:31:00 +02:00
cgfhtw 93b301ee08 Finish Status insert function 2024-07-24 13:24:15 +02:00
SimonGschnell 4b0878b248 Merge branch 'master' into feature-39911/Suche_um_raeume_erweitern 2024-07-24 13:00:52 +02:00
cgfhtw d9cba6bf5c Check orgform student/bewerber 2024-07-24 08:45:48 +02:00
ma0068 7498b327d4 dynamic Toolbars Interessent, Student, update actions interessent 2024-07-24 08:42:19 +02:00
cgfhtw d12f3dd846 Check History for Student status 2024-07-23 14:51:42 +02:00
cgfhtw 7a5bec077f Check Personenkennzeichen 2024-07-23 14:47:23 +02:00
SimonGschnell 1211d63ccf adds placeholders for the ampeln and adds new endpoints that fetch activeAmpeln and confirmedActiveAmpeln of the user 2024-07-23 13:59:04 +02:00
SimonGschnell 7e983292ea adds the endpoint that fetches all ampeln of a user that are not confirmed by the user yet and also removes some unnecessary comments from other enpoints 2024-07-23 11:26:52 +02:00
SimonGschnell 2083e95f8c adds vertical layout for the documents view when the viewport is less than lg 2024-07-23 09:14:38 +02:00
SimonGschnell f207419859 removes the import for userdata and profilUpdate from the old fhcapi which should be replaced by the new fhcapi 2024-07-23 08:58:52 +02:00
cgfhtw 4b97e33e20 comment 2024-07-23 08:58:33 +02:00
SimonGschnell e613ac3255 computes the childactions for the room in the search result independently 2024-07-22 14:33:19 +02:00
SimonGschnell 9170653260 adds a childaction for the rooms when searching for a room to see the eventoverview of the room 2024-07-22 14:07:00 +02:00
cgfhtw 0ee57e488d PrestudentstatusCheckLib: checkIfExistingPrestudentRolle 2024-07-22 13:42:13 +02:00
SimonGschnell f4bf3eec86 merging feature-39911/Suche_um_raeume_erweitern 2024-07-22 12:55:01 +02:00
Cris 0df9385f33 Adapted DB query to filter only Lehrveranstaltungen with lehrtyp_kurzbz 'lv' 2024-07-22 12:02:08 +02:00
SimonGschnell 82417a7f6f removes old api files and removes the use(fhcApi) because it is already imported in the Phrasen plugin 2024-07-22 11:36:12 +02:00
SimonGschnell a0871657ca adds insertFile to the new ProfilUpdate FhcAPIController and starts a transaction when deleting the foreign key from the profil update and deleting the old file 2024-07-22 11:24:47 +02:00
SimonGschnell 0cc6222175 adds deleteProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 14:57:42 +02:00
SimonGschnell 8700abd0fa adds updateProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 14:50:00 +02:00
SimonGschnell 12626511e9 adds insertProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 14:00:40 +02:00
cgfhtw fe4b5bf582 Status insert checks 2024-07-19 13:35:21 +02:00
cgfhtw 31abd39ba8 PrestudentstatusCheckLib: status history 2024-07-19 13:34:56 +02:00
SimonGschnell a06f9b581f adds selectProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 13:11:58 +02:00
SimonGschnell be66150631 adds acceptProfilRequest and denyProfilRequest to the new ProfilUpdate FhcAPIController 2024-07-19 11:38:15 +02:00
SimonGschnell 9eb61649eb adds getProfilRequestFiles to the new ProfilUpdate FhcAPIController 2024-07-19 09:06:49 +02:00
ma0068 4075245dcb getSemesterOfBewerber for Aufgenommen 2024-07-19 09:03:40 +02:00
ma0068 dcb001e0d9 rename addNewStatus to changeStatus 2024-07-19 07:52:52 +02:00
ma0068 de41668e71 ToolbarInteressent, Start with Actions Interessent 2024-07-18 16:46:07 +02:00
SimonGschnell ddd4d5bafe parses the links in the moodle addon dynamically, so that other addons can easily override the phrase used for the links 2024-07-18 14:03:15 +02:00
cgfhtw 9a4061910a Status insert-function: some updates 2024-07-18 13:51:44 +02:00
cgfhtw 7db059b910 PrestudentCheckLib: correct return value for checkIfMeldestichtagErreicht 2024-07-18 13:51:14 +02:00
cgfhtw 605ecb164a Status: clear validation for statusModal 2024-07-18 13:50:30 +02:00
cgfhtw f4376d44a2 Fix Bugs in Bismeldestichtag_model checkIfMeldestichtagErreicht 2024-07-18 13:40:52 +02:00
cgfhtw 5c4c3872f0 Fix missing {{ }} 2024-07-18 13:32:19 +02:00
cgfhtw 69b88b35b9 Status: person name in phrase for modal header 2024-07-18 13:28:18 +02:00
cgfhtw 3514b02960 Status: Saver list reload 2024-07-18 13:27:30 +02:00
cgfhtw b171959920 Improvements to statusModal & use Status insert function in Component 2024-07-18 13:19:28 +02:00
cgfhtw e38e45c283 Status insert-function & better access testing for updateStatus-function 2024-07-18 12:04:35 +02:00
cgfhtw f55b5120ff Auth_Controller helper function for checking stg access rights for a prestudent 2024-07-18 12:03:18 +02:00
cgfhtw 7a8d2986af Checklib fix checkIfExistingStudentRolle & checkIfMeldestichtagErreicht 2024-07-18 12:02:12 +02:00
cgfhtw b62634242a Bismeldestichtag_model fix missing DateTime 2024-07-18 12:01:15 +02:00
SimonGschnell 2711113a69 solves column title race condition 2024-07-18 11:43:08 +02:00
SimonGschnell 328a46f16d adds getTopic to the new ProfilUpdate FhcAPIController 2024-07-18 10:40:30 +02:00
SimonGschnell 885315c22b adds getStatus to the new ProfilUpdate FhcAPIController 2024-07-18 09:52:08 +02:00
SimonGschnell 29aa7f5056 adds isMitarbeiter to the new Profil FhcAPIController 2024-07-18 09:36:30 +02:00
SimonGschnell fdd3026212 adds getAllNationen to the new Profil FhcAPIController 2024-07-18 08:53:45 +02:00
Harald Bamberger 965e23dba7 Merge branch 'feature-40743/Anrechnung_Config-fuer-zusaetzliche-Felder' 2024-07-17 14:08:55 +02:00
cgfhtw 6475eb838e Merge branch 'master' into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-07-17 11:59:40 +02:00
ma0068 287d44f64a add formatted dates to sql query getHistoryPrestudent 2024-07-17 09:20:31 +02:00
Harald Bamberger f064a29efc Merge branch 'master' into feature-40743/Anrechnung_Config-fuer-zusaetzliche-Felder 2024-07-17 08:02:55 +02:00
Harald Bamberger 6dd1dc62bf Merge branch 'feature-39592/vereinfachte_Sicht_fuer_Assistenz' 2024-07-16 20:59:48 +02:00
SimonGschnell da8bb697df change url of Gesamtnote Menu Punkt 2024-07-16 15:42:42 +02:00
SimonGschnell 3417dcd41d centers the text, displays default message and makes # links not clickable and removes the link styling from them 2024-07-16 15:18:23 +02:00
Harald Bamberger fcacd2a660 Merge branch 'master' into feature-39592/vereinfachte_Sicht_fuer_Assistenz 2024-07-16 14:23:16 +02:00
Harald Bamberger 8c9ed2c52c Textaenderung 2024-07-16 14:19:32 +02:00
Harald Bamberger 36aab1b579 Merge branch 'feature-36555/Studstatus_HinweistextFAS_Pruefungsdatum' 2024-07-16 14:11:34 +02:00
Harald Bamberger 3c50ffd945 remove unnecessary style 2024-07-16 14:07:44 +02:00
cgfhtw 7031a4d9c4 Use only active Statusgruende & "--keine Auswahl--" 2024-07-16 09:59:10 +02:00
ma0068 043d876642 bugfix orgform_kurzbz 2024-07-16 09:20:40 +02:00
ma0068 8860969649 bugfix redraw only if table, refactor generate_personenkennzeichen 2024-07-16 07:47:18 +02:00
cgfhtw b8601bac51 Multistatus: copypasta 2024-07-16 07:33:52 +02:00
Harald Bamberger bf1f0428ea use textbox to retain layout 2024-07-15 19:06:19 +02:00
Harald Bamberger f49161420d try to improve layout 2024-07-15 18:18:53 +02:00
Johann Hoffmann 630d2659b3 extension/anwesenheit_assistenz -> extension/anw_ent_admin; removed hardocoded status; check for overlapping excuse timespans; and a lot more ;) 2024-07-15 17:38:13 +02:00
ma0068 58403ff00e bugfixes changeStatus, generateMatrikelnummer, updateLists, validations 2024-07-15 15:41:45 +02:00
cgfhtw 5043f00c97 added missing end tag & removed :value="NULL" since this is not allowed in option tags 2024-07-15 15:16:52 +02:00
cgfhtw 0a457c4bac use "getStudiensemester" from dedicated Lists Controller 2024-07-15 15:13:41 +02:00
ma0068 780dce293d refactor addStudent, bugfix updateList after delete, check organisationsform ersterStudent 2024-07-15 11:57:16 +02:00
cgfhtw 5dbeea80df reload Tables correctly on student change 2024-07-15 11:39:05 +02:00
cgfhtw 9af7ec3ff5 Prefetch Tab config to prevent reloading tabcontent on student change 2024-07-15 10:58:10 +02:00
cgfhtw af127d666d Merge branch 'master' into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-07-15 09:35:19 +02:00
SimonGschnell 14df81cbfb adds c4_linkList and additional styling to the LvUebersicht Menu 2024-07-12 16:14:20 +02:00
SimonGschnell 1614771150 loads content of the menu punkte in iframe inside a full-screen modal 2024-07-12 13:17:44 +02:00
ma0068 eb12b35e37 reload detailtab after changedStatus, update getUserLanguage() 2024-07-12 11:29:38 +02:00
ma0068 19775fac3f Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-07-12 09:23:00 +02:00
ma0068 0bb5cb1fdc bugfix generateMatrikelnnummer, Reihenfolge validierung turnIntoStudent 2024-07-12 09:20:42 +02:00
cgfhtw 78471a2c3a Use Prestudentstatus_model instead of Prestudent_model for status history 2024-07-12 08:30:57 +02:00
Harald Bamberger 464dbba457 add missing api js files 2024-07-11 18:43:31 +02:00
Harald Bamberger 9d455c35d0 Betriebsmittel.js: use arrow function for dynamic ajaxParams, Filter.js: remove required from filterType 2024-07-11 18:32:47 +02:00
Harald Bamberger 3f84024ce8 uncomment null check, layout of hint 2024-07-11 17:35:18 +02:00
KarpAlex e9ae046592 Prestudentstatuschecklib: checks also work when dates of two status are the same 2024-07-11 16:44:22 +02:00
Harald Bamberger 16ab9998b0 Merge branch 'master' into feature-39592/vereinfachte_Sicht_fuer_Assistenz 2024-07-11 14:44:44 +02:00
Cris ce7b368a8e Adapted lv.orgform_kurzbz to selects in Lehrveranstaltung_model.php 2024-07-11 14:33:38 +02:00
cgfhtw 4c862932e8 use CI Model functions for Bismeldestichtag_model->getLastReachedMeldestichtag() 2024-07-11 14:28:29 +02:00
cgfhtw 8a88aa2128 Correctly use FhcApi in Bismeldestichtag 2024-07-11 14:23:53 +02:00
ma0068 3706b0f972 Delete action in Tab Contact and Status: primeVueAlert instead of BSModal 2024-07-11 13:22:11 +02:00
Harald Bamberger 115151473a backport recent changes of Betriebsmittel component and phrases from feature-30660/FHC4_StudierendenGUI_Prototyp Branch 2024-07-11 11:57:45 +02:00
Cris a23b133217 Adapted requestAnrechnung.js to handle submit data and events on Begruendung-zur-Gleichwertigkeit fields
...depending on $config['explain_equivalence']
2024-07-11 10:54:43 +02:00
ma0068 a728bec15f BewerberZuStudent: new action turnIntoStudent 2024-07-11 10:52:59 +02:00
Cris 1139b251ef Adapted Views to handle display of Begruendung-zur-Gleichwertigkeit fields
...depending on $config['explain_equivalence']
2024-07-11 10:52:51 +02:00
Cris 8c3b85066a Adapted Controller RequestAnrechnung.php to handle Begruendung-zur-Gleichwertigkeit fields
...depending on $config['explain_equivalence']
2024-07-11 10:49:05 +02:00
Cris 0b48e94d3c Added config variable $config['explain_equivalence'] (Begruendung zu Gleichwertigkeit)
...to display and enable 'Begründung zu Gleichwertigkeit'-fields
2024-07-11 10:44:12 +02:00
cgfhtw f2ca9f765f StV: Prestudent History disabled class 2024-07-10 16:02:13 +02:00
Harald Bamberger 46ea054bac change text, add config to show hint or not, styling 2024-07-10 15:52:57 +02:00
Cris 03205674aa Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-07-10 15:51:51 +02:00
ma0048 c94f185308 - faktor für lvs hinzugefuegt 2024-07-10 15:13:46 +02:00
Cris eead73f10c Added phrases for core and softwarebereitstellung to phrasesupdate.php 2024-07-10 14:44:01 +02:00
SimonGschnell a83e07350e makes the pinboard link redirect to all news 2024-07-10 11:35:36 +02:00
SimonGschnell d364630d92 instead of modifying the original menu keys, it adds new keys for the cis4 version of the menu 2024-07-10 10:48:24 +02:00
SimonGschnell bc9f247323 replaces wrong quatations in the menu items if the link_onclick array key is defined 2024-07-10 09:10:35 +02:00
cgfhtw a930247eec Cleanup 2024-07-10 08:44:04 +02:00
cgfhtw 108045ac54 Betriebsmittel Compontent: names 2024-07-09 16:14:43 +02:00
cgfhtw cccf85f3d9 StV List: Accessibility fix 2024-07-09 16:10:08 +02:00
SimonGschnell 56080f6681 changes the LVUebersicht and the endpoint 2024-07-09 15:28:28 +02:00
cgfhtw e79a70fc2f Betriebsmittel: stabilized 2024-07-09 14:06:29 +02:00
Harald Bamberger 8b254b3967 Merge branch 'master' into feature-36555/Studstatus_HinweistextFAS_Pruefungsdatum 2024-07-09 11:52:07 +02:00
Harald Bamberger c4ef0f998c Merge branch 'feature-40285/Studstatus_Datum_der_Abmeldung_auf_den_3_Abmeldungsdokumenten' 2024-07-09 11:49:41 +02:00
Harald Bamberger 37fb9dd851 use date that seems more stable than one that depends on a config entry that may change over time and then change the date in previous documents 2024-07-09 11:38:16 +02:00
SimonGschnell 8a44a9e1af passes the menu as a reference to the on Events instead of using a callback function 2024-07-09 10:37:43 +02:00
Harald Bamberger 2a537df687 Merge branch 'master' into feature-40285/Studstatus_Datum_der_Abmeldung_auf_den_3_Abmeldungsdokumenten 2024-07-09 10:35:40 +02:00
SimonGschnell 84029fc729 updates editAdressen in the Profil 2024-07-08 15:15:08 +02:00
Johann Hoffmann 66b151dce0 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp
# Conflicts:
#	system/dbupdate_3.4.php
#	system/phrasesupdate.php
2024-07-08 14:42:01 +02:00
Alexei Karpenko 1a8a7cc260 prestudent model gethistoryprestudent: added order by for insertamum, ext_id 2024-07-08 12:42:32 +02:00
Cris 4d48dfe018 Added method getLvsByStudiensemesterAndOes to Lehrveranstaltung_model.php
getLvsByStudiensemesterAndOes: Gets Lehrveranstaltungen with its Stg, OE and OE-type and filters by Studiensemester and Organisationseinheiten if necessary.
2024-07-08 12:26:41 +02:00
Cris 4e053a4769 Updated phrases: Added phrases for Softwareanforderung in category Softwarebereitstellung 2024-07-08 12:24:44 +02:00
SimonGschnell 0347f8bf02 filters the menu to remove all elements that don't have the position property 2024-07-08 11:43:48 +02:00
SimonGschnell e98f59e984 adds all menu punkte from fh-core to the LvMenu endpoint function 2024-07-08 10:54:39 +02:00
SimonGschnell 578afaeb08 adds fh-core menu logic WIP 2024-07-05 15:21:14 +02:00
SimonGschnell 08555a77be makes contentModal bigger for the room content and uses the raum_info component to insert the tabulator in the content 2024-07-05 10:00:54 +02:00
SimonGschnell 79ffc1c077 creating lvMenu with Event hooks WIP 2024-07-04 15:37:50 +02:00
SimonGschnell 92afdf71cd changing fhcapi for the client side for the profil WIP 2024-07-03 15:53:01 +02:00
SimonGschnell 2a7735bca5 outsources internal queryies to the appropriate classes, to assign the values to the needed variables to fill the menu array of the menu_lv.inc.php 2024-07-03 11:56:18 +02:00
Johann Hoffmann affbe7821a email vorlagen sql insert; trim entschuldigungs begründung to max size; WIP routing; WIP fancy loader overlay; WIP Api Testing; lektor ui finetuning; 2024-07-02 16:51:42 +02:00
SimonGschnell 19753a9ef7 test api endpoint to include the lvinfo menu link 2024-07-02 14:50:54 +02:00
SimonGschnell 57d3d3af13 removes the shared storage for the searchbar and saves the data local in the searchbar again 2024-07-02 10:28:35 +02:00
SimonGschnell 3d2ea2821e fixes little typo, that fails to render the widget 2024-07-02 09:26:19 +02:00
SimonGschnell ff0f2320e1 changes the layout of the searchbar to be the same in the mobile view and in the desktop view 2024-07-01 14:43:43 +02:00
Harald Bamberger dd0bdddbc6 backport recent changes of Betriebsmittel component and phrases from feature-30660/FHC4_StudierendenGUI_Prototyp Branch 2024-07-01 14:12:48 +02:00
SimonGschnell f4f08c0710 stores the local information of the searchbar inside a collected storage in case more than one searchbar is used 2024-07-01 13:53:55 +02:00
SimonGschnell 3e3f005525 changes the layout/buttons of the searchbarsettings, adds responsive searchbar in the header for mobile views 2024-06-28 14:34:41 +02:00
SimonGschnell d0f457d8ed changes the data format from the studierendenEmail api call and displays the mailto on the modal 2024-06-28 11:06:44 +02:00
cgfhtw f5286ae66b Bugfix: Use correct id for attachment preview 2024-06-27 15:55:56 +02:00
cgfhtw 6b4e8df411 remove outcommented code 2024-06-27 15:21:51 +02:00
SimonGschnell c34144a4e8 creates sql query in the lehreinheit_model to query the studierenden Mail inside a lehrveranstaltung and creates the matching fhcapi methods / frontend/v1 api controllers 2024-06-27 15:09:09 +02:00
ma0068 18a6262eaf Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-06-27 14:20:26 +02:00
ma0068 8fa395a582 Refactor Logic Statuschanges 2024-06-27 14:20:11 +02:00
Alexei Karpenko 834d03459b prestudentstatus checks studierendenverwaltung: changed comment 2024-06-27 12:52:12 +02:00
SimonGschnell ffc1241188 news widget 'alle News' redirects to the news URI 2024-06-27 11:53:22 +02:00
cgfhtw 534faef82c Notiz: use dms_id instead of name & code cleanup 2024-06-27 10:29:09 +02:00
cgfhtw 5658e7a0b4 StV: Notizen: getting rid of horizontal scrollbar 2024-06-27 09:42:59 +02:00
cgfhtw b784ad6b26 Notizen: fixing DB transaction in Delete function & Code Cleanup 2024-06-27 09:42:15 +02:00
Alexei Karpenko 32e1e487a9 issues: enabled resolving without explicitely creating a resolver (by using producer method), old resolvers are still working. Created example for "self-resolving" issue: AbbrecherAktiv 2024-06-26 22:46:36 +02:00
SimonGschnell 5070353bf0 passes the active_addons constant to the LvUebersicht Modal 2024-06-26 16:37:54 +02:00
SimonGschnell a540ac3f7e adds a General view for the content_types that dont need any special extra computation 2024-06-26 15:58:50 +02:00
Johann Hoffmann 1305633511 removed 99% of console.logs; fixed entschuldigung update notiz only; added kontrolleDeleteMaxReach Constant from config; updateAnwesenheiten notiz fix; Entschuldigungs studiengang fetch fix; 2024-06-26 15:38:22 +02:00
SimonGschnell 93b7f6e57c fixes little typo 2024-06-26 15:20:19 +02:00
SimonGschnell 4640db5aff adds a view components for the news if the content that gets loaded has the template_kurzbz news 2024-06-26 14:17:44 +02:00
SimonGschnell 478adb740e changes the db query and adopts the layout of the Vue component to show the correct betreff and content of the news 2024-06-26 13:21:32 +02:00
Cris 7f32cca476 Merge branch 'master' into feature-40319/SWB_Software-und-Lizenzanforderung 2024-06-26 11:54:51 +02:00
Cris e8fe3c2eff Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-06-26 11:53:28 +02:00
cgfhtw 7cf89392a2 Prestudent History: aktiv & bold highlighting 2024-06-26 11:19:58 +02:00
cgfhtw c8f0bdd6d7 Prestudent History: add prestudent_id 2024-06-26 11:08:00 +02:00
cgfhtw c679e12d16 Tab Prestudent styling 2024-06-26 11:07:40 +02:00
cgfhtw 2144982829 Tabulator persistenceID 2024-06-26 11:07:04 +02:00
Cris 580f063efe Updated phrases: Added phrases for Softwareanforderung in category Softwarebereitstellung 2024-06-26 10:48:59 +02:00
Cris 3a16c4ebf3 Added method getAutocompleteSuggestions to Lehrveranstaltung_model.php
Get Lehrveranstaltungen by eventQuery string. Use with autocomplete event queries.
2024-06-26 10:45:56 +02:00
cgfhtw ac04629f86 Cleanup & Code Identation 2024-06-26 08:50:26 +02:00
SimonGschnell f546554f87 changes the layout of the news widget in the dashboard 2024-06-25 16:48:05 +02:00
SimonGschnell f4176ebcda adds the content of the news to the dashboard items and makes them scrollable through css classes 2024-06-25 14:18:11 +02:00
cgfhtw 10cd655b67 ZGV config default values 2024-06-25 10:37:32 +02:00
cgfhtw 77d7417132 UDF Component checkbox styles 2024-06-25 09:50:13 +02:00
Johann Hoffmann dd044b9146 entschuldigungen reload fix; student anw group header toggle fix; scan error msg fix; delete modal with kontrolle selection; scan code route renamed to profile/scan from student/scan; fixed sum formatting; 2024-06-24 16:35:48 +02:00
SimonGschnell 27287bd07a creating the api endpoint that fetches the content of the news instead of text metdata 2024-06-24 16:05:51 +02:00
SimonGschnell 7267d526bb rendering content pages 2024-06-24 14:23:34 +02:00
SimonGschnell f8c431e0bc updating comment of the content function 2024-06-24 14:23:34 +02:00
SimonGschnell 629ea3716e changes how the content and the news are displayed and also modifies the modals for the roominformation which now get their data from props instead of passing them directly via refs 2024-06-24 14:23:34 +02:00
SimonGschnell 6230aa47ae now also displays the room information inside a modal and does not redirect to the content site 2024-06-24 14:23:34 +02:00
SimonGschnell b3dfcdc295 the calendar modal is correctly opened when the correct event is called 2024-06-24 14:23:34 +02:00
SimonGschnell bb9d4bda04 adds a general modal for the lehrveranstaltungs Uebersicht with all the links connected to the lehrveranstaltung 2024-06-24 14:23:34 +02:00
SimonGschnell d92ad0a6c6 links the ort_kurzbz from the Stundenplan in the Dashboard to the Ort Information Content 2024-06-24 14:23:34 +02:00
SimonGschnell 63f089dc27 changes the layout of the Stundenplan Events 2024-06-24 13:50:13 +02:00
cgfhtw 6cca4d2daa StV: Students consolidation 2024-06-24 13:49:34 +02:00
SimonGschnell 77cd3bb02d removes the z-index from the calendar header so that it doesn't show over the menu when used in mobil view 2024-06-24 13:11:55 +02:00
SimonGschnell 008847e490 adds a sql query for the grouping algorithm 2024-06-24 13:08:44 +02:00
ma0068 f1605011dd update phrases 2024-06-24 12:04:30 +02:00
ma0068 cb617463ed Validation: Modal AskForAusbildungssemester 2024-06-24 12:03:02 +02:00
Johann Hoffmann 570798b5f7 landing page is now container for tabs or single component directly; WIP reworking lektor UI; 2024-06-24 10:51:23 +02:00
ma0068 e4abc745c8 Bugfix rt-stufe 2024-06-24 08:57:03 +02:00
Alexei Karpenko 155d2f9651 Merge remote-tracking branch 'origin/feature-30679/Plausichecks_Behebung_parameter_zur_Identifizierung_eines_Issues_einbeziehen' into feature-40728/Issues_logik_auslagern_in_eigene_library 2024-06-21 15:03:23 +02:00
Alexei Karpenko 453f93aba6 outsourcing Issue logic: removed var dumps 2024-06-21 14:58:26 +02:00
Alexei Karpenko d2611ac0a5 put issue logik in own library (so GUIs should not have to reimplement it) 2024-06-21 14:34:31 +02:00
ma0068 7bf109298b bugfix Anzeige Abbrecher, Absolvent 2024-06-21 13:26:55 +02:00
Andreas Österreicher b56e8c5f9f Im Abschlusspruefung Karteireiter wird in der Liste bei der Beurteilung jetzt die
Bezeichnung der Note angezeigt anstatt der Kurzbz
2024-06-21 13:02:55 +02:00
Alexei Karpenko e78598900a Studierendenverwaltung: added new prestudenstatus checks, created PrestudentstatusCheckLib 2024-06-19 20:42:14 +02:00
ma0068 823579dc59 refactor addNewStatus, cleanup Multi.js 2024-06-19 15:57:36 +02:00
ma0068 58005d1832 change getStudienplaene from prestudent_id to array prestudent_ids 2024-06-19 14:31:47 +02:00
cgfhtw 9c53a7a75b PDF Download Button während Einspruchsfrist verbergen 2024-06-19 14:02:20 +02:00
Harald Bamberger 1f36a08f05 Merge branch 'merge_37107_37133_39212' 2024-06-19 11:41:11 +02:00
cgfhtw 631a552708 Datum bei Abmeldung d Stud PDF 2024-06-19 10:55:48 +02:00
ma0068 d6be83b48c Refactor Tab Multistatus: Modal 2024-06-19 10:38:41 +02:00
Harald Bamberger ea9c35a64b Merge branch 'feature-37107/Fristenmanagement' into merge_37107_37133_39212 2024-06-19 10:28:39 +02:00
Harald Bamberger 04c006a733 do not create dummy manual events 2024-06-19 10:28:03 +02:00
Harald Bamberger aff1f9126f Merge branch 'master' into merge_37107_37133_39212 2024-06-19 09:45:05 +02:00
cgfhtw a8acf91980 Datum bei Abmeldung Fristablauf d WH PDF 2024-06-19 09:21:13 +02:00
Andreas Österreicher fb77ab67e7 Prüfungshonorare im Notenkarteireiter zeigen nur aktive Mitarbeiter an 2024-06-19 09:05:08 +02:00
Harald Bamberger d3a277f9fb Merge branch 'feature-39212/PV21-Grund_beim_Beenden_eines_DV' into merge_37107_37133_39212 2024-06-19 08:52:03 +02:00
Harald Bamberger 0aa53f64ff db Aenderungen Gegenpruefung hinzugefuegt 2024-06-19 08:51:34 +02:00
ma0068 29a920b1ce Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-06-18 16:25:04 +02:00
ma0068 0729f2ed1a refactor actions prestudentLib 2024-06-18 16:24:57 +02:00
Johann Hoffmann b4b44d9a89 added entschuldigung & anw_user notizen; entschukldigung notizen working; WIP anw notizen; api fixes entschuldigung; LE for LVA fetch now disregarding stundenplan; Paths renamed to new controller names; 2024-06-18 14:15:35 +02:00
cgfhtw 3e0c15e18f Datum bei Abmeldung d StgL PDF 2024-06-18 11:12:12 +02:00
cgfhtw f276435750 Student list code rearrangement 2024-06-18 08:36:02 +02:00
ma0068 d600a6d2c3 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-06-18 07:58:51 +02:00
ma0068 b5dbb8a16a Refactor Functions in Prestudent Lib, Unterbrecher as single Action 2024-06-17 18:38:04 +02:00
Johann Hoffmann 473815639b added entschuldigung max reach constant; rewrote SQL queries from string insert to param escaping; removed Stundenplan Lookup from LE for LVA fetch; load LE Stundenplan termine and serve as option when starting new kontrolle. 2024-06-17 17:39:56 +02:00
Cris 538c2e09ce Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-06-17 14:20:43 +02:00
cgfhtw 752632456c Bug: Prestudent semester 2024-06-17 12:06:19 +02:00
cgfhtw 9220e1f85f Cleanup Verband & list 2024-06-17 11:07:55 +02:00
ma0068 1036c97be7 Tab Status: change statusgrund_kurzbz to bezeichnung_mehrsprachig 2024-06-14 15:58:11 +02:00
SimonGschnell a0472c6573 little changes 2024-06-14 14:44:29 +02:00
ma0068 521423a343 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-06-14 14:34:34 +02:00
ma0068 04c5ccc891 use setAbbrecher, set UnterbrecherFas 2024-06-14 14:34:15 +02:00
Harald Bamberger e05fa0f4d8 Merge branch 'master' into merge_37107_37133_39212 2024-06-14 11:50:32 +02:00
Harald Bamberger c3278ad30f add app softwarebereitstellung to prevent checksystem errors when adding phrases for softwarebereitstellung while not having installed the extension 2024-06-14 11:49:43 +02:00
SimonGschnell f83cd3b87a checks whether the user wants to fetch content or the news 2024-06-14 11:18:29 +02:00
Harald Bamberger e4326e00e4 Merge branch 'feature-39212/PV21-Grund_beim_Beenden_eines_DV' into merge_37107_37133_39212 2024-06-14 11:02:25 +02:00
Harald Bamberger 93d0f88b0d function getDVByPersonUID: add dvendegrund_kurzbz and dvendegrund_anmerkung to select 2024-06-14 10:48:43 +02:00
Harald Bamberger 1c385d22cd Merge branch 'feature-37133/Gehaltsbaender' into merge_37107_37133_39212 2024-06-14 10:41:48 +02:00
Harald Bamberger 24786c6ae6 Merge branch 'feature-37107/Fristenmanagement' into merge_37107_37133_39212 2024-06-13 13:30:38 +02:00
Harald Bamberger 0e5d4b30ed Merge branch 'master' into feature-37133/Gehaltsbaender 2024-06-13 13:26:48 +02:00
Harald Bamberger 4e233f760d Merge branch 'master' into feature-37107/Fristenmanagement 2024-06-13 13:26:02 +02:00
SimonGschnell dd7c8480f3 removes unwanted methods and properties from CalendarModal 2024-06-13 12:29:36 +02:00
SimonGschnell de4accab83 cleans up the Stundenplan grouping algorithm 2024-06-13 12:27:09 +02:00
Harald Bamberger fd2474cc38 Merge branch 'master' into feature-39212/PV21-Grund_beim_Beenden_eines_DV 2024-06-13 11:51:10 +02:00
Andreas Österreicher 20eee62c19 Merge branch 'sonstiges-40279/SWB-Lizenzserverport' 2024-06-13 11:13:30 +02:00
cgfhtw 182e370086 Bugfix: Integer cast 2024-06-12 15:58:34 +02:00
cgfhtw ee2c937cbf Highlight selected Verband 2024-06-12 15:36:03 +02:00
cgfhtw 2f65e6a801 Bugfixes 2024-06-12 15:35:42 +02:00
cgfhtw ad440e12b5 remove console.log 2024-06-12 15:22:39 +02:00
cgfhtw f469f7aea9 Students Endpoint => fhcApi 2024-06-12 15:06:43 +02:00
Werner Masik eb327c3adc update Handyverwaltung filter 2024-06-12 14:52:22 +02:00
SimonGschnell d1afd9f09d groups the uids of the reservierungen in the raum uebersicht and renders different template if the calender entry is a reservierung or a stundenplan event 2024-06-12 14:42:30 +02:00
Harald Bamberger 1e56707e5a Merge branch 'feature-40415/Studstatus-UID_in_Sancho_Message_Abmeldung_StG_Ablauf_Einspruchsfrist' 2024-06-12 08:13:11 +02:00
Harald Bamberger 6816a300f6 Beschriftung korrigiert 2024-06-11 16:39:20 +02:00
Harald Bamberger 0b8191a435 Beschriftung zu IDs in Sancho Message hinzugefuegt 2024-06-11 16:26:52 +02:00
SimonGschnell 9c51f25c9e modifies how the slot template from the Calendar Page is passed to the CalendarApp and prints the reservierungen differently (but the reservierungen are not grouped yet) 2024-06-11 15:03:09 +02:00
Harald Bamberger f8d8a44a3c student_uid zu sancho message Abmeldung StG Ablauf Einspruchsfrist 2024-06-11 14:47:54 +02:00
Cris cd0eacf947 Updated phrases: Added phrases 'lizenzserverPort' and 'raumSwZuordnung' 2024-06-11 13:52:03 +02:00
Cris dd47cd2a7c Updated filter: Added lizenzserver_kurzbz and lizenzserver_port to SoftwareManagement filter 2024-06-11 13:51:03 +02:00
ma0068 d8460923ca Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-06-11 12:16:48 +02:00
ma0068 2e06633972 bugfix Validierung Email required 2024-06-11 12:16:35 +02:00
Cris a4b77fc43f Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-06-11 11:32:47 +02:00
cgfhtw 5b193e89c0 Cleanup 2024-06-11 10:23:09 +02:00
cgfhtw b7dff7d2c3 Permission-Filter Verband 2024-06-11 10:22:52 +02:00
ma0068 bef53dadb1 refactor Tab Contact 2024-06-11 09:27:40 +02:00
Johann Hoffmann e7e5d76531 fhcapi use factory merge 2024-06-10 17:23:37 +02:00
Johann Hoffmann 52a55a018c merge fix 2024-06-10 15:13:30 +02:00
Andreas Österreicher f943ae7566 Merge branch 'feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software' 2024-06-10 14:05:49 +02:00
Cris f1547b069d Merge branch 'feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software' of https://github.com/FH-Complete/FHC-Core into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2024-06-10 13:37:46 +02:00
Cris ac7dc1599c Corrected path to init.js.php 2024-06-10 13:37:14 +02:00
Johann Hoffmann aa1d70f8f0 fix 2024-06-10 13:35:06 +02:00
Johann Hoffmann 9350e9230f API refactor 2024-06-10 13:30:44 +02:00
SimonGschnell 022ad26dd2 reservierungen query also joins the studiengangs and mitarbeiter information 2024-06-10 13:01:55 +02:00
SimonGschnell 392d8f38d2 adding the reservierungen to the room plannung 2024-06-10 11:39:16 +02:00
SimonGschnell 8442690bc7 splits the multiple stg into different rows if there are more than one stg in one lv 2024-06-10 10:56:12 +02:00
SimonGschnell 70b0b3fae7 MVP algorithm for stundenplan gruppierung (testing) 2024-06-07 15:06:28 +02:00
Andreas Österreicher 46b7dc1ce7 Dauer für die Anzeige von abgelaufenen Projekten in der Zeitaufzeichnung
auf 2 Monate verlängert
2024-06-07 10:19:12 +02:00
ma0068 0b24e1098a Betriebsmittel Adaptierung Layout Form 2024-06-06 11:20:57 +02:00
Johann Hoffmann 068aa03b4f Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-06-06 11:02:56 +02:00
ma0068 fe69c0a578 Betriebsmittel: Form as Modal 2024-06-06 10:44:37 +02:00
SimonGschnell 25d284389a gruppieren algorithm erweitern 2024-06-06 09:25:46 +02:00
ma0068 accb8f7f82 delete old endpoint betriebsmittel 2024-06-06 08:10:25 +02:00
ma0068 2d61dea287 refactor resources: endpoint betriebsmittel 2024-06-05 16:53:54 +02:00
Werner Masik cd8fffd2f7 added filter update for Handyverwaltung 2024-06-04 16:20:43 +02:00
Cris 125a2da9b3 Merge branch 'feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software' of https://github.com/FH-Complete/FHC-Core into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2024-06-04 16:16:49 +02:00
Cris 884d930e71 Merge branch 'master' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2024-06-04 16:05:33 +02:00
Cris 49045c06af Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-06-04 16:04:19 +02:00
SimonGschnell 1a5d270936 calendarDate preparation 2024-06-04 15:00:41 +02:00
ma0068 48d36cc859 include Phrases wawi 2024-06-04 11:41:05 +02:00
ma0068 8c4d00b8ef encode/decode Inventarnummer 2024-06-04 11:31:18 +02:00
SimonGschnell 3df1aaf371 uses the new fhcApi factory to make the roomInformation get request from the frontent/v1/stundenplan api and uses the CalendarDate class to get the first day of the week and the last day of the week to make the request for the room information over the whole week 2024-06-04 08:24:58 +02:00
Harald Bamberger 7b148b1a39 Merge branch 'master' into feature-39212/PV21-Grund_beim_Beenden_eines_DV 2024-06-03 17:21:50 +02:00
Harald Bamberger 0cbb8997e2 migratecontract config und config check auch in MigrateHourlyRate verwenden 2024-06-03 17:14:55 +02:00
cgfhtw 3b3191c407 Kontakt Validation 2024-06-03 16:59:59 +02:00
Cris 512002c0e8 Created init.js file and changed link url in stpl_week to open Software-Raumsuche by OrtKurzbz 2024-06-03 16:40:35 +02:00
Cris 9652f48044 Added phrases 'zugeklappt', 'softwareliste', 'raumverfuegbarkeit' 2024-06-03 16:27:31 +02:00
Harald Bamberger 7491b9c1b0 try to fix mobile dashboard view 2024-06-03 11:35:11 +02:00
Harald Bamberger 204de30459 make news modal more responsive 2024-06-03 10:46:26 +02:00
cgfhtw 9a3a72deb0 Permissions Bankverbindungen 2024-06-03 10:33:11 +02:00
Harald Bamberger 92319b9b29 quick fix for overlapping dashboard elements on mobile phones 2024-06-03 10:27:03 +02:00
cgfhtw b477d814c6 Bugfix: missing end-tag 2024-06-03 09:21:45 +02:00
SimonGschnell 39321dcde3 adds the roomInformation Calendar to the menu and uses different template for the calendar page slot 2024-05-31 12:28:06 +02:00
SimonGschnell b9bd8e1d4d Merge branch 'feature-25999/C4' into feature-39912/Room_planning_calendar 2024-05-31 08:53:40 +02:00
ma0068 0c44a497a5 adapt modal add/update status 2024-05-29 16:06:09 +02:00
Harald Bamberger 9454bde14a backport Betriebsmittel Component from feature-30660/FHC4_StudierendenGUI_Prototyp Branch 2024-05-29 15:19:23 +02:00
ma0068 5d8df75e86 refactor Tab Contact: backend 2024-05-29 12:34:20 +02:00
Harald Bamberger a924c9d2bb backport Betriebsmittel Component from feature-30660/FHC4_StudierendenGUI_Prototyp Branch 2024-05-29 11:49:11 +02:00
ma0068 0c8d4d830f Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-05-28 16:34:47 +02:00
ma0068 0a4d89543a refactor tab contact: form component, dropwdowns plz, ort, gemeinde 2024-05-28 16:34:34 +02:00
cgfhtw f218174ad3 Comments 2024-05-28 14:39:41 +02:00
cgfhtw dccf845e3b Notiz Anhang Preview & CodeQuality 2024-05-28 14:38:37 +02:00
cgfhtw fb4997b1ac DmsUpload Preview 2024-05-28 14:37:54 +02:00
Andreas Österreicher 5453579c7b Merge branch 'feature-36963/BIS_check_duales_Studium' 2024-05-28 09:29:44 +02:00
KarpAlex d8ba92e343 Merge branch 'master' into feature-36963/BIS_check_duales_Studium 2024-05-27 19:42:48 +02:00
ma0068 dd138380c9 Adaptierungen Tab Adresse: show Zustelladresse, Heimatadresse Validierung backend, Layout: Ticks, required 2024-05-27 17:07:09 +02:00
ma0068 d020537679 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-05-27 14:57:31 +02:00
ma0068 259a3c218a Funktionalitaet feature-39602 2024-05-27 14:57:18 +02:00
cgfhtw d5e8227918 Bugfix: api/frontend/fas controller do not inherit from FHCAPI_Controller 2024-05-27 12:45:10 +02:00
SimonGschnell 5021c47c9f calendar style changes 2024-05-27 12:20:58 +02:00
cgfhtw 69abf1e9e2 Comment 2024-05-27 11:50:17 +02:00
SimonGschnell 87681351b9 Merge branch 'feature-25999/C4' into feature-39912/Room_planning_calendar 2024-05-27 10:55:44 +02:00
ma0068 21fb679c08 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-05-27 08:53:54 +02:00
cgfhtw 3d1f81a721 address: code quality 2024-05-27 08:53:18 +02:00
SimonGschnell 16f90604b6 stundenplan modal for LVs and making calendar header sticky 2024-05-24 11:17:06 +02:00
SimonGschnell 234ec03db9 adds the phrase noGrade 2024-05-24 09:37:07 +02:00
Johann Hoffmann 0536ff0044 load person_id & uid for students to navigate them with admin view; WIP studentDropdown selection; WIP changing studentComponent to work with different permissions; 2024-05-23 16:49:53 +02:00
SimonGschnell 729509a45d WIP 2024-05-23 15:40:23 +02:00
SimonGschnell 12b2f3ab07 adding more information to the cis40 stundenplan 2024-05-23 15:39:31 +02:00
Alexei Karpenko 854d836e30 Abschlussprüfungsprotokolle: added link in FAS to read-only form 2024-05-23 13:56:18 +02:00
SimonGschnell 25deb0a440 takes the value of the node not just the node 2024-05-23 13:01:18 +02:00
SimonGschnell cef41f3710 fixes html, one closing div to much 2024-05-23 12:44:12 +02:00
ma0068 471e2e7b86 temp 2024-05-23 09:52:25 +02:00
Johann Hoffmann 59a1e84fb2 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp
# Conflicts:
#	public/js/components/filter/Filter.js
#	public/js/plugin/FhcApi.js
#	system/dbupdate_3.4.php
2024-05-22 15:42:19 +02:00
Harald Bamberger 8cba0aec5a vertragsarten dvbund, dvanderegk und dvanderebet hinzugefuegt, MigrateContract default oe und ba1code mapping in config verschoben und config check implementiert 2024-05-22 15:32:28 +02:00
cgfhtw 7541770fbb Code Quality & Comments 2024-05-22 13:42:39 +02:00
cgfhtw ae4c06f481 Bugfix: Typo validations 2024-05-22 13:09:18 +02:00
cgfhtw 84013e42e7 Bugfixes: correct validation function, cast stg_kz to int, query order 2024-05-22 12:46:05 +02:00
Cris aab198e355 Merge branch 'master' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2024-05-22 11:03:34 +02:00
cgfhtw 5eafa6b5f4 Bugfix: filter not null 2024-05-22 08:54:23 +02:00
cgfhtw b52ea08013 Correct Casting for stg_kz 2024-05-22 08:54:00 +02:00
cgfhtw e20bebad87 Bugfixes: Typos 2024-05-21 16:09:21 +02:00
SimonGschnell 186e9e6f08 WIP room planning in calendar 2024-05-21 15:56:18 +02:00
ma0068 1993e20ffc Notiz component: new layout popupModal 2024-05-21 15:35:57 +02:00
Cris 559a6b317d Fixed multiple display of child software 2024-05-21 14:44:41 +02:00
Cris 66a80697c2 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-05-21 14:21:34 +02:00
SimonGschnell c566d07847 fixes little xml layout issue 2024-05-21 13:34:58 +02:00
ma0068 6d97a9e9aa Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-05-21 11:47:36 +02:00
ma0068 9cade51ff4 Dropdown Status Aendern, Phrases 2024-05-21 11:47:24 +02:00
SimonGschnell 48bb2ef7e1 adds the insert query for the new raum template and the update statement to update the template for every room content 2024-05-21 11:05:22 +02:00
cgfhtw 17512e60b2 Favorites => fhcApi 2024-05-21 10:53:23 +02:00
SimonGschnell 393475e62c adds the content update script for the room content to the checksystem 2024-05-21 10:49:27 +02:00
SimonGschnell d07c568d5e adds dbupdate queryies for the new raum template 2024-05-21 10:37:53 +02:00
Werner Masik 706dad6df6 added DV Ende 2024-05-16 21:58:34 +02:00
cgfhtw 1f45ddc17d minor improvements 2024-05-16 16:40:08 +02:00
Johann Hoffmann 7530a74ff3 demo stand gf; 2024-05-16 16:39:54 +02:00
cgfhtw 3ef5528196 Vue.js Warnings 2024-05-16 16:32:59 +02:00
ma0068 e915671a02 Adaptions for Apacheconfirmity 2024-05-16 13:17:28 +02:00
Harald Bamberger f2a2469e6e MigrateContract: keine ZeitaufzeichnungsVbs erstellen wenn za oder azg flag null ist. MigrateHourlyRate: kalkulatorische Stundensaetze nur migrieren wenn SAP Sync Tabelle existiert. 2024-05-15 17:25:26 +02:00
SimonGschnell c7e01bd3f2 creates the sql query with the needed room information to be displayed in the search 2024-05-15 14:37:18 +02:00
SimonGschnell 56e6efe416 WIP sql query for the raum search 2024-05-14 15:57:48 +02:00
SimonGschnell 841e3b0390 raum query 2024-05-14 14:21:52 +02:00
ma0068 4c671c2ee9 Phrases Validierungen 2024-05-14 14:13:38 +02:00
Harald Bamberger b3c6127cfe Merge branch 'feature-25999/C4_TEST' into feature-25999/C4 2024-05-14 14:01:24 +02:00
Cris c4c17f69c7 Added phrase softwaretypKurzbz 2024-05-14 13:41:33 +02:00
ma0068 1f4b029973 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-05-14 09:25:40 +02:00
ma0068 33267de4be Refactor Status, Adaptions Prestudent 2024-05-14 09:25:21 +02:00
Harald Bamberger 141b1523e1 Merge branch 'master' into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-05-13 16:44:15 +02:00
Johann Hoffmann 3b762c8065 getStudentsForLvaInSemester data query; getLektorIsTeachingLE veryfication query; getLektorenForLvaInSemester selection query; moved setup from app to landing page, landing page thus unskippable; now checking qr code age in check in; charts smaller size now; more phrasen; lektor tabulator height fix; ma uid selection of lektors for admin and assistenz; tested and implemented QRDelete Cronjob; 2024-05-13 16:01:26 +02:00
Cris 8a0d2a2f10 Refactored Tabs title assignment to utilize computed property
This is necessary to render language phrases correctly
2024-05-13 14:02:05 +02:00
Cris 6d728ae0e7 Merge branch 'master' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software
# Conflicts:
#	public/js/components/Tabs.js
#	public/js/components/filter/Filter.js
2024-05-13 12:07:37 +02:00
Cris 58f52dfaae Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-05-13 11:07:16 +02:00
Cris 5643607845 Added phrases 'statusErfolgreichUebertragen' and 'statusUebertragenMsg' to Softwarebereitstellung app 2024-05-13 11:06:32 +02:00
ma0048 a0284c313a - funktion fuer das alle markierten akzeptieren getrennt
- fehlende phrasen hinzugefuegt
2024-05-13 09:16:29 +02:00
SimonGschnell fd8e49c11f hotfix in Modal.js 2024-05-08 14:35:41 +02:00
SimonGschnell 6fa5ff81d6 Merge branch 'feature-25999/task-39464' into feature-25999/C4_TEST 2024-05-08 12:01:53 +02:00
SimonGschnell 0942480428 adds the missing model for the function 2024-05-08 11:58:35 +02:00
SimonGschnell 2fd2746a74 Merge branch 'feature-25999/task-39464' of github.com:FH-Complete/FHC-Core into feature-25999/task-39464 2024-05-08 11:56:50 +02:00
SimonGschnell 8e2129902c Merge branch 'feature-25999/task-39464' into feature-25999/C4_TEST 2024-05-08 11:29:39 +02:00
SimonGschnell d0509abb8b also adds the new controller functions to the CisVue/Cms and CisHmvc/Cms 2024-05-08 11:28:16 +02:00
SimonGschnell c2a782e164 updates news fetching and DB_Model pagination methods 2024-05-08 11:28:16 +02:00
SimonGschnell 5ac0b249ec makes component Pagination page_size prop a required prop 2024-05-08 11:28:16 +02:00
SimonGschnell 5142f5656b passes the page_size down from the parent component to the child component 2024-05-08 11:28:16 +02:00
SimonGschnell 7bd70a6436 makes it possible to send the page_size from the frontend to the backend to adopt how many rows to query 2024-05-08 11:28:16 +02:00
SimonGschnell c017014171 changes how the pagination is done in the DB_Model 2024-05-08 11:28:16 +02:00
SimonGschnell 36c8862b99 implementing frontend pagination for components 2024-05-08 11:28:16 +02:00
SimonGschnell 29f7e34e10 adds pagination logic to C4 news 2024-05-08 11:28:16 +02:00
SimonGschnell 730db74743 Merge branch 'feature-25999/C4_ma0594_profilePage' into feature-25999/C4_TEST 2024-05-08 11:14:41 +02:00
SimonGschnell d1207ced02 Merge branch 'master' into feature-25999/C4_TEST 2024-05-08 11:06:34 +02:00
SimonGschnell fb6bb96fbd making Filter-core-cmp emit the tableBuilt event 2024-05-08 10:58:38 +02:00
SimonGschnell 9db09a040a Merge branch 'master' into feature-25999/C4_ma0594_profilePage 2024-05-08 09:58:18 +02:00
Harald Bamberger 93b111af93 fix handleSystemError is not a function 2024-05-06 16:48:38 +02:00
Harald Bamberger 6a8a96b748 fix long lasting request getPrestudents to block browser when timedout once 2024-05-06 16:04:45 +02:00
SimonGschnell a563f053ef adds the width and the height properties to the dashboard item, they were missing and caused a bug where the news widget was not displaying correctly 2024-05-06 14:19:04 +02:00
Johann Hoffmann 3846f38a6f added PK to tbl_anwesenheit_check; chenged anwesenheiten sum function to account for timespans of the checks; added extension/anwesenheit_admin berechtigung; fotos are now being sent as links to bild.php; studentByLva table now with von & bis times of the check; now updating attendance check times when starting further checks on the same date; checking if time the code is being sent is in the timespan of the kontrolle; added method to delete QR codes older than certain ms to be called from QRDelete Cronjob; 2024-05-06 11:21:01 +02:00
ma0068 d1b813b1cc update editStatus: getHistory, setAbbrecher, dropdown newStatus, validations 2024-05-03 16:53:31 +02:00
Harald Bamberger 69b0b3601d Merge branch 'master' into feature-39212/PV21-Grund_beim_Beenden_eines_DV 2024-05-03 13:08:12 +02:00
ma0068 8663d86f7a adaption NotizComponent 2024-05-03 10:59:41 +02:00
SimonGschnell efcebb567f responsive adjustments 2024-05-03 10:46:20 +02:00
SimonGschnell e6ad3b3168 adjust responsiveness of createAnrechnung.php 2024-05-03 10:35:46 +02:00
SimonGschnell f9058b954e adjusting the responsive layout for approveAnrechnungDetail view 2024-05-03 10:31:53 +02:00
SimonGschnell 4aa8807830 adds responsiveness for the view approveAnrechnungUebersicht 2024-05-03 09:48:18 +02:00
Andreas Österreicher 40c0393bc0 Voller Name der Kritikalität des Services wird angezeigt im
Servicekatalog
2024-05-02 16:31:34 +02:00
Andreas Österreicher c6193530db Merge branch 'feature-39288/Servicekatalog_Kritikalitaet' 2024-05-02 16:27:09 +02:00
SimonGschnell 9975f767b8 adds responsiveness to reviewAnrechnungDetail.php 2024-05-02 12:15:57 +02:00
SimonGschnell 0b58d4fd6f also adds the programmatically unselectable logic to the reject button 2024-05-02 11:43:19 +02:00
ma0068 ce72294273 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-05-02 11:32:30 +02:00
SimonGschnell bcafb6cea6 removes unnecessary function call from reviewAnrechnungUebersicht.js 2024-05-02 11:30:38 +02:00
SimonGschnell 6ea802717b adds pointer-events none to all rows with the class .tabulator-unselectable except for the links inside those rows, because it was not possible to programmatically retrigger the selectableCheck 2024-05-02 11:14:12 +02:00
ma0068 12e06776be Notizcomponent: using factories as endpoint 2024-05-02 11:13:45 +02:00
Johann Hoffmann 2c08a482e3 finished phrasen in backend; setup component is no a modal in landing page and only for lektors with multiple LE assigned in an lva; assistenz skips landing page; tabulator formatting fixes; getAllAnwesenheitenByLektor now fetches students and their anwesenheiten entries seperately which is significantly faster; 2024-05-02 09:29:50 +02:00
Harald Bamberger 3a3d28e9e6 Merge branch 'feature-37246/APIs_Konsolidierung' 2024-04-30 21:45:48 +02:00
Harald Bamberger 3b8776f947 Merge branch 'master' into feature-37246/APIs_Konsolidierung 2024-04-30 16:26:15 +02:00
Andreas Österreicher 23255ed84f Merge branch 'feature-17727/FasDefaultStundensatzProjektbetreuungAnzeigen' 2024-04-30 16:17:00 +02:00
Andreas Österreicher a3b5996c50 Stundensatz wird abhängig vom Studiensemester der Projektarbeit /
Lehreinheit ermittelt
2024-04-30 16:16:03 +02:00
SimonGschnell 10bfb6c9e8 also fixes the isSelectable bug when rejecting a anrechnung in the approveAnrechnungenUebersicht view 2024-04-30 15:03:30 +02:00
SimonGschnell 86d3042cc6 makes the rows that were recently selected unselectable and adds the correct styling in the approveAnrechnungUebersicht view 2024-04-30 14:18:22 +02:00
cgfhtw 9d0e63e695 API Konsolidierung Verband 2024-04-30 13:22:08 +02:00
Andreas Österreicher a606add6eb Merge branch 'master' into feature-17727/FasDefaultStundensatzProjektbetreuungAnzeigen 2024-04-30 10:55:58 +02:00
SimonGschnell ac0103751d adds a border to the tableWidget and also adds a function that finds the tableunqiueid using the tableInstance 2024-04-30 09:48:08 +02:00
cgfhtw fe06b2360e API Konsolodierung: stv address 2024-04-30 08:48:15 +02:00
cgfhtw c8009a8a6c API Konsolodierung: stv lists 2024-04-30 08:33:39 +02:00
SimonGschnell 20a2e369c5 adds new button to show all new and changed lehrauftraege in the orderLehrauftrag view, so that the user can set the initial filter himself 2024-04-29 15:53:56 +02:00
cgfhtw c2ffd02907 Consolidate FHCApi childs 2024-04-29 15:00:38 +02:00
cgfhtw 0536deda1a StV: static primevue 2024-04-29 14:47:44 +02:00
KarpAlex 18dabf26e4 service uebersicht in cis: loading only one moodle config instead of all addon configs to avoid php notices 2024-04-29 14:00:30 +02:00
SimonGschnell 555db0d5af fixes the selection of the tableUniqueID 2024-04-29 11:45:08 +02:00
cgfhtw 7bb98479dd API konsolidierung StV Config 2024-04-29 11:40:46 +02:00
SimonGschnell b0d31361c1 updates fontawesome version 2024-04-29 11:38:03 +02:00
SimonGschnell 8cf63f3b76 replaces the icons images with actual icons from the fontawesome6 library 2024-04-29 11:34:18 +02:00
cgfhtw b5c830ed35 FHCAPI stabilize addError function 2024-04-29 11:19:10 +02:00
cgfhtw 8e56b404b9 Merge branch 'feature-37246/APIs_Konsolidierung' into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-04-29 11:17:12 +02:00
ma0068 e4ee83c590 Multistatus Adaptions Design 2024-04-29 10:51:02 +02:00
Harald Bamberger ef5040557d Merge branch 'master' into feature-37246/APIs_Konsolidierung 2024-04-29 09:37:06 +02:00
SimonGschnell ffe4fcb0b3 removes the cis styles from the admin views 2024-04-26 14:43:56 +02:00
ma0068 bc7fa71894 Multiactions Status Change 2024-04-26 14:16:36 +02:00
SimonGschnell dec6b160a6 fixes the acceptLehrauftrag view with bootstrap5 and tabulator5 2024-04-26 14:07:24 +02:00
Andreas Österreicher 8999b59f4e Renamed Field 2024-04-26 13:41:33 +02:00
cgfhtw 81612da80c collapse-auto-close: better event handling 2024-04-26 13:18:06 +02:00
cgfhtw 47130b48ec Auto close filter 2024-04-26 13:06:24 +02:00
cgfhtw 1b35b95173 Comment 2024-04-25 15:54:27 +02:00
SimonGschnell e4f1da751d migrating the acceptLehrauftrags view to bootstrap 5 2024-04-25 15:19:24 +02:00
Harald Bamberger 2ea3597a10 Merge branch 'master' into feature-39212/PV21-Grund_beim_Beenden_eines_DV 2024-04-25 15:11:41 +02:00
Harald Bamberger 08dd6a7783 add dvendegrund_kurzbz and dvendegrund_anmerkung when reading dvs from db 2024-04-25 15:11:16 +02:00
SimonGschnell 88fd26d192 Merge branch 'master' into feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5 2024-04-25 14:35:50 +02:00
SimonGschnell 580b6239c2 remove the body tag from all views that use the FHC-Header view 2024-04-25 14:35:06 +02:00
Andreas Österreicher d55cb56a1a Merge branch 'bug-39609/automatischer_abgewiesener_status_setzen' 2024-04-25 14:24:43 +02:00
ma0048 8bac75ae52 - bug behoben, damit keine leeren "Status Abgewiesen gesetzt" Mails verschickt werden 2024-04-25 14:20:18 +02:00
cgfhtw 7944ce091e Konto: save filter settings 2024-04-25 14:17:08 +02:00
SimonGschnell b7ffe00c69 sets the height of the adminZeitverfuegbarkeit to 50% of the screen ehight 2024-04-25 14:16:28 +02:00
SimonGschnell d01b05fd73 edit anrechnungszeitfenster does actually edit and not insert a new anrechnungszeitfenster 2024-04-25 13:30:32 +02:00
SimonGschnell deb0197452 fixes the adminAnrechnungen page 2024-04-25 13:13:24 +02:00
cgfhtw 4f4df8a8b7 Konto: more phrases 2024-04-25 13:09:10 +02:00
cgfhtw 912b018e32 Config typo 2024-04-25 11:59:12 +02:00
cgfhtw ab8b46203e fhcapifactory add stv 2024-04-25 11:57:54 +02:00
cgfhtw 1a6c107f0b Bugfix: phrasesupdate missing insertvon 2024-04-25 11:55:50 +02:00
cgfhtw e3ff62001b StV Phrasen 2024-04-25 11:47:53 +02:00
cgfhtw f47f8d5da4 Konto: Phrases 2024-04-25 11:36:37 +02:00
SimonGschnell fed30daad0 bug fix, only appending the event to the accept and deny action button if they were actually created 2024-04-25 09:41:32 +02:00
SimonGschnell a2e943ac40 adjusts the actions of the ProfilUpdateView table with accept and deny buttons 2024-04-25 09:29:47 +02:00
Johann Hoffmann f5d534a409 added require branch update file in dbupdate_3.4.php; added phrasen everywhere in frontend, WIP translating backend messages; 2024-04-24 15:52:53 +02:00
Werner Masik 3b06519f2f updated phrases for salary range 2024-04-24 15:25:42 +02:00
SimonGschnell cea06994de fixes the bug with the columnDefault tooltips that was inside the TableWidget.js file 2024-04-24 14:59:46 +02:00
Werner Masik c15a350392 moved dbUpdate for gehaltsband to extension 2024-04-24 14:55:22 +02:00
ma0048 b1e85fe92b - international skills auf vuejs
- note uebernehmen hinzugefuegt
2024-04-24 14:18:55 +02:00
cgfhtw 1b19a0821f Konto filters for Student list 2024-04-24 14:02:58 +02:00
SimonGschnell 5a62dbc740 refactors the adminAnrechnung page because it is used in an bootstrap3 environment 2024-04-24 11:35:02 +02:00
SimonGschnell 7dfe2f1932 tabulator5 function changes 2024-04-24 10:00:12 +02:00
Harald Bamberger c33a11e952 Merge branch 'master' into feature-37246/APIs_Konsolidierung 2024-04-24 08:30:25 +02:00
Harald Bamberger 844c07be9c Merge branch 'feature-39174/Studstatus_AbmeldungStglFuerUnterbrecher' 2024-04-24 08:25:51 +02:00
Johann Hoffmann 633b9eeafe loading STG permissions for assistenz into frontend and only fetching entschuldigungsdata for those; new data fetch api methods for lektor to visualize graphs: getAllByLva & getAllByStudiengang. old one renamed to getAllByLvaAssigned; automatic email to responsible adress on entschuldigung upload of a student; focused on pie charts for reusable landing page design; fixed entschuldigungen date filter validation; WIP extension specific phrases; 2024-04-23 17:00:32 +02:00
Harald Bamberger 5175dcdbe4 Merge branch 'master' into feature-37246/APIs_Konsolidierung 2024-04-23 15:57:50 +02:00
SimonGschnell 96b79c8740 corrects reviewAnrechnungDetail style typo, and adds the height function to the adminAnrechnung table again 2024-04-23 13:43:00 +02:00
SimonGschnell bebec98285 adds a little space with a br between the tablewidget header and the table itself 2024-04-23 13:16:04 +02:00
SimonGschnell 8d68faf922 replaces the pull-right class with a conditional if bootstrapVersion was set to 5 2024-04-23 13:06:02 +02:00
SimonGschnell 9ae36b54e1 remove the 50% height from the table and add fitColumns to the table so that the columns take the whole available space 2024-04-23 12:55:44 +02:00
SimonGschnell 11c9622186 replaces the anrechnungen.css with styles in the zeitverfuegbarkeit view 2024-04-23 12:50:29 +02:00
SimonGschnell 3a1ac15740 adds the button width and margin classes from the Tabulator.css (used in Tabulator4) to the anrechnungen.css file 2024-04-23 12:47:17 +02:00
SimonGschnell 51ee16926c adds a tabulator redraw when adding the details column to the tableWidget 2024-04-23 09:49:41 +02:00
ma0068 5e3a7d4307 bugfix tooltip 2024-04-23 08:12:57 +02:00
SimonGschnell e1fac8e871 adds the bootstrapVersion flag to all the TableWidgetData files 2024-04-22 17:11:02 +02:00
ma0068 ab978592a0 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-04-22 16:22:07 +02:00
ma0068 fd0fb7c9b4 Refactor Notizcomponent: add Endpoint and core NotizController 2024-04-22 16:21:54 +02:00
SimonGschnell 977c2d4432 Merge branch 'master' into feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5 2024-04-22 15:18:19 +02:00
SimonGschnell 258c5f7777 Merge branch 'master' into feature-36185/requestAnrechnung_bootstrap3_zu_bootstrap5 2024-04-22 14:56:07 +02:00
SimonGschnell e2e7966f83 adds accept and deny actions in the actions column of the ProfilUpdateView component 2024-04-22 14:55:37 +02:00
SimonGschnell 349865b8fb fixes the phrasen for the column titles of the ProfilUpdateView 2024-04-22 13:52:38 +02:00
SimonGschnell 27428b15bb changes the escaping string for the xslt_xhtml_c4 2024-04-22 11:49:19 +02:00
Harald Bamberger 93ae5577f8 try with here documents 2024-04-22 11:25:24 +02:00
cgfhtw 28ab904144 Download PDF & Bugfix New 2024-04-19 14:52:50 +02:00
SimonGschnell 1447a930d3 adds more phrasen to the profil and the profilUpdate views, headers of tables phrasen 2024-04-19 14:24:32 +02:00
Andreas Österreicher 0655118f2b Merge branch 'feature-39349/tdb_phrasen' 2024-04-19 10:38:39 +02:00
ma0068 8d61025afa Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-04-19 07:08:01 +02:00
ma0068 a65336993c Bugfix Notiztab 2024-04-19 07:07:44 +02:00
Alexei Karpenko 412bb10a06 Servicekatalog: renamed Kategorie column to Kritikalität in vilesci, added column Kritikalitaet in cis overview 2024-04-18 15:38:22 +02:00
cgfhtw 6025660e23 Konto counter & Zahlungsreferenz 2024-04-18 15:14:41 +02:00
cgfhtw ed59de7e80 Merge remote-tracking branch 'origin/feature-30660/FHC4_StudierendenGUI_Prototyp' into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-04-18 15:12:55 +02:00
SimonGschnell 4bb9c61168 also fixes the phrasen for the student/Mitarbeiter View Ansicht 2024-04-18 15:06:38 +02:00
ma0068 c90b875aa2 Bugfix reload Prestudent 2024-04-18 15:01:54 +02:00
SimonGschnell bc0d581402 fixes phrasen in the studentProfil 2024-04-18 15:00:28 +02:00
ma0068 eda68ef5e0 BugFix Watch Reload Tabs 2024-04-18 14:54:18 +02:00
SimonGschnell 4e5379c5d9 adds an edit button over every section in the profil page to edit that section 2024-04-18 14:53:51 +02:00
SimonGschnell cc0ea44de3 also adds the new controller functions to the CisVue/Cms and CisHmvc/Cms 2024-04-18 11:56:55 +02:00
SimonGschnell 3993d614d4 updates news fetching and DB_Model pagination methods 2024-04-18 11:52:58 +02:00
Andreas Österreicher 3a4492671d Fixed Signing Documents via CIS 2024-04-18 08:53:22 +02:00
Werner Masik b2deea6962 added db schema for Gehaltsbaender 2024-04-17 16:40:12 +02:00
SimonGschnell 71f63095c2 makes component Pagination page_size prop a required prop 2024-04-17 15:15:51 +02:00
SimonGschnell 92f2c6e0a2 passes the page_size down from the parent component to the child component 2024-04-17 15:12:55 +02:00
SimonGschnell 284ae0637e makes it possible to send the page_size from the frontend to the backend to adopt how many rows to query 2024-04-17 14:54:22 +02:00
SimonGschnell 6c642f1242 changes how the pagination is done in the DB_Model 2024-04-17 14:23:09 +02:00
ma0068 9da2854e61 temp save 2024-04-17 12:25:24 +02:00
ma0068 6211a77119 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-04-16 15:43:03 +02:00
ma0068 2f08d1b1c1 Notizcomponent: add twoColumnsLayout, refactor UX 2024-04-16 15:42:49 +02:00
cgfhtw 006a763436 Konto delete 2024-04-16 14:34:45 +02:00
cgfhtw e15f4981fb Konto new 2024-04-16 12:56:12 +02:00
Andreas Österreicher 8a115626ba CDATA bei Lernergebnisse hinzugefügt 2024-04-16 10:33:27 +02:00
Andreas Österreicher 20aba9aa90 Merge branch 'feature-27349/DiplomaSupplementQuereinstiegerRahmenvertrag' 2024-04-16 10:22:48 +02:00
cgfhtw 63d7716a6c Konto Edit: Date config 2024-04-16 09:19:17 +02:00
cgfhtw b51ce13024 CSS correction 2024-04-16 09:18:19 +02:00
Andreas Österreicher 8057ecbc60 Merge branch 'feature-15490/lehrauftragsliste_stammkostenstelle_bei_fix_angestellten' 2024-04-15 15:41:53 +02:00
SimonGschnell d77499b73b implementing frontend pagination for components 2024-04-15 13:35:33 +02:00
Johann Hoffmann 563e7bebc0 setupComponent currently uses globalProperties as model for le selection; lektorComponent uses globalProperties for le_id; le_selection now has sophisticated info String detailing every group associated with le for lektor; WIP assistenz filter setup; WIP checking in router guard for missing le_id when they have not loaded yet; 2024-04-12 15:01:37 +02:00
SimonGschnell ad956bef8e adds pagination logic to C4 news 2024-04-12 14:38:01 +02:00
ma0068 69067c1ef9 Notizcomponent refactor: fhcapi, validations, phrases, format dates 2024-04-12 10:48:40 +02:00
cgfhtw efebaeeb27 Edit 2024-04-12 10:38:06 +02:00
cgfhtw 8705341563 FormInput: remove input and update:modelValue event from $attrs to prevent double emits 2024-04-12 10:35:31 +02:00
cgfhtw e32bf2df57 BsModal: send event objects on emit 2024-04-12 10:33:40 +02:00
cgfhtw 44d60e5f52 Validation Stg Permissions 2024-04-12 10:31:22 +02:00
cgfhtw 10a6d374f1 FHC-Core-SAP Phrases 2024-04-12 10:29:57 +02:00
cgfhtw 054ef5d00f Bugfix Api: clearValidation 2024-04-12 10:29:06 +02:00
cgfhtw 1fb019b795 Search by person 2024-04-12 10:28:39 +02:00
SimonGschnell ea9bd93e73 phrasen fix and bug where profilUpdates were only sorted when accepting the request and not denying 2024-04-12 09:39:28 +02:00
cgfhtw e0c7691e04 missing catch 2024-04-11 15:14:15 +02:00
SimonGschnell 86504fd663 doesn't show the footer if the view inside the EditProfil Modal is set to Status 2024-04-11 11:39:29 +02:00
SimonGschnell 2b68831415 adds more filter options for the ProfilUpdateView 2024-04-11 11:20:32 +02:00
SimonGschnell 4fc4cd762d adopts logic to fetched profilUpdate status and topic from the database 2024-04-11 09:15:19 +02:00
Andreas Österreicher c03e6deb95 Removed useless code 2024-04-10 16:45:46 +02:00
SimonGschnell 21c2bafed6 adapt the logic of the profilUpdate feature to use constant status and topics from the database 2024-04-10 15:08:21 +02:00
ma0068 941dce6032 Diplomasupplement: Adaptierung Wording Niveau 2024-04-10 14:48:04 +02:00
Harald Bamberger 94224f7ef7 dvendegrund Ablauf durch Zeit added 2024-04-10 14:28:07 +02:00
Cris f51f006377 Corrected phrase anmerkungIntern 2024-04-10 14:07:41 +02:00
ma0068 487a2b6037 Phrases valdidations, format dates, design adapations 2024-04-10 10:42:16 +02:00
Andreas Österreicher 637392c844 Merge branch 'master' into feature-15490/lehrauftragsliste_stammkostenstelle_bei_fix_angestellten 2024-04-10 09:56:58 +02:00
Harald Bamberger e11dd21a1e add parameter dvendegrund_kurzbz and dvendegrund_anmerkung 2024-04-09 16:35:00 +02:00
ma0068 675ce0e9aa Bug utf8_decode Umlaute in betriebsmitteltyp 2024-04-09 16:20:29 +02:00
ma0068 aed3f99365 Phrases Betriebsmittel 2024-04-09 16:09:14 +02:00
Harald Bamberger 1a1cd76bc4 add grant on hr.tbl_dvendegrund to user vilesci 2024-04-09 15:42:00 +02:00
Harald Bamberger a9818e1f63 add initial values to hr.tbl_dvendegrund 2024-04-09 15:27:47 +02:00
Harald Bamberger 56900e31db add table hr.tbl_dvendegrund, add columns dvendegrund_kurzbz and dvendegrund_anmerkung to hr.tbl_dienstverhaeltnis 2024-04-09 15:08:32 +02:00
ma0068 456700a06e Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-04-09 15:07:33 +02:00
ma0068 d63c7c3457 Logik Inventar, Validierungen 2024-04-09 15:03:43 +02:00
SimonGschnell 5b2365a1e2 stores the status of profilUpdate with their language in the database and adapts the logic to it 2024-04-09 15:02:17 +02:00
Andreas Österreicher e41eada893 Removed unused Code 2024-04-09 14:08:58 +02:00
Andreas Österreicher a32e78c9b8 Merge branch 'master' into feature-27349/DiplomaSupplementQuereinstiegerRahmenvertrag 2024-04-09 13:53:37 +02:00
Cris 1d0c2be449 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-04-09 11:33:38 +02:00
Andreas Österreicher bdb0a5702d Fehler behoben wodurch keine Note im Freigabemail angezeigt wurde
Fehler behoben wodurch keine Punkteübernahme bie Nachprüfungen möglich
war
2024-04-09 11:24:44 +02:00
Harald Bamberger 026a276c02 add grant on frist_id sequence 2024-04-09 11:11:03 +02:00
Harald Bamberger 3b41df5ddc Merge branch 'master' into feature-37107/Fristenmanagement 2024-04-09 10:44:02 +02:00
SimonGschnell 78031bf1ad fixes buggs that were produced with the introduction of new phrasen 2024-04-09 09:08:47 +02:00
SimonGschnell 2df91bce5c adds phrasen to the ProfilUpdateView.js file 2024-04-08 15:49:28 +02:00
SimonGschnell 960341e25d adds more profil phrasen error messages 2024-04-08 15:08:20 +02:00
SimonGschnell 1b04d70839 adds phrasen for profil in php controller and adds error message phrasen 2024-04-08 15:03:08 +02:00
Andreas Österreicher 8a9477eaf0 Fixed PHP7.4 Warning 2024-04-08 12:54:05 +02:00
cgfhtw ee6221e325 add konto tab 2024-04-08 12:40:23 +02:00
Johann Hoffmann cf0c7a2f8c put le_ids aswell as viewdata for le selection in globalProperties to share between components; using FhcApi Plugin for API calls; le selection in setup now with info (gruppe_kurzbz, lehrform_kurzbz, semester, verband, gruppe); fixed setting foto in viewData after refreshing sum eg after kontrolle; 2024-04-08 12:25:25 +02:00
SimonGschnell b77e56161d fixing some not working phrasen 2024-04-08 09:58:53 +02:00
Werner Masik f2ba0fd469 update phrases and added events for fristenmanagement 2024-04-07 00:33:25 +02:00
SimonGschnell 0cd86e3e54 cannot use this keyword when assigning default values to props in componenets 2024-04-05 14:57:00 +02:00
ma0068 53e44b9df5 Action PrintÜbernahmebestätigung 2024-04-05 14:22:42 +02:00
Andreas Österreicher 257c7a5aac Projektzeitenexport für Administration/HR im Vilesci hinzugefügt 2024-04-05 14:14:13 +02:00
SimonGschnell 150b4ec09d phrasen for acceptDenyUpdate.js and ProfilUpdateView.js 2024-04-05 10:33:23 +02:00
ma0068 a5daa63da4 Table, Form, Backend Crud Betriebsmittel 2024-04-04 16:28:24 +02:00
ma0048 753a193be1 - added phrases for bpks details 2024-04-04 15:41:18 +02:00
SimonGschnell c1cb2904e6 adding phrases for Profil and ProfilUpdate 2024-04-04 15:02:47 +02:00
SimonGschnell 6af2a01166 tabulator5 migration changes 2024-04-04 09:55:41 +02:00
SimonGschnell 2e5f53f59a changes tabulator cell alignment in tabulator5 2024-04-04 09:36:46 +02:00
KarpAlex 2132fe76ae added Plausicheck: students in DUAL Studiengang should have set boolean value dual to true, plausicheck bugfixes (loading model, remove unnecessary property) 2024-04-03 17:39:00 +02:00
Cris cfe73b361e Sorted project phases by start date and bezeichnung in Zeitaufzeichnung
Sorted within dropdown
2024-04-03 15:13:32 +02:00
SimonGschnell dd2f982e95 adding the uniqueID jquery identifier to acceptLehrvertrag.js 2024-04-03 14:33:35 +02:00
Cris a2791fecd1 Sorted projects in alphabetical order in Zeitaufzeichnung
Sorted within dropdown and in project cvs export file.
2024-04-03 13:10:30 +02:00
Cris d2a8d59f6d Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-04-03 12:59:00 +02:00
Cris 9907ee2267 Added phrase global/zeilenAuswaehlen 2024-04-03 11:45:43 +02:00
ma0068 2951b2a0d1 Start Tab Betriebsmittel 2024-04-03 10:26:26 +02:00
Werner Masik 5cabac62d7 add frist events for befristung 2024-04-02 18:33:37 +02:00
SimonGschnell a2d71d3a8d adjusts how the AcceptDenyModal is used and included in the ProfilUpdateView 2024-04-02 16:38:29 +02:00
SimonGschnell 51a65495aa corrects the insertion of the dms_kategorie profil_aenderung in the checksystem 2024-04-02 15:31:56 +02:00
SimonGschnell e33d863732 upgrades pruefungsprotokollUebersicht to tabulator 5 2024-04-02 13:03:52 +02:00
SimonGschnell 4e3ab802b6 removes unnecessary debugging log 2024-04-02 12:49:33 +02:00
SimonGschnell d8fb36543f migrates adminZeitverfuegbarkeit to tabulator5 2024-04-02 12:46:51 +02:00
SimonGschnell e29dfd99f3 migrate approveLehrauftrag/acceptLehrauftrag/orderLehrauftrag to tabulator 5 2024-04-02 12:34:51 +02:00
ma0068 61af95b7e5 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-04-02 09:23:41 +02:00
ma0068 ab3c631030 update Phrases Status 2024-04-02 09:22:59 +02:00
ma0068 2d88ee031c refactor Tab Kontakt api Controller, Phrases alerts 2024-04-02 09:12:26 +02:00
cgfhtw 8ffc8a20d3 s&d 2024-03-29 14:27:45 +01:00
cgfhtw d34ce78c94 s&d 2024-03-29 13:00:54 +01:00
cgfhtw c6f4fbb0b8 Use Udf Component 2024-03-28 15:39:19 +01:00
cgfhtw b1c094383f Udf Component 2024-03-28 15:38:50 +01:00
cgfhtw 46fff01eaa Form_validation: extra functions 2024-03-28 15:37:50 +01:00
cgfhtw 24641d1444 Tabs: use computed on titles 2024-03-28 15:35:43 +01:00
cgfhtw abfd92e387 Fetch: check for intermediate properties of error object 2024-03-28 15:35:26 +01:00
Cris ba1fa6add4 Merge branch 'master' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2024-03-28 13:20:51 +01:00
Cris 8d8e45b6de Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-03-28 13:20:16 +01:00
Cris 05516f2952 Fixed: issue with component tabs not recognizing loaded phrases
Vue.computed ensures loading phrase reactively when phrases are loaded
2024-03-28 13:19:31 +01:00
Cris d34f5b92f4 Added new phrases for softwarebereitstellung- and for core app 2024-03-28 13:14:34 +01:00
ma0068 3023cd2e94 Refactor status for api-controller, add phrases for alerts 2024-03-27 11:23:38 +01:00
ma0068 65c7db7ae4 bugfix phrases tabulator, refactor Prestudent.js using FHCAPI_CONTROLLER 2024-03-25 13:28:28 +01:00
ma0068 b907f01ebb Phrases History and Status, Formvalidation Prestudent 2024-03-25 09:09:40 +01:00
Johann Hoffmann 927ed934c0 new Controller & routes for Landing Page; Fixed querying students for n LE; Pictures in LektorOverview & Detailview; WIP SetupComponent to select missing parameters in case; added highcharts library as pure JS; WIP designing Charts based on role & parameter input or setup; Integration in old cis via Mein Cis/Meine LV aswell as Studium/Studiengänge currently as "Anwesenheiten NEU"; WIP Landing Page Design; WIP LE Selection from Stundenplan Entries with appropriate Classification; defined settings for QR Regeneration and showing time left on a progress bar; entry query parameters are being handled inside globalProperties, controller parameters are still inside permissions array; 2024-03-22 14:12:17 +01:00
ma0068 1b3c052c12 codesniffer 2024-03-22 13:00:05 +01:00
ma0068 9038910303 phrases 2024-03-22 10:36:57 +01:00
cgfhtw 06b0529813 Autocomplete: empty message 2024-03-22 09:10:13 +01:00
cgfhtw c4942cc70e Studstatus => FhcApi 2024-03-21 15:45:55 +01:00
SimonGschnell 7dec1178e4 changes the parameter list of the tooltip function in tabulator 5 for approveAnrechnungUebersicht and reviewAnrechungUebersicht 2024-03-21 14:51:04 +01:00
SimonGschnell 72b19987bd removes unnecessary debugging prints 2024-03-21 14:46:03 +01:00
SimonGschnell 1a76231df0 migrated orderLehrauftrag to tabulator5 2024-03-21 14:37:28 +01:00
SimonGschnell 57e5626fe4 reset the navbar to use bootstrap3 2024-03-21 13:52:56 +01:00
SimonGschnell a8c60c105d migrating approveLehrauftrag to tabulator5 2024-03-21 13:42:43 +01:00
ma0068 27715c7f5f update prestudent: uft8-coding, foerderrelevant, permissions 2024-03-21 13:28:51 +01:00
SimonGschnell 47dfb66b8d replacing string concatenation with string literals for tableWidget Header and Footer 2024-03-21 09:27:44 +01:00
SimonGschnell 081a2d69f5 set version 3 as the default version of bootstrap for the tableWidget 2024-03-21 08:49:28 +01:00
ma0068 1b4a2f2d7a Refactor right hasPermissionToSkipStatusCheck 2024-03-21 07:58:37 +01:00
SimonGschnell 59f25bd3a2 adding the bootstrapVersion flag to the /widget/table view to dynamically render css classes + little fixes 2024-03-20 13:26:23 +01:00
SimonGschnell 78a16982f8 updates the tableHelpsite to use bootstrap5 classes if the bootstrapVersion flag is set to 5 2024-03-20 13:25:32 +01:00
Cris bc798bd0b4 Added uniqueId prop to Filter.js to fix URL using apiFunctionParameters.filterUniqueId 2024-03-20 09:58:25 +01:00
Cris f6eceb892d Added label property 'class' to Input.js
...which fixes style issues when creating input-group buttons using the Input.js component
2024-03-20 09:52:26 +01:00
Cris 6eae83f4eb Added primevues autocomplete slot template to Input.js
Now, when using the Input Component with type 'autocomplete', it is possible to add also primevues built in slot templates there
2024-03-20 09:50:03 +01:00
Cris 842e62b0dd Fixed Input.js error causing to keep last entries' first letter in form inputs, even when formdata was emptied 2024-03-20 09:42:23 +01:00
Cris 10e57dae2d Adapted style of .tabulator-cell .btn to be squared and increased padding 2024-03-20 09:38:08 +01:00
cgfhtw 69803cdb0d Phrasen: Bugfix - correct function for multiple categories 2024-03-20 08:27:26 +01:00
Werner Masik 426a439552 added sort column to frist 2024-03-20 00:13:55 +01:00
cgfhtw 4e6b7a845b FhcApi: use errorHeader for multiple calls 2024-03-19 16:54:14 +01:00
cgfhtw 30efd55d6c FhcApi: settle handled Promises & discard them in FhcAlert 2024-03-19 16:53:36 +01:00
SimonGschnell de15d43bb7 adds bootstrapVersion flag to the tableWidget options to render bootstrap3 classes or bootstrap5 classes 2024-03-19 15:29:28 +01:00
ma0068 a495ff9b98 Popup Löschen bei letzter Rolle 2024-03-19 14:31:50 +01:00
ma0068 54b2dce3d6 update DeleteStatus and Prestudent, with Logs and Transactions 2024-03-19 10:58:59 +01:00
cgfhtw 8f0e837fb7 Phrasen Plugin: Bugfix this 2024-03-19 08:45:10 +01:00
SimonGschnell acac5dfc65 trying to independenly restyle the navigationWidget 2024-03-18 15:17:14 +01:00
SimonGschnell 92cb4dedef migrates adminAnrechnungData and adminAnrechnung.js to use tabulator5 2024-03-18 11:49:54 +01:00
SimonGschnell 3cdc051861 updates adminAnrechnung view to bootstrap5 2024-03-18 11:42:34 +01:00
SimonGschnell 961526925c updates reviewAnrechnungDetail.js to change the correct bootstrap5 classes in the javascript 2024-03-18 11:07:12 +01:00
SimonGschnell 571bf8ebad update reviewAnrechnungenDetail to Bootatrap5 and little styling fixes for other Detail views 2024-03-18 11:02:26 +01:00
Johann Hoffmann 44260ddb4d basic link to Anwesenheit Extension from cis_menu_lv.inc.php checking on CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN in global.config-default.inc.php 2024-03-18 10:58:14 +01:00
Johann Hoffmann b39b8559d9 Merge branch 'master' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp 2024-03-18 10:55:05 +01:00
SimonGschnell 72bf2525b7 updating reviewAnrechnungUebersicht to bootstrap5 and tabulator5 2024-03-18 10:14:05 +01:00
cgfhtw b147f73954 Merge branch 'master' into feature-37246/APIs_Konsolidierung 2024-03-18 09:51:29 +01:00
SimonGschnell 83ccc93305 little adjustments and migrations 2024-03-15 15:02:17 +01:00
SimonGschnell 5ecac3cb99 migrates createAnrechnung to bootstrap 5 and tabulator 5 2024-03-15 15:01:55 +01:00
SimonGschnell 183cb1ac17 little adjustments on requestAnrechnung 2024-03-15 12:52:21 +01:00
SimonGschnell cc461aab8b updates js file of approveAnrechnungDetail to be bootstrap5 conform 2024-03-15 12:52:00 +01:00
SimonGschnell f9c894307d buttons with attribute disabled and title fix 2024-03-15 11:58:31 +01:00
SimonGschnell 9360c8a470 migrates approveAnrechnungDetail to bootstrap5 and adds little adjustments to requestAnrechungImportant 2024-03-15 11:57:11 +01:00
SimonGschnell 868d10ffd6 adds bg-secondary-subtle to the color palette and fixes buttons that are disabled and have a title attribute 2024-03-15 11:56:16 +01:00
SimonGschnell 465ab736ee changed AnrechnungenInfo panel to bootstrap5 accordion 2024-03-15 11:18:31 +01:00
ma0068 e5a0dcb829 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-03-14 15:53:39 +01:00
ma0068 4f8d620814 refactor updateStatus 2024-03-14 15:42:20 +01:00
SimonGschnell 8556632f90 updating approveAnrechnungDetail to boostrap5 2024-03-14 11:36:42 +01:00
ma0068 ac508a9f19 bug Anzeige Orgform 2024-03-14 11:02:45 +01:00
ma0068 e32c68e0e3 update function advanceStatus 2024-03-14 10:32:39 +01:00
SimonGschnell 8a835cb7f8 reset searchbar.js fixing searchbar style 2024-03-13 14:44:56 +01:00
cgfhtw 9ae3a6dc29 Form Input: label as prop 2024-03-13 14:25:01 +01:00
SimonGschnell 3c2190b280 fixes zustellAdressenCount for EditAdresse and formats code files 2024-03-13 14:01:29 +01:00
SimonGschnell c0e6552c08 fixes zustellKontakteCount in EditKontakt 2024-03-13 13:44:08 +01:00
ma0068 87384f42f9 Update Logik Lehrverband: as function, with transactions 2024-03-13 13:31:53 +01:00
SimonGschnell e7480eb9ff hotfix, editProfil modal in fetchProfilUpdates component 2024-03-13 12:23:45 +01:00
SimonGschnell 1816f3f5f6 fully upgrades the approveAnrechnungUebersicht to tabulator5 2024-03-13 10:22:10 +01:00
Werner Masik e28627a676 removed verantwortlich column from tbl_frist 2024-03-12 17:34:13 +01:00
SimonGschnell 6722fde9c9 adapts approveAnrechnungUebersicht for the new tabultor5 functions 2024-03-12 15:33:24 +01:00
cgfhtw 874f08f6dd Merge remote-tracking branch 'origin/feature-30660/FHC4_StudierendenGUI_Prototyp' into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-03-12 15:16:54 +01:00
cgfhtw 77ebf1d857 Apply to changes from master 2024-03-12 15:08:33 +01:00
SimonGschnell 70418b8ff6 updates TableWidget.js functions that are no longer valid in tabulator5 2024-03-12 14:30:40 +01:00
SimonGschnell 1dc4f5b56a upgrading tableWidget to tabulator 5 with custom jquery_wrapper 2024-03-12 12:28:59 +01:00
cgfhtw 1a39abf7c7 Merge branch 'master' into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-03-12 11:31:49 +01:00
Harald Bamberger 691bbaaf82 workaround for tabulator jquery_wrapper 2024-03-12 09:59:21 +01:00
ma0068 a49075bcb7 check Bismeldestichtag, refactor Lehrverband 2024-03-12 07:52:51 +01:00
cgfhtw 6acf65b49f Form Component: expose _defaultErrorHandlers 2024-03-11 15:24:48 +01:00
cgfhtw 40c98b1dcc FHCAPI Controller: optional status param for error function 2024-03-11 15:23:54 +01:00
cgfhtw b359a77a8d Comments 2024-03-11 09:56:34 +01:00
cgfhtw d259c0d35c Fetch: more robust error handling 2024-03-11 09:46:59 +01:00
cgfhtw 011b4a83eb Filter => FhcApi 2024-03-11 09:46:39 +01:00
SimonGschnell aa7982fea9 adds jquery adjustments 2024-03-08 12:34:26 +01:00
cgfhtw 85f9b14326 Comments 2024-03-07 16:56:37 +01:00
cgfhtw 5f77bdd6fc Spelling 2024-03-07 16:56:30 +01:00
cgfhtw d2eadb98ce Navigation => FhcApi 2024-03-07 16:56:14 +01:00
SimonGschnell 1b65f6f4e6 trying to add callbacks after the tabulator called the tableBuilt event with jquery 2024-03-07 14:48:11 +01:00
cgfhtw 291f32bfe2 Tabs => FhcApi 2024-03-07 14:35:29 +01:00
ma0068 3a9f6a0edd check Meldestichtag, update function getHistoryPrestudent 2024-03-07 14:20:46 +01:00
SimonGschnell 7eda02f366 adds include variable tabulator5JQuery to FHC-Common.php 2024-03-07 11:46:05 +01:00
SimonGschnell b1411549f3 better folder structure for Cis Profil 2024-03-07 11:14:58 +01:00
SimonGschnell 96e0bfa72c changes how the EditProfil Modal passes props to its children 2024-03-07 11:08:43 +01:00
cgfhtw f539ed8977 Depricated comment 2024-03-07 08:54:28 +01:00
cgfhtw 20619311e3 Use fhcApi in Searchbar 2024-03-07 08:50:27 +01:00
cgfhtw 4ac46d19e9 Testsearch view: naming convention 2024-03-07 08:23:29 +01:00
cgfhtw dad459e023 Testsearch: Codequality 2024-03-07 08:18:49 +01:00
cgfhtw 8f6fbda4cf Testsearch: Bugfixes 2024-03-07 08:11:58 +01:00
cgfhtw b6723e92d8 Code Quality 2024-03-07 08:01:11 +01:00
cgfhtw 1344ab987e Options for custom FhcApiFactory 2024-03-06 16:52:42 +01:00
cgfhtw 1dcece8563 Use Factory for Phrasen 2024-03-06 16:52:10 +01:00
cgfhtw f2ebf25640 Use new FhcApiFactory Folder 2024-03-06 16:51:25 +01:00
cgfhtw f6427f57b8 Use FHCAPI Controller for Phrasen 2024-03-06 16:49:35 +01:00
cgfhtw 68459e086a Auth_Controller special permissions 2024-03-06 16:15:04 +01:00
SimonGschnell 464799d22b tabulator upgrade 2024-03-06 14:46:21 +01:00
Cris 03e166dc89 Merge branch 'master' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software
# Conflicts:
#	public/js/components/filter/Filter.js
#	public/js/plugin/FhcAlert.js
#	system/filtersupdate.php
2024-03-06 14:07:19 +01:00
Cris 0940ea77de Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-03-06 13:59:06 +01:00
cgfhtw 872ef7c31c Move Phrasen API 2024-03-06 13:02:34 +01:00
cgfhtw e89aa824d2 FHCAPI_Controller extends Auth_Controller + auth error handling in FhcApi 2024-03-06 11:48:15 +01:00
cgfhtw 1b65378d6c Auth_Controller private functions 2024-03-06 11:47:34 +01:00
Werner Masik 77666e5210 added column verantwortlich_uid 2024-03-06 08:27:39 +01:00
ma0068 fdbbba5038 add phrase location 2024-03-05 16:42:06 +01:00
ma0068 5b795c2ccf phrases update merge conflict 2024-03-05 16:36:43 +01:00
ma0068 7bec7016c3 merge master into branch FHC4 2024-03-05 16:31:41 +01:00
SimonGschnell e41e24be04 adding the option to add css classes to the HTMLWidget 2024-03-05 15:38:51 +01:00
ma0068 aadaa3f2a3 Revert "css"
This reverts commit 91c01f36f4.
2024-03-05 15:18:14 +01:00
Cris 7f735e9a10 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-03-05 13:05:03 +01:00
ma0068 91c01f36f4 css 2024-03-05 10:34:01 +01:00
SimonGschnell 144a872c98 adds cutsom cis css style which lowers the overall font size 2024-03-05 09:36:16 +01:00
ma0068 35bf6a2efd Tab Status: show Dropdown Statusgruende only if exisiting 2024-03-05 09:31:50 +01:00
ma0068 861f8a7288 Prestudent: Button Save inactive, if there are changes 2024-03-05 08:47:45 +01:00
ma0068 caac612a0d confirm status and add transactions 2024-03-04 15:45:54 +01:00
SimonGschnell b7a1236acc anrechnung.css update 2024-03-04 15:06:08 +01:00
SimonGschnell dd309e972b js alert messages update, need to update the phrasesupdate.php 2024-03-04 15:03:49 +01:00
SimonGschnell 84ba0dbb64 bootstrap 5 upgrade (tooltips,cards,margins,..) 2024-03-04 13:50:06 +01:00
ma0068 a7f1e43225 Status als eigener Tab 2024-03-04 10:10:35 +01:00
ma0068 b98794a292 fix bug Validierung checkifExistingStudentRolle 2024-03-04 08:40:08 +01:00
Werner Masik c60f7ed8b0 dbUpdate for fristenmanagement completed 2024-03-01 15:43:15 +01:00
SimonGschnell ccf01100bb adds new classes because alert-info/warning/... are not consistent in the new bootstrap versions 2024-03-01 15:36:10 +01:00
Werner Masik 7a6d095b78 create db tables for fristenmanagement 2024-02-29 17:09:59 +01:00
ma0068 77e31f2da6 Delete Prestudent 2024-02-29 10:58:45 +01:00
ma0068 88df5057fb Update, Vorrücken, Delete, Refactoring Statusvalidations 2024-02-27 16:53:37 +01:00
Johann Hoffmann 8ccc621a91 Finalized db schema changes for Anwesenheitskontrolle and Checkin; Multiple Lektor scenario not being managed yet; reworked frontend requests towards API Controller to not confuse vue router; WIP UX; 2024-02-27 11:42:42 +01:00
SimonGschnell 21f7099878 refactor 2024-02-23 14:32:06 +01:00
ma0068 843ddad987 Statuschecks, Berechtigungen, add new Status 2024-02-23 12:28:26 +01:00
SimonGschnell f09692edd1 adds primevue autocomplete field for EditAdresse 2024-02-22 15:04:24 +01:00
SimonGschnell ee7a819094 Merge branch 'master' into feature-25999/C4_ma0594dev 2024-02-22 12:06:16 +01:00
SimonGschnell 989f1ecf02 finishes the documentation in Profil.php controller and refactors getView 2024-02-22 11:50:08 +01:00
Johann Hoffmann 63a06dfef2 WIP api controller backend; WIP adapting queries to new db schema; 2024-02-22 10:30:18 +01:00
SimonGschnell 0b84e1b608 finishes documentation on Profil.php controller 2024-02-22 09:00:53 +01:00
SimonGschnell 4edd242f09 adds documentation to the Profil.php controller not finished 2024-02-21 15:44:41 +01:00
SimonGschnell 2a393f0087 adds the fields gemeinde and nation to the EditAdresse Component and adds autocomplete for the gemeinde if the nation is A 2024-02-21 12:31:41 +01:00
SimonGschnell 1bed062a01 querying the right data for the EditAdresse Nation and Gemeinde Fields 2024-02-20 15:57:17 +01:00
SimonGschnell 6f7bca6eab adds loading modal to ProfilUpdateView 2024-02-20 14:32:28 +01:00
SimonGschnell 47abce4aad handles the loading modal in the root Profil app when inserting a new profil update that may takes some time because it has to send out emails 2024-02-20 10:50:35 +01:00
SimonGschnell 1afb9130c0 adds a loading animation when waiting for the emails to be sent out when inserting a new profil update request 2024-02-19 15:12:16 +01:00
SimonGschnell 2e9cc2b291 /ProfilUpdate/id/ was added to the ProfilUpdate controller to automatically open the necessary profil_update on startup of the page, this functionality is used when sending emails with the link to the profil_update 2024-02-19 14:36:45 +01:00
SimonGschnell 2d5aea2bb8 translates the english status into a german version for the email vorlage 2024-02-19 09:14:45 +01:00
SimonGschnell 318087c572 sends email to the user if a profil update was accepted or rejected 2024-02-16 15:37:20 +01:00
SimonGschnell 501224b9b7 sends emails on insertion of an profil update to the studiengänge in case of students and to hr in case of a mitarbeiter 2024-02-16 14:33:49 +01:00
ma0068 6a5b2db79d Start Actions New, Edit, Delete 2024-02-15 17:02:16 +01:00
SimonGschnell 34b995ed6d adds dms_kategorie for profil updates as an insert into statement in the dbupdate file 2024-02-15 16:20:54 +01:00
SimonGschnell 04f6ee6156 Merge branch 'master' into feature-25999/C4_ma0594dev 2024-02-15 15:16:07 +01:00
SimonGschnell 6eeeb8b4b7 send email 2024-02-15 15:09:41 +01:00
SimonGschnell 279fbe51c3 sendMail function now gets all the studiengang emails of an active student or sends the mail to personalverwaltung if it is a mitarbeiter 2024-02-15 14:24:07 +01:00
Johann Hoffmann afa00caa4c Merge remote-tracking branch 'origin/feature-34543/UX_Template' into feature-33683/digitale_anwesenheitsliste_und_entschuldigungsmanagement_fuer_studierende_prototyp
# Conflicts:
#	system/filtersupdate.php
2024-02-15 14:16:33 +01:00
SimonGschnell fd260a6307 changes the check if a user has permissions to accept or deny a profil update 2024-02-15 09:59:27 +01:00
SimonGschnell 028be08ec3 fixes little bug with profil update checking 2024-02-14 14:38:21 +01:00
SimonGschnell 5758d7cf4f overrides old zustelladressen/kontakte when changing or adding a new zustelladresse/kontakt 2024-02-14 14:18:31 +01:00
SimonGschnell b655c4021a instead of calculating how many zustelladressen or zustellkontakte a user has in the backend, it is calculated in the client side to prevent an extra api call 2024-02-14 11:42:20 +01:00
SimonGschnell 65a9b8c80f little fix 2024-02-14 09:01:40 +01:00
SimonGschnell bfba05753e also shows the zustellungs warning when there is more than one kontakt marked as zustellung 2024-02-14 08:56:25 +01:00
SimonGschnell 5ee241d914 now editAdressen shows a warning message if a new adresse is marked as zustelladresse 2024-02-13 15:30:23 +01:00
Cris 8f81426fa4 Corrected error when using alertMultiple and handleSystemMessage 2024-02-13 14:54:42 +01:00
Cris 6140e15139 Removed unused tabulatorAdditionalColumns property. Instead additional cols like 'action buttons' are now checked by index. 2024-02-13 14:53:01 +01:00
SimonGschnell 409221434a removes the checkbox for heimatadresse because it should not be changed by the user 2024-02-13 14:25:07 +01:00
SimonGschnell 66b843be1b hides the profil updates list if no profil update is present 2024-02-13 14:20:01 +01:00
SimonGschnell 1be8c27cb5 checks the permissions of a user when accepting or denying a profil update 2024-02-13 13:37:10 +01:00
Cris acb29c5c69 Merge branch 'master' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software
# Conflicts:
#	application/views/templates/FHC-Footer.php
#	composer.json
#	public/js/components/Bootstrap/Modal.js
#	public/js/components/filter/Filter.js
#	public/js/plugin/FhcAlert.js
2024-02-13 11:54:55 +01:00
SimonGschnell 92f2f5108c refactor of Profil.php to reuse function functionalities 2024-02-13 11:39:57 +01:00
Cris 91f43665fd Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-02-13 10:54:14 +01:00
ma0068 7ec24bfc7b Component Status: Tabelle 2024-02-13 10:45:00 +01:00
SimonGschnell 24b467cd90 show different options for address types if the user is a mitarbeiter or a student 2024-02-12 16:29:19 +01:00
SimonGschnell 9ac523c087 deletes column name from public.tbl_profil_update 2024-02-12 16:00:17 +01:00
SimonGschnell 4b898bd976 queries full name of user that created profil_update using join in Profil_update_model 2024-02-12 15:58:52 +01:00
ma0068 f4197f090b Component Gesamthistorie 2024-02-12 15:11:00 +01:00
SimonGschnell 78bffb1348 little bugfix 2024-02-12 14:08:26 +01:00
SimonGschnell 6aa0bbb037 fixed little bug with fileOutput 2024-02-12 12:27:15 +01:00
SimonGschnell a09a350338 berechtigungen für die Ansicht von Profil Update Dokumente 2024-02-12 11:30:49 +01:00
ma0068 824423f3ea Update Fkt getTypenStg() 2024-02-12 11:00:35 +01:00
ma0068 a21a5ce044 edit field priority only with right basis/prestudent 2024-02-12 09:18:33 +01:00
SimonGschnell b21d3448cb fixes some data handling errors in controller functions 2024-02-12 09:07:51 +01:00
SimonGschnell 90012856dc EditAdresse layout change 2024-02-09 15:21:53 +01:00
SimonGschnell bbf6616cd9 corrects the display of links to attachments of a profil update request 2024-02-09 14:41:29 +01:00
SimonGschnell 43492add0b changes how files are attached/replaced to a profil update 2024-02-09 13:55:08 +01:00
ma0068 898f40e8a5 hidden fields ZGV depending on Config entries 2024-02-09 12:14:14 +01:00
ma0068 c5f69d0e44 Prestudent: Form und Save/Upload Logic 2024-02-09 08:36:33 +01:00
SimonGschnell cda13ac705 makes the send button in the profil update popup disabled instead of not showing it 2024-02-08 13:47:03 +01:00
SimonGschnell 89bc5a5d9d Assistenten koennen nur Profil Aenderungen von Studenten ansehen deren Organisationseinheit in den Berechtigung des Assistenten vorhanden sind (und kleiner sessionStorage fix der einen String zu Boolean converted) 2024-02-08 11:48:14 +01:00
ma0068 9d6159c202 Start Prestudent Tab - Forms 2024-02-07 17:54:52 +01:00
SimonGschnell fa1871a059 adopting profil controllers/models/views to db table change 2024-02-07 16:34:00 +01:00
SimonGschnell 3739581a29 db tabellen anpassung 2024-02-07 16:25:39 +01:00
SimonGschnell 9362aea0cf when user does not have permissions to accept/deny a profil update request it is notified via alert modal 2024-02-07 14:21:25 +01:00
SimonGschnell 286c7be83d only displays profil update requests the uid has permissions for (mitarbeiter/stammdaten or student/stammdaten), also fixes bug and adds JSON.parse to get the value in the sessionStorage 2024-02-07 13:25:50 +01:00
ma0068 d56dbdf563 Adaptierung Notizcomponent: teleport datepicker, tinymce mount conditionally, fehlerhandling missing id and type 2024-02-07 09:28:30 +01:00
SimonGschnell 1e260a178c trying to restructure where editData is created 2024-02-06 16:24:43 +01:00
SimonGschnell 3d2c7e4026 sorts the data of the profil updates before displaying them in a table and tooltips have been added to the hr profil update requests table 2024-02-06 11:26:45 +01:00
ma0068 1ddf5a8370 Notizcomponent: Tinymce optional 2024-02-06 08:08:17 +01:00
SimonGschnell f47650f5e9 shows a menu when right clicking a profil update request in the hr view 2024-02-05 15:33:51 +01:00
Johann Hoffmann c6d4c34cad define AnwesenheitenByLektor in system/filtersupdate.php 2024-02-05 15:32:03 +01:00
SimonGschnell ff88581ecd stores the value of the selection to show all or only the pending Profil update requests in the sessionStorage 2024-02-05 14:26:38 +01:00
SimonGschnell 4faaa78ee1 also shows the zustelladresse checkbox when viewing an Adresse component in the hr View for Profil Updates 2024-02-05 13:16:51 +01:00
SimonGschnell a2d0f9e39a funciton that queries the ProfilUpdates now takes a associative array instead of multiple separate parameters 2024-02-05 11:17:07 +01:00
SimonGschnell 6e55382d15 adds zustelladresse as a field to EditKontakte component 2024-02-05 09:52:27 +01:00
ma0068 23853e4a19 temp 2024-02-05 07:56:24 +01:00
ma0068 2fcbbcac84 refactor NotizComponent 2024-02-02 15:10:46 +01:00
SimonGschnell c88da53c03 only allows to user to send profil updates when the input doesn't correspond the original values 2024-02-02 09:49:07 +01:00
SimonGschnell e5182a20ac adds a select to the profilUpdateRequests to change display between only pending and all requests 2024-02-01 15:27:24 +01:00
SimonGschnell d813f55a9b makes it possible to display documents when reviewing profil update requests 2024-02-01 14:08:55 +01:00
SimonGschnell 1460e6ed80 modifing uploaded files int the fetchProfilUpdates component works correctly 2024-01-31 15:22:03 +01:00
SimonGschnell 0e69e432da fixes a lot of bugs and adds the inseramum/insertvon/updateamum/updatevon fields to the cis_profil_update db table 2024-01-31 14:26:54 +01:00
SimonGschnell 6f081e4136 removes logs 2024-01-31 09:15:48 +01:00
SimonGschnell df1fe01abe makes watcher eager and aligns files vertically 2024-01-31 09:05:23 +01:00
Cris 7e14fff7f3 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-01-30 17:18:55 +01:00
SimonGschnell 3362eb8e31 changing the text_input component to accept documents for the name or the title of a PersonUpdateRequest 2024-01-30 15:59:56 +01:00
SimonGschnell a21a292da6 dokument upload 2024-01-29 16:48:41 +01:00
ma0068 ed71077243 update lastupdate Contacttable 2024-01-29 16:09:07 +01:00
ma0068 b99b09ca6a Form Validation Notiz und Kontakt-Tab 2024-01-29 14:24:47 +01:00
SimonGschnell 76f2501fec little layout fix 2024-01-29 11:14:51 +01:00
SimonGschnell 9ebb04a01b StudentView also uses the layout components 2024-01-29 09:49:50 +01:00
SimonGschnell 783a2fb2b0 removes print in MitarbeiterView Controller and MitarbeiterView uses the components to render the information 2024-01-29 09:22:20 +01:00
ma0068 b7fa6b2072 update Forms 2024-01-29 07:52:15 +01:00
SimonGschnell bdf59f3230 layout fixes and adding profilUpdateRequests component to Student view 2024-01-26 17:51:08 +01:00
SimonGschnell bece495ac8 fixes edge cases realted to creating new profil update requests 2024-01-26 16:37:39 +01:00
ma0068 e824d48edf update action and delete buttons in Kontakt-Tab 2024-01-26 14:40:57 +01:00
ma0068 c49a36e9ca insert Phrasen to Modals and Tables in Tab Kontakt 2024-01-26 14:02:34 +01:00
SimonGschnell 15cd9155f1 updates kontakt_id / adresse_id in profilUpdateRequest after inserting new kontakt/adresse in db 2024-01-25 16:43:47 +01:00
ma0068 4653e070b1 Notiztab: Phrasen für Form und Tabulator Notiz, Update Actionbuttons 2024-01-25 10:27:43 +01:00
SimonGschnell 20672cd311 add/delete/update von Adressen funktioniert 2024-01-24 17:03:06 +01:00
SimonGschnell a390eefd75 add/delete/update kontakt is possible 2024-01-24 16:06:22 +01:00
SimonGschnell 20d6a34506 little style changes and adds name field to the public.tbl_cis_profil_update table 2024-01-24 12:18:21 +01:00
ma0068 b8c885c8a4 Remove html-Tags in tabulator text 2024-01-24 09:04:53 +01:00
SimonGschnell 5f55834ccf controller functionality to apply profil update requests to the user 2024-01-23 18:03:38 +01:00
ma0068 2f5d93daa2 change config-ul auf config 2024-01-23 13:38:47 +01:00
ma0068 e513550cba bugfix eingabe textarea Tinymce 2024-01-23 13:22:26 +01:00
SimonGschnell 13f2bb4e85 fixes little bug where status timestamp was converted from null to the current date, with create_date in php 2024-01-23 11:40:02 +01:00
SimonGschnell df74bade9b fixes bug when getting all the profil update requests and makes it possible to add a message when dening or accepting a profil update 2024-01-23 11:00:43 +01:00
SimonGschnell 7abe04a69f fixes little bug for View Profil and changes layout of the profil update fetch component 2024-01-22 16:02:52 +01:00
ma0068 4bd430ae79 tiny mce, workaround for binding textfield variable 2024-01-22 14:51:40 +01:00
SimonGschnell fb9b65b138 changes how to display the hr table with all the user update requests and the update request table in the profil view, also adds some new columns to the cis_profil_update table to store the status, status date and status message 2024-01-22 14:45:32 +01:00
ma0068 72bde46ca6 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp
Update Routine
2024-01-19 15:20:12 +01:00
ma0068 33a93457ec finished Handling of Fileuploads 2024-01-19 15:19:57 +01:00
SimonGschnell 0d5e8e89a6 splits the ProfilComponents.js file into multiple components in the ProfilComponents Folder and StudentProfil uses the components 2024-01-19 15:07:57 +01:00
ma0068 3e912f9545 bugfix prop 2024-01-19 09:04:37 +01:00
cgfhtw 7861829ee4 input color 2024-01-18 15:54:23 +01:00
cgfhtw 604bfeea20 Form input component: improvements 2024-01-18 15:41:24 +01:00
cgfhtw dc973217b7 Css improvements 2024-01-18 15:40:56 +01:00
cgfhtw bc71415dd5 Tabs: rename prop configUrl => config 2024-01-18 15:40:42 +01:00
SimonGschnell 84b23a148e modulerizing the profil page in multiple reusable components 2024-01-18 15:32:52 +01:00
ma0068 98c877e9ea Tiny MCE: neue Notiz erstellen 2024-01-18 14:38:23 +01:00
SimonGschnell 5e7e2b63dd disables the kontakt input field in the EditKontakt component if no Kontakttyp was selected 2024-01-18 11:31:28 +01:00
ma0068 0512295b8b Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-01-18 09:46:39 +01:00
ma0068 b9329aa417 temp 2024-01-18 09:46:31 +01:00
SimonGschnell c5f6ce861b when adding a new kontakt or address, it is possible to modify it afterwards 2024-01-18 09:20:01 +01:00
ma0068 bd4bbe0b7a Update response/error handling 2024-01-18 07:45:08 +01:00
cgfhtw 0c0d529478 Tabs: vertical usage & reactive configUrl & configUrl accepts object 2024-01-17 16:03:24 +01:00
cgfhtw f17591327d Quickfix missing "!" 2024-01-17 16:00:56 +01:00
SimonGschnell 8bda0f2f96 first template for the functionality to add a new kontakt/address 2024-01-17 15:34:53 +01:00
cgfhtw 5c9e1b3fd3 Use new Form Components in Details 2024-01-17 15:28:39 +01:00
cgfhtw 8762e87658 Noten: Switch all/current semester 2024-01-17 15:24:44 +01:00
cgfhtw abb9885b3b Fhc.css 2024-01-17 15:23:00 +01:00
cgfhtw 22f6e3fe3b Upload Dms Component 2024-01-17 15:18:38 +01:00
SimonGschnell 49fda27e56 profilUpdates need to have unique adresse_id or kontakt_id 2024-01-17 13:53:32 +01:00
ma0068 364c3f0518 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp
update routine
2024-01-17 13:24:11 +01:00
ma0068 dc5368f346 Letzte Änderung 2024-01-17 13:23:52 +01:00
SimonGschnell a5c77543b1 adds functionality to delete a Kontakt or an Adress 2024-01-17 12:07:06 +01:00
Cris af010a51e9 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-01-17 11:33:54 +01:00
SimonGschnell b53dec6a31 adds breadcrumb to modal and adjusts controller functions and api calls 2024-01-16 15:44:04 +01:00
ma0068 28fe3ef839 Funktionserweiterungen um idType 2024-01-16 14:34:13 +01:00
SimonGschnell 73792d1e78 the user is now able to delete an existing change request that he made 2024-01-15 15:40:55 +01:00
ma0068 09c02b0906 refactoring controllers, codesniffer 2024-01-15 15:29:04 +01:00
SimonGschnell e881abe904 allows user to make profil changes requests and to oversee his requested changes 2024-01-15 15:15:16 +01:00
ma0068 70d7496ed9 bei Löschen von Notiz Entfernen aller DMS- und Einträge in Notizdokument 2024-01-15 14:54:24 +01:00
ma0068 20edb299a7 Form validation 2024-01-15 14:05:34 +01:00
ma0068 61616fbaef Update AppendForm mit JSON.stringify, Update Form, authUid 2024-01-15 13:56:17 +01:00
Cris 579c1c6aff Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-01-15 10:28:10 +01:00
ma0068 8d8c25bd6e Autocomplete Feld Mitarbeiter für Bearbeiterlogik 2024-01-15 09:39:46 +01:00
ma0068 4526c10d30 temp 2024-01-11 12:56:36 +01:00
ma0068 ef6634a38e bugfix FileUpload Component 2024-01-11 09:56:59 +01:00
ma0068 db6e1add8a refactoring Fkt addNewNotiz 2024-01-11 07:37:46 +01:00
SimonGschnell d3a3ebacfc first templates for the components Select and Breadcrumbs 2024-01-10 15:02:11 +01:00
cgfhtw 751c1fd31e Profile Image: Slash removed from path 2024-01-10 14:51:28 +01:00
SimonGschnell 75ce2a0aa8 Shows Select option names without _ 2024-01-10 09:11:24 +01:00
ma0068 7ef88fcc02 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp
pull and push routine
2024-01-09 16:39:51 +01:00
ma0068 284351a024 bugfix format date vuedatepicker 2024-01-09 16:39:38 +01:00
SimonGschnell b1d8a2f5a4 adds topic field to the cis_profil_update table and changes the layout of the editProfil Modul 2024-01-09 15:51:50 +01:00
cgfhtw a3f9e19bd6 Noten manuell ändern 2024-01-09 13:22:37 +01:00
ma0068 d99e260b47 Merge branch 'feature-30660/FHC4_StudierendenGUI_Prototyp' of github.com:FH-Complete/FHC-Core into feature-30660/FHC4_StudierendenGUI_Prototyp 2024-01-09 12:57:28 +01:00
ma0068 83335d6d30 neue Component File, filehandling mit datatransfer 2024-01-09 12:55:35 +01:00
SimonGschnell 5b597dbc31 changing the editProfil Modal from an Accordion to a select 2024-01-08 15:19:18 +01:00
ma0068 ff6f23b3f4 Notiz löschen mit Dokumenten, Start Umbau Funktionen von person_id auf typ 2024-01-05 15:13:10 +01:00
SimonGschnell e479a7aa49 stores the old and the new value in the profil update request, to track which information has to be updated in the database 2024-01-05 10:40:47 +01:00
Simon Gschnell ee8051915e formats the update timestamps in php, differently tracks which properties and informations where changed by the user 2024-01-04 16:06:47 +01:00
cgfhtw c7e008b615 Noten anzeigen 2024-01-04 15:00:13 +01:00
cgfhtw ef91489b29 Bugfixes 2024-01-03 15:49:10 +01:00
cgfhtw b070607f91 reload details on tab change 2024-01-03 15:39:31 +01:00
cgfhtw b4505536f6 track tab changes with event 2024-01-03 15:38:39 +01:00
cgfhtw 9a81111ebc Propagate reload into details tabs 2024-01-03 15:14:44 +01:00
cgfhtw b5bbf89b7d Make current tab accessible from outside 2024-01-03 15:14:11 +01:00
cgfhtw 49c2911557 Bugfix 2024-01-03 15:13:53 +01:00
Simon Gschnell d412c1d00e first template for the hr view to accept or deny profil update requests 2024-01-03 14:38:40 +01:00
ma0068 b07d9a9a63 single fileupload 2024-01-03 09:50:06 +01:00
Simon Gschnell ddab42123b refactores the modal out of the view into its own modal component 2024-01-02 12:50:04 +01:00
Simon Gschnell bb0656c480 http response returns the timestamp of the change 2023-12-29 12:01:25 +01:00
Simon Gschnell a27b80c394 show the date of the last edit profil information request if there is any 2023-12-29 10:17:33 +01:00
Simon Gschnell 59b848c576 fetches profil update request if an entry with uid in table public.tbl_cis_profil_update exists 2023-12-28 11:51:58 +01:00
Simon Gschnell 414541b6cf checks if table entry for uid exists and performs update or insert on result 2023-12-28 10:43:21 +01:00
Simon Gschnell 981e782c57 checks whether the editProfilData was changed by the user and is not in the original state 2023-12-28 10:15:24 +01:00
Simon Gschnell 87f640d66a little layout fix for MitarbeiterViewProfil.js 2023-12-27 11:20:54 +01:00
Simon Gschnell d8cd52f7a0 accordion styling 2023-12-27 11:16:18 +01:00
Simon Gschnell f3e23b888d fixing the accordion with editData 2023-12-27 10:42:33 +01:00
Simon Gschnell 620528fa50 moves the collapseFunction to the parent component Profil and also manages the collapse state from the parent 2023-12-27 09:27:18 +01:00
Simon Gschnell 733275a162 first profil info edit template 2023-12-22 14:18:49 +01:00
ma0068 c2fb582db0 temp 2023-12-22 12:04:03 +01:00
cgfhtw cbd7566e3c CSS improvements 2023-12-22 11:34:51 +01:00
cgfhtw 7dbf29d655 Filter Cmpt: filterType not required (if tableOnly is true) 2023-12-22 11:33:55 +01:00
cgfhtw 4503e0db71 Filter Cmpt: handle rowselection via setup option 2023-12-22 11:05:41 +01:00
cgfhtw 787d479a33 Filter Cmpt: correct type for Column names 2023-12-22 11:04:42 +01:00
cgfhtw a2f944ff92 VueJs Warning: FhcAlert number/string 2023-12-22 11:01:43 +01:00
cgfhtw 2db669ca2e Merge remote-tracking branch 'origin/feature-30660/FHC4_StudierendenGUI_Prototyp' into feature-30660/FHC4_StudierendenGUI_Prototyp 2023-12-22 10:47:55 +01:00
ma0068 e7703f3c9b neues Attribut abschlussbeurteilung_deutsch 2023-12-22 07:55:29 +01:00
cgfhtw 4b5e784081 Tabs: handle null and array values 2023-12-21 15:10:30 +01:00
cgfhtw f479e7ff62 Better List Click handling 2023-12-21 15:09:50 +01:00
cgfhtw c7ee0ce82b Tabs.js: MarkRaw Warning 2023-12-21 14:02:01 +01:00
cgfhtw d38ed229bf Korrekturen Bugs 2023-12-21 14:01:25 +01:00
Simon Gschnell d6ef9c4ec4 adds custom floating label css construct to the rest of the profil views 2023-12-21 11:46:42 +01:00
Simon Gschnell fed4f7f929 replaced form-control with custom css construct 2023-12-21 08:53:56 +01:00
ma0068 5d4ec93b09 Change Font-Size in Tabulator 5, Start Dateiupload 2023-12-20 11:39:28 +01:00
Simon Gschnell 6f8bd9527c changes the styling when hovering over form-control fields in the profil view, so that it does not also change the behavior of other elements that use form-control on the web page 2023-12-19 16:00:43 +01:00
Simon Gschnell 9c69d8cc46 trims the student information so that the value is falsy in javascript 2023-12-19 15:49:57 +01:00
Simon Gschnell 8666dbe3a6 wrong uid was used to get the emails of the student profil view 2023-12-19 15:36:11 +01:00
Simon Gschnell c08171536c changes the tel and mailto links of all profil views 2023-12-19 15:34:28 +01:00
Simon Gschnell 030be5b83f queryies the telefon number of the mitarbeiter with standort and adds tel links to all phone numbers 2023-12-19 11:02:44 +01:00
Simon Gschnell a3e70afdc1 adds font-size 1rem to the .tabulator class of the FilterComponent 2023-12-19 11:01:51 +01:00
Simon Gschnell 8b06ef030a adds icons and some layout changes 2023-12-18 15:27:45 +01:00
Simon Gschnell f0a3b8db95 Merge remote-tracking branch 'origin/feature-25999/C4' into feature-25999/C4_ma0594dev
merges menu width
2023-12-18 12:26:01 +01:00
cgfhtw eb05922043 menu width 2023-12-18 12:25:16 +01:00
Simon Gschnell 5fbe374ea3 removes the p-4 for all screensizes from the cis-main and adds different padding for mobile view Cis-main in Cis.css 2023-12-18 12:21:17 +01:00
Simon Gschnell 64326136d5 Merge remote-tracking branch 'origin/feature-25999/C4' into feature-25999/C4_ma0594dev 2023-12-18 12:14:07 +01:00
Simon Gschnell fa3d9e1e05 layout changes 2023-12-18 12:13:03 +01:00
cgfhtw 9c2f062d34 Css update 2023-12-18 09:56:59 +01:00
cgfhtw 2e1f38cc91 Merge remote-tracking branch 'origin/feature-25999/C4' into feature-25999/C4 2023-12-18 09:54:15 +01:00
cgfhtw ae0c311be3 Css korrektur 2023-12-18 09:53:52 +01:00
KarpAlex b6adf1ad53 Merge branch 'master' into feature-30679/Plausichecks_Behebung_parameter_zur_Identifizierung_eines_Issues_einbeziehen 2023-12-17 19:12:05 +01:00
Simon Gschnell 1d75a26230 responsive layout 2023-12-15 14:40:56 +01:00
ma0068 7c29a726f2 Aktionen Start New, Update, Delete 2023-12-14 16:33:49 +01:00
ma0068 798469dfcc Start Component Notiz und Tab Notizen 2023-12-14 16:01:18 +01:00
Simon Gschnell 98006b3d2b puts hidden quick links in card 2023-12-14 09:19:07 +01:00
Simon Gschnell 91781d3a38 adds cards to the main information of the mitarbeiter profil view 2023-12-13 15:56:24 +01:00
Simon Gschnell d87670edb8 adds Mailverteiler in card 2023-12-13 15:49:51 +01:00
Simon Gschnell 5671bb340b resposive profil information column change and remove default table sideMenu prop 2023-12-13 14:47:40 +01:00
Simon Gschnell bff4fa5544 Merge branch 'master' into feature-25999/C4_ma0594dev 2023-12-13 14:34:37 +01:00
Simon Gschnell b6dbe1513e adds the collapsing funktions to all the different profil view that use a table with more than one column 2023-12-13 13:59:23 +01:00
Simon Gschnell 8fe19d40bc little fix for the collapsing columns function 2023-12-13 13:26:44 +01:00
Simon Gschnell ba17974371 adds the collapsing function to the column itself 2023-12-13 12:58:34 +01:00
Simon Gschnell b400ea758c fixing the hide/show all collapsed table columns function by calling the click event instead of changing the classes and styles manually 2023-12-13 12:54:44 +01:00
Simon Gschnell 058863ba8d fix for show/hide all collapsed columns icon function, weird bug where collapsed columns icons don't work on first click 2023-12-13 11:22:47 +01:00
Simon Gschnell 4715ce3b95 icon to show or hide all collapsed columns 2023-12-13 10:58:05 +01:00
Simon Gschnell a72b8a153e layout changes 2023-12-12 15:34:28 +01:00
Simon Gschnell 633cd6be0f adds wrap word to every view and deltes the old profil view 2023-12-12 14:48:26 +01:00
Simon Gschnell 5b03abb50c restyling for the hidden dropdown quick links 2023-12-12 14:42:15 +01:00
Simon Gschnell 036365e148 shows all columns, removes the hidding of a column 2023-12-12 14:00:01 +01:00
Simon Gschnell 4b45914d4f adds the collapse formater function as a global Vue function that can be used by alle the different view components 2023-12-12 13:50:38 +01:00
Simon Gschnell b2c8bcb2bf adds a little shadow to the collapsed columns in the tables 2023-12-12 13:21:15 +01:00
Simon Gschnell 350911d474 adds responsive layout collapse to both tables 2023-12-12 12:15:27 +01:00
Simon Gschnell 3a191f4a11 adds responsive layout to the tables by collapsing the columns of a table 2023-12-12 12:09:03 +01:00
Simon Gschnell 38301572ae Mailverteiler nehmen ganze Spalte ein bei Viewport lg 2023-12-12 09:41:53 +01:00
Simon Gschnell aefe73b642 overflow-wrap: break-word style for better text wrapping 2023-12-12 09:28:49 +01:00
Simon Gschnell efc8e7c5fe css fix to wrap words when space gets little 2023-12-12 09:04:07 +01:00
Simon Gschnell 37f89010a4 adds Mitarbeiter und Studenten Profil Titel 2023-12-11 15:18:44 +01:00
Simon Gschnell 84706c957e changes dynamically the col width if a kontakt anmerkung is vorhanden or not 2023-12-11 14:35:17 +01:00
Simon Gschnell 9beb426531 adding word wrap to bootstrap columns 2023-12-11 13:47:56 +01:00
Simon Gschnell 832a3de8c5 centers the text of the link under the image 2023-12-11 13:38:44 +01:00
Simon Gschnell d378cd3002 center profil image in the middle 2023-12-11 13:05:25 +01:00
Simon Gschnell f45d692e66 used new layout for the different views 2023-12-11 12:55:54 +01:00
Simon Gschnell e8a89cf277 add comments to the layout to logically seperate the different columns and rows 2023-12-11 09:47:39 +01:00
Simon Gschnell 8f152cdf50 fixed layout bug, table now shows under profil information without disturbing the right panel 2023-12-11 08:51:51 +01:00
Harald Bamberger 3f84fa7f2d use smaller base font-size 2023-12-07 17:17:48 +01:00
Harald Bamberger 0b97a92ae9 use smaller base font-size 2023-12-07 16:03:14 +01:00
Simon Gschnell a48cbaabb9 layout template 2023-12-07 15:59:01 +01:00
cgfhtw 6fa680d19f Fix: use modelValue instead of student in Kontakt.js 2023-12-06 16:33:18 +01:00
Cris 8a29146fc2 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2023-12-06 14:42:45 +01:00
Simon Gschnell 02e7ef12de Profil information layout 2023-12-06 13:47:35 +01:00
Simon Gschnell 617c126aa8 store getAuthUID and getAuthPersonID inside Profil controller to avoid extra calls 2023-12-06 09:52:46 +01:00
Simon Gschnell 28b7a41b80 cleaning up the code not needed in the Profil controler 2023-12-05 13:55:51 +01:00
Simon Gschnell 0d3c55b019 dynamic component inside the profil app now controlls the view and the data 2023-12-05 13:52:31 +01:00
Simon Gschnell 087bf229af restructuring controller 2023-12-05 10:39:39 +01:00
cgfhtw 44cc6a3a83 Merge remote-tracking branch 'origin/feature-30660/FHC4_StudierendenGUI_Prototyp' into feature-30660/FHC4_StudierendenGUI_Prototyp 2023-12-04 10:42:00 +01:00
cgfhtw 9c2ece2bda References like in CI4 2023-12-04 10:37:10 +01:00
Simon Gschnell 71fda916a3 added Menu link and Profile pop up link 2023-12-04 09:25:08 +01:00
Simon Gschnell 75547ea5e3 adding link to search to view profile 2023-12-01 13:35:29 +01:00
ma0068 4fb8bdd5d9 PV Autocomplete 2023-12-01 12:47:53 +01:00
cgfhtw 4ba828d0e8 Add Student Images 2023-12-01 12:44:10 +01:00
cgfhtw da9002356c Tabs Component 2023-12-01 12:43:39 +01:00
ma0068 a105143771 Überarbeitung Tab Kontakt 2023-12-01 12:18:42 +01:00
Simon Gschnell 48f4afae73 adds Ort_kurzbz for the View_Mitarbeiter 2023-12-01 11:41:17 +01:00
Simon Gschnell 38f76f68f1 conditional rendering for different Profile Views 2023-12-01 11:07:25 +01:00
cgfhtw 776908792a Datepicker css 2023-11-29 16:38:20 +01:00
cgfhtw 4e73b40a84 Merge branch 'master' into feature-30660/FHC4_StudierendenGUI_Prototyp 2023-11-29 15:40:24 +01:00
cgfhtw c0252e5ad9 Modal from Master 2023-11-29 15:38:16 +01:00
cgfhtw 9ac31f3925 line ending 2023-11-29 15:32:13 +01:00
cgfhtw 6f3335cc3d vue-datepicker 2023-11-29 15:25:39 +01:00
cgfhtw a8b4e2b399 dont use "useForm" anymore 2023-11-29 15:18:15 +01:00
cgfhtw dd2867a23d composer 2023-11-29 15:14:34 +01:00
cgfhtw 5d7370e4af Form Validation reverse Arguments 2023-11-29 13:31:01 +01:00
cgfhtw d0779eadf9 Merge remote-tracking branch 'origin/feature-30660/FHC4_StudierendenGUI_Prototyp' into feature-30660/FHC4_StudierendenGUI_Prototyp 2023-11-29 12:15:43 +01:00
cgfhtw a0635840b7 New Validation 2023-11-29 12:14:45 +01:00
cgfhtw 74f9ac7600 Cleanup & CSS 2023-11-29 12:14:29 +01:00
ma0068 7a3bb2a374 Section Kontakt und Bankverbindungen überarbeitet 2023-11-28 16:55:20 +01:00
Simon Gschnell f26801b7de adds a prop to the FilterTable component to conditionally render the filter columns, this was added because there is no need for a filter column when the table only has 1 column 2023-11-28 14:58:16 +01:00
Simon Gschnell c68856b740 completes the index view for both student and mitarbeiter 2023-11-28 14:56:42 +01:00
Simon Gschnell e3ec0fc36c upadtes api calls 2023-11-28 14:55:42 +01:00
Simon Gschnell 2df956ef20 layout for index Mitarbeiter 2023-11-27 12:04:57 +01:00
Simon Gschnell 1817757745 adds the @ to the emails and changes the layout of the information displayed on the profile page 2023-11-27 12:01:04 +01:00
ma0068 27e2286096 getNations 2023-11-23 15:50:02 +01:00
ma0068 9f336b4590 Formatierungen modals, Tabulator 2023-11-23 15:38:55 +01:00
Simon Gschnell dee3b35a5d solved table bug 2023-11-23 14:48:05 +01:00
cgfhtw 1d9899d830 Merge remote-tracking branch 'origin/feature-30660/FHC4_StudierendenGUI_Prototyp' into feature-30660/FHC4_StudierendenGUI_Prototyp 2023-11-23 10:24:08 +01:00
cgfhtw d105ea7a56 Interessenten anlegen (Debug Version) 2023-11-23 10:22:48 +01:00
Simon Gschnell d08b904530 mailverteiler und deren mailto href 2023-11-23 10:02:22 +01:00
ma0068 a32cda96d0 tidy up, z-Index for Modal 2023-11-22 15:58:18 +01:00
ma0068 3674315305 update speichern/löschen autocomplete 2023-11-22 13:33:19 +01:00
ma0068 f7d1f459ca reset Modals 2023-11-22 12:49:16 +01:00
ma0068 cc52a9a28b update search 2023-11-22 11:24:27 +01:00
Simon Gschnell 0e813f78fb updates the foto_sperre_function to automatically update the data of the vue component 2023-11-22 09:51:49 +01:00
ma0068 92fdf3da4c Autocomplete, überarbeitung Modal 2023-11-22 09:02:54 +01:00
Simon Gschnell 16b61d0560 Daten fuer die Betriebsmittel und zutrittskarten_ausgegebenam gesammelt 2023-11-20 17:30:58 +01:00
Simon Gschnell 4fead18c06 adds the model calls for the benutzerfunktionen information for the cis profile 2023-11-17 15:27:41 +01:00
Simon Gschnell 6b27c00d30 new data collection 2023-11-17 13:09:32 +01:00
Simon Gschnell 40a58ad9d0 Merge branch 'feature-25999/C4' of github.com:FH-Complete/FHC-Core into feature-25999/C4 2023-11-17 13:05:48 +01:00
cgfhtw 364217c36d Accessibility for Details Tabs 2023-11-17 12:31:10 +01:00
cgfhtw 4158a66da4 accessibility directive first draft 2023-11-17 11:54:36 +01:00
cgfhtw 9c73908733 Merge remote-tracking branch 'origin/feature-30660/FHC4_StudierendenGUI_Prototyp' into feature-30660/FHC4_StudierendenGUI_Prototyp 2023-11-16 16:49:12 +01:00
cgfhtw b684c6a34d DatePicker & Form with v-model & validation in fhcAlert 2023-11-16 16:41:22 +01:00
ma0068 4502eefaae neuer Controller Kontakt.php, Abfragen Adressen 2023-11-16 07:46:48 +01:00
Simon Gschnell dee0bdaa17 querying new data for the cis profile page 2023-11-15 15:09:59 +01:00
ma0068 9fdef54efc Funktion json2odt für newline Qualifikationsziele 2023-11-15 14:24:47 +01:00
Simon Gschnell 7c229bbcee importing the api calls in the component and creating api endpoints for the cis profile page 2023-11-15 13:49:06 +01:00
ma0068 dc76ae8506 neue Tags addon_aktiv und lernergebnisse 2023-11-15 09:44:25 +01:00
SimonGschnell 9227cc12f0 retrieving user data from mitarbeiter and benutzer models 2023-11-14 14:36:47 +01:00
SimonGschnell 5b385d376e creating the controller/view/api base 2023-11-14 11:52:45 +01:00
cgfhtw c0fbc74862 Bug: search url not dynamic 2023-11-13 15:04:41 +01:00
cgfhtw c65fc571ac fix: copy pasta 2023-11-09 09:25:13 +01:00
cgfhtw a4b24880f6 Merge remote-tracking branch 'origin/feature-30660/FHC4_StudierendenGUI_Prototyp' into feature-30660/FHC4_StudierendenGUI_Prototyp 2023-11-06 14:29:25 +01:00
cgfhtw 219113bc73 InteressentIn anlegen: check + getGeschlechter return value 2023-11-06 14:25:38 +01:00
cgfhtw 8e3939a885 bug: path seperator 2023-11-06 11:20:00 +01:00
cgfhtw 52d406bca7 FhcAlert improvements & InteressentIn anlegen part 1 2023-11-06 11:06:10 +01:00
ma0068 81b080ec41 Modal Adressen 2023-11-02 16:41:28 +01:00
ma0068 94fe3b594d Anlage Kontakttab 2023-11-02 12:52:38 +01:00
cgfhtw 45715d78f7 Bootstrap Modal Component 2023-11-02 11:47:09 +01:00
cgfhtw 818a93ab2c search for studiengang_kz 2023-10-31 14:52:54 +01:00
cgfhtw 29600f1059 Basic Search 2023-10-31 14:45:47 +01:00
cgfhtw bd9f3abfea add FhcAlert file 2023-10-31 14:45:29 +01:00
cgfhtw 562b8b000f Don't submit field that is empty when original value is null 2023-10-31 14:44:52 +01:00
cgfhtw be7321723a add FhcAlert 2023-10-31 14:44:04 +01:00
Cris c494dd1cdc Added handleFormErrors- and resetFormErrors method to FhcAlert Plugin 2023-10-31 10:41:00 +01:00
Cris 5a002c0f04 Minor change: Adapted mail-text 2023-10-31 10:40:06 +01:00
cgfhtw aacba9f6ae Accessibility 2023-10-25 16:55:01 +02:00
cgfhtw 6d8606795f Favorites keyboard navigation 2023-10-25 14:04:50 +02:00
Cris fbb00be7cd Added slot 'search' to Filterwidget.js
Slot to inject a autoselect / inputfield to search tabulator, if tabulator should stay empty until search results are provided. (Example: performance reasons if too many data; search for multiple at once)
2023-10-25 12:55:35 +02:00
Cris c6d82fe029 Minor style change of confirmDelete message 2023-10-25 12:49:37 +02:00
Cris 6b2150b066 Fixed: unknown 'fhcerror' to this 2023-10-25 12:48:00 +02:00
cgfhtw 8c7bbff1c1 Favorites 2023-10-25 10:37:51 +02:00
cgfhtw e34bacb443 Routing & dynamic tab loading 2023-10-24 15:52:28 +02:00
Cris 007ee49844 Merge branch 'feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software' of https://github.com/FH-Complete/FHC-Core into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2023-10-24 15:51:10 +02:00
cgfhtw bae7096ca1 Better Primeview esm path 2023-10-24 15:04:45 +02:00
cgfhtw 22453c71b4 fhcAlert: slight improvements 2 2023-10-24 13:35:50 +02:00
cgfhtw d57fd9eb60 fhcAlert: slight improvements 2023-10-24 12:23:12 +02:00
cgfhtw b01cd99a93 Plugin: Fhc Alert 2023-10-19 14:10:55 +02:00
cgfhtw 645972d549 primevue esm & search & favorites 2023-10-19 09:48:42 +02:00
Cris c0b4ad2633 Merge branch 'feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software' of https://github.com/FH-Complete/FHC-Core into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2023-10-17 11:38:29 +02:00
Cris 0f80b9d31b Added Primevue-Toast and -Confirmdialog libraries to FHC-Footer 2023-10-17 11:30:35 +02:00
cgfhtw 65bf35fa3e Studiensemester now 2023-10-16 13:51:21 +02:00
cgfhtw 697b1e5c00 Save Button -> Top Right 2023-10-13 10:40:37 +02:00
cgfhtw c744d48aef "keep-alive" component caching 2023-10-12 15:49:44 +02:00
cgfhtw 93ef1151df Prestudent Query 2023-10-12 15:47:54 +02:00
cgfhtw c74d22d46c Verband Order 2023-10-12 15:47:44 +02:00
cgfhtw 1e449e6fd1 Bugfix: FilterCmpt: reload function 2023-10-11 15:38:30 +02:00
KarpAlex af678b3c56 added vue datepicker to composer 2023-10-09 14:29:38 +02:00
cgfhtw 39ed309dd5 autoselect rows 2023-10-09 11:10:06 +02:00
cgfhtw e28261f4f6 Studiensemester in Variable 2023-10-05 15:41:55 +02:00
cgfhtw 484a48e309 Studiensemester in Variable 2023-10-05 11:08:52 +02:00
ma0068 d1377b3f4e Searchbar Student Prestudent 2023-10-03 16:19:40 +02:00
cgfhtw fa74438f66 Validation 2023-10-02 16:38:11 +02:00
cgfhtw 2a0a0a81f2 Feld Bpk 2023-10-02 11:33:23 +02:00
cgfhtw 468d334530 Feld Zugangscode 2023-10-02 10:44:08 +02:00
ma0068 41ff430464 Detailsicht StudentIn, Speichern 2023-09-28 08:45:54 +02:00
cgfhtw 9eeaeb2a14 Details Person 2023-09-27 09:16:42 +02:00
Cris 4e11e12c99 Removed aktiv column from SoftwareManagement Filter
Not used anymore.
2023-09-21 14:40:50 +02:00
Cris fa3a718ad4 Added getAutocompleteSuggestions method to OE Model
Get OEs by eventQuery string. Use with autocomplete event queries.
2023-09-21 14:40:05 +02:00
cgfhtw bd92777b96 improvements 2 2023-09-04 16:52:46 +02:00
cgfhtw 1009f73109 improvements 2023-08-31 08:26:16 +02:00
cgfhtw 13f71502e6 1st draft 2023-08-23 10:28:55 +02:00
cgfhtw 34c84d00da Merge branch 'feature-28886/Filter_Component_vs_Table_Component' into feature-30660/FHC4_StudierendenGUI_Prototyp 2023-08-22 13:31:50 +02:00
Cris e1c23fc6fa Added Filter ImageVerwaltung 2023-08-10 11:34:54 +02:00
Cris b7a3d2dcb4 Removed column 'actions' from filtersupdate 2023-08-09 10:57:06 +02:00
Cris 49e4aa78e9 Merge branch 'feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software' of https://github.com/FH-Complete/FHC-Core into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2023-08-09 10:43:57 +02:00
KarpAlex 4a2cdaf52a added primevue autocomplete 2023-08-04 14:46:53 +02:00
Cris 56230e3752 Changed button-color of Tabulators Header-'ADD Button' to primary color 2023-08-03 09:45:45 +02:00
Cris 4e17be39f6 Added column 'actions' to filtersupdate 2023-08-03 09:44:28 +02:00
KarpAlex 2f001987f3 Filter.js additional columns: additional columns are displayed based on field name, not title 2023-08-02 19:14:58 +02:00
KarpAlex 553f2feaa4 filter component: enabled nested tabulator 2023-08-02 16:22:10 +02:00
Cris b70011436e Added column 'softwarestatus_kurzbz' to filtersupdate 2023-08-02 13:39:47 +02:00
Cris 44182af5fa Formatted Tabulator Header: Abstaende vergroessert
Abstand Titel zu Actionbuttons und zwischen Actionbuttons untereinander vergroessert
2023-07-31 09:30:45 +02:00
cgfhtw 7dee77a6af Code Quality 2023-07-27 11:42:03 +02:00
cgfhtw ace3bd6736 Verbesserungen 2023-07-27 10:57:53 +02:00
cgfhtw cfe7c5b0da Merge branch 'feature-27351/Digitalisierung_Formulare_Neu' into feature-25999/C4 2023-07-25 14:07:17 +02:00
cgfhtw 764628d5fb Merge branch 'feature-27351/Digitalisierung_Formulare_Neu' into feature-25999/C4 2023-07-25 10:40:38 +02:00
cgfhtw 2046b6c2a8 Menu Entry: Studierendenantrag 2023-07-25 10:38:48 +02:00
cgfhtw 8901791911 Merge branch 'feature-27351/Digitalisierung_Formulare_Neu' into feature-25999/C4 2023-07-19 14:37:59 +02:00
cgfhtw ffd12e8ddf Access Rights 2023-07-19 11:17:17 +02:00
cgfhtw 044695183f Merge branch 'feature-24647/Konfigurierbare_Dashboards' into feature-25999/C4 2023-07-19 11:15:40 +02:00
cgfhtw 0beabe0f4a spaces to tabs 2023-07-19 11:11:52 +02:00
cgfhtw 0fd53dc3ac spaces to tabs 2023-07-19 11:10:01 +02:00
cgfhtw 72169b26c3 separate class attribute and property for easier readability 2023-07-19 11:06:01 +02:00
cgfhtw 7b96f99929 Access Rights Api Controller 2023-07-19 10:59:39 +02:00
cgfhtw 72d0517701 Merge branch 'master' into feature-25999/C4 2023-07-19 10:55:35 +02:00
Cris 1aae75312e Merge remote-tracking branch 'origin/feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2023-07-19 10:30:31 +02:00
KarpAlex d88ff104a3 filter component: added property tabulatorAdditionalColumns for displaying additional columns not in filter 2023-07-18 19:11:10 +02:00
ma0068 073cd6cb23 neue Tags für Anzeige Semester in Anrechnungen 2023-07-14 14:17:05 +02:00
cgfhtw dc21662fc9 Add missing SQL Rights for web 2023-07-14 13:01:01 +02:00
cgfhtw b0c9231d14 Hmvc: Safer Code 2023-07-14 09:02:25 +02:00
cgfhtw c5db083a84 Correct paths 2023-07-12 15:32:52 +02:00
cgfhtw 5f3e393ed1 Default menu: correct paths 2023-07-12 09:12:03 +02:00
KarpAlex 1416e91af7 Issues: Behebung parameter are included in identification of an issue 2023-07-11 15:58:48 +02:00
ma0048 533291bf33 - bug fix
- neue sortierung
- neue spalte
- sqls abfragen angepasst
2023-07-11 14:17:51 +02:00
Cris 0d690b60b6 Merge remote-tracking branch 'origin/feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2023-07-10 11:28:31 +02:00
cgfhtw 3e4703408b directories from variables 2023-07-10 08:42:48 +02:00
KarpAlex 539efcb6ec added Modal.js to Bootstrap components 2023-07-06 12:03:38 +02:00
KarpAlex ddf72af139 Merge branch 'feature-28886/Filter_Component_vs_Table_Component' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2023-07-04 14:43:28 +02:00
Cris 06b929381d Merge remote-tracking branch 'origin/feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software
# Conflicts:
#	system/filtersupdate.php
2023-07-04 13:48:21 +02:00
KarpAlex fc147f577a filter.js: fix for nested tabulator: set columns before set data, filtersupdate: renamed columns 2023-07-04 12:17:15 +02:00
KarpAlex 388400338e Merge branch 'feature-28886/Filter_Component_vs_Table_Component' into feature-28575/Softwarebereitstellung_GUI_zur_Verwaltung_von_Software 2023-07-04 12:16:06 +02:00
KarpAlex 71e86cfcde filter.js bugfixes: saving customfilter, and set columns before data (necessary e.g. for nested tabulator) 2023-07-03 11:45:15 +02:00
Cris 7356b17688 Added SW-ID column to SW-Table 2023-07-03 09:37:32 +02:00
KarpAlex f0d0c0837a added Filter for Software Management 2023-06-17 20:51:33 +02:00
ma0048 e26ba1d219 - spalte gesamtstunden erteilt hinzugefuegt 2023-06-12 09:22:32 +02:00
ma0048 afebd44b78 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core into feature-15490/lehrauftragsliste_stammkostenstelle_bei_fix_angestellten 2023-06-01 10:21:26 +02:00
cgfhtw d54868070f 29006: Dashboard verbesserungen 2023-05-08 12:39:25 +02:00
cgfhtw 2780ec5636 Dashboard Admin Demo 2023-05-05 14:27:33 +02:00
cgfhtw 4f43b79ed5 default controller 2023-04-14 12:50:07 +02:00
ma0068 f1402c439c Adaptierungen Rahmenvertrag FHG 2023-04-12 08:15:55 +02:00
cgfhtw 95458c193c CIS4 Entry & View titles 2023-03-31 14:50:56 +02:00
cgfhtw 2a59fad2fc CMS loading speedup 2023-03-31 09:21:52 +02:00
cgfhtw e2cf663f88 Default Menu 2023-03-31 09:21:09 +02:00
cgfhtw 7e518c3978 Documents 2023-03-24 11:26:16 +01:00
Paolo 06179ee714 Code quality check fixes 2023-03-23 14:38:42 +01:00
Andreas Österreicher 9d8adaba26 Ermittlung des Projektbetreuer Stundensatz an Config angepasst 2023-03-14 13:05:10 +01:00
Andreas Österreicher 1165f4407e Merge branch 'master' into feature-17727/FasDefaultStundensatzProjektbetreuungAnzeigen 2023-03-14 12:53:08 +01:00
cgfhtw 9e11dfb668 code quality 2023-03-14 11:00:36 +01:00
cgfhtw 6b6392deb4 Missing ; 2023-03-13 09:02:46 +01:00
cgfhtw 2238b872c6 Documents Self Service 2023-03-13 09:01:45 +01:00
ma0068 7a554b0d0c Adaptierung Berechnung ECTS 2023-03-10 12:49:34 +01:00
cgfhtw 83c0413815 code quality 2023-03-10 10:29:54 +01:00
cgfhtw 91e43bbc07 Documents first draft 2023-03-10 09:28:57 +01:00
cgfhtw f9975eb530 Code Quality 2023-03-10 09:28:04 +01:00
ma0068 345cc6cf83 Adaptierung Attribut studPlan 2023-03-09 08:19:05 +01:00
ma0068 eee4faa241 Adaptierungen Matr_nr als zusätzliches Feld, LVS statt ALVS, Herausfiltern von nicht studienplanrelevanten LVs 2023-03-07 17:47:40 +01:00
ma0068 83896113d8 Anpassungen rdf diplomasupplement 2023-03-06 15:02:44 +01:00
cgfhtw 555b8f4e6b access rights 2023-02-24 11:59:27 +01:00
cgfhtw 280890a00d Stundenplan Widget 2023-02-24 11:57:54 +01:00
cgfhtw 3d1908982a Merge branch 'feature-24647/Konfigurierbare_Dashboards' into feature-25999/C4 2023-02-09 16:12:36 +01:00
cgfhtw 9f72206796 Stundenplan Widget Basic 2023-02-06 11:44:36 +01:00
cgfhtw 13b898179e Widget classes 2023-02-06 09:46:32 +01:00
cgfhtw 7e2d63e3fe Css cleanup 2023-02-06 08:53:32 +01:00
cgfhtw 0f60ab2a54 Stundenplan & Calendar 2023-02-06 08:43:43 +01:00
cgfhtw d1f69d4696 MyLV Verbesserungen & cleanup 2023-02-06 08:42:42 +01:00
cgfhtw 034bed6580 cleanup 2023-01-16 11:40:40 +01:00
cgfhtw 2e126692f2 MyLv: Permissions & notFound fallback 2023-01-16 11:38:24 +01:00
cgfhtw 559e4d2bc0 cleanup 2023-01-16 11:22:53 +01:00
cgfhtw 2f2f19306b MyLv 2023-01-16 10:32:24 +01:00
cgfhtw ebc7b5a3d9 Login/Logout 2023-01-16 10:31:02 +01:00
cgfhtw c5b996f35e use vue for cms for link correction 2022-12-16 13:41:16 +01:00
cgfhtw 00c52e4880 cleanup 2022-12-16 11:43:35 +01:00
cgfhtw 4335c2da80 add Dashboard to HMVC 2022-12-16 11:36:33 +01:00
cgfhtw 085ed750ca using cis.php and routing news 2022-12-16 11:34:39 +01:00
cgfhtw c56b774d1d 3 Versions 2022-12-15 09:42:28 +01:00
cgfhtw 266ba7523f s&d 2022-11-29 08:48:50 +01:00
cgfhtw 546e55ed96 Merge branch 'feature-24647/Konfigurierbare_Dashboards' into feature-25999/C4 2022-11-24 15:36:38 +01:00
cgfhtw 4120f5a566 Merge remote-tracking branch 'origin/feature-24647/Konfigurierbare_Dashboards' into feature-24647/Konfigurierbare_Dashboards 2022-11-24 11:53:06 +01:00
cgfhtw 4758fcb413 access rights 2022-11-24 11:52:09 +01:00
cgfhtw 3e0aa849d4 bugfixes & "+" background 2022-11-24 11:52:01 +01:00
Harald Bamberger 3e17892831 fixed path to news placeholder image 2022-11-24 11:50:09 +01:00
cgfhtw d51a95a8a0 test controller & views 2022-11-24 11:48:46 +01:00
cgfhtw d7c2362a0e double widgets bug 2022-11-22 14:39:33 +01:00
ma0048 75f8c4e909 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core into feature-15490/lehrauftragsliste_stammkostenstelle_bei_fix_angestellten 2022-11-15 15:09:29 +01:00
cgfhtw a5749a5ea2 bug: wrong check for empty fields when adding new widgets (coordinates are based on 0,0 not 1,1) 2022-11-08 14:47:44 +01:00
cgfhtw 0e7343acfb bug: uncaught promise on widget-picker abort 2022-11-08 14:46:44 +01:00
ma0048 c3ff32a9d6 - unterschiedliche farbmarkierungen hinzugefuegt 2022-11-07 11:16:27 +01:00
ma0048 592fd7ac10 Merge remote-tracking branch 'origin/master' into feature-15490/lehrauftragsliste_stammkostenstelle_bei_fix_angestellten 2022-11-04 10:49:27 +01:00
cgfhtw 0d65ae5b85 widget icons absolute path 2022-11-03 11:37:13 +01:00
cgfhtw 55959ccd41 modal size 2022-11-03 11:33:52 +01:00
cgfhtw 935881dce2 icon & cursor 2022-11-03 11:28:25 +01:00
cgfhtw 3764df6102 Add widget to preset bugfix 2022-11-03 11:24:29 +01:00
Harald Bamberger e1addbfe04 Merge branch 'master' into feature-24647/Konfigurierbare_Dashboards_api
- mv dbchanges from system/dbupdate_3.3.php to system/dbupdate_3.4.php
- mv dbchanges include file from system/dashboard/ to system/dbupdate_3.4/ and prevent direct script access
2022-11-03 10:41:56 +01:00
Harald Bamberger 677f74781b Merge branch 'feature-24647/Konfigurierbare_Dashboards_widgets' into feature-24647/Konfigurierbare_Dashboards_api 2022-11-03 10:31:36 +01:00
Harald Bamberger c78c731388 renamed Dashboard Controller to DashboardDemo and used view to dashboard_demo 2022-11-03 10:27:39 +01:00
ma0068 d7897d7129 Merge branch 'master' into feature-17727/FasDefaultStundensatzProjektbetreuungAnzeigen 2022-11-02 16:18:23 +01:00
cgfhtw 8fd61edaab Admin Components 2022-10-28 12:41:25 +02:00
cgfhtw 92ec7f44ef Update Dashboard Endpoints for Admin GUI 2022-10-28 12:40:57 +02:00
cgfhtw be6ad8ce2a cleanup 2022-10-28 12:39:19 +02:00
Cris 630c1bc2bc Changed to display 4 Ampeln in Widget 2022-10-25 14:35:38 +02:00
Cris a1ccd392f5 Added News Widget 2022-10-25 14:28:25 +02:00
Cris bc723b22f4 Added getAll() to News Model 2022-10-25 14:28:14 +02:00
Cris 71699f6e74 Added Ampel Widget 2022-10-25 14:17:52 +02:00
Cris 1d6c5b4257 Added Url Widget 2022-10-25 14:17:32 +02:00
Cris 7f1cc966f0 Added API Controller to perform API calls 2022-10-25 13:00:43 +02:00
Cris aaf64a759b Added Widgets to Widget Controller 2022-10-25 12:59:03 +02:00
Cris ae05b34cbf Removed test function 2022-10-25 12:58:14 +02:00
Cris fdc52ae47d Added Offcanvas Component 2022-10-25 12:57:27 +02:00
Cris c5d3f47457 Merged Modal Component, adapted body padding there 2022-10-25 12:55:49 +02:00
Cris 699b76f4cb Added general used methods and computed property to Abstract Mixin Component
. apiurl: returns app root and ci router from FHC_JS_DATA_OBJECT
. formatDateTime: returns human readable date time
. getDate: returns human readable date
2022-10-25 12:54:35 +02:00
cgfhtw 1043714767 adminMode in Sections 2022-10-25 09:51:20 +02:00
cgfhtw a65d297997 use FHC_JS_DATA_STORAGE_OBJECT for apiurl 2022-10-24 16:01:02 +02:00
cgfhtw a3722273e9 use Bootstrap modals 2022-10-24 15:44:12 +02:00
cgfhtw 4aa7b9854a setConfig is an emit not a prop 2022-10-24 15:08:10 +02:00
Cris b6308d1ff5 Merge remote-tracking branch 'origin/feature-24647/Konfigurierbare_Dashboards_api' into feature-24647/Konfigurierbare_Dashboards_widgets 2022-10-24 11:04:31 +02:00
cgfhtw 8983a0e821 Bootstrap Modal (+ Alert,Confirm,Prompt) 2022-10-24 11:01:27 +02:00
Cris 67f1094a97 Added Modal Component 2022-10-17 13:40:18 +02:00
Cris 065dd1d081 Added FHTW illustration image 2022-10-17 13:38:07 +02:00
Cris ecbc6d8e3d Added Dashboard Controller & View 2022-10-17 13:37:08 +02:00
Cris 0bd6af8da1 Merge remote-tracking branch 'origin/feature-24647/Konfigurierbare_Dashboards_api' into feature-24647/Konfigurierbare_Dashboards_widgets 2022-10-13 15:14:29 +02:00
cgfhtw 680787d881 Don't move out of bounds on Drag&Drop 2022-10-13 14:44:33 +02:00
cgfhtw a71ead0a85 Ajax update: better data consistency 2022-10-13 14:38:03 +02:00
cgfhtw fd2aa8a1bb Cleanup & uid from AuthLib 2022-10-13 08:43:08 +02:00
cgfhtw 6570c958b3 Bug: DataTransfer in Chrome 2022-10-12 15:50:40 +02:00
Cris b4053c45fd Merge remote-tracking branch 'origin/feature-24647/Konfigurierbare_Dashboards_api' into feature-24647/Konfigurierbare_Dashboards_widgets 2022-10-12 15:17:47 +02:00
cgfhtw dd4d71bd7d Bug: Deepmerge on update 2022-10-12 10:29:52 +02:00
Cris c7c8913833 Adapted Dashboard DB Update: Berechtigungen ergänzt / Typspezifikation entfernt.
. Berechtigungen ergänzt:
  - dashboard/benutzer
  - dashboard/admin

. Typspezifikation entfernt in Create Sequence
  - war nicht mit PHPSQL 9.6.2 kompatibel.
2022-10-12 09:19:54 +02:00
cgfhtw a468338ead Configurable CSS classes to Default Widget 2022-10-12 09:08:24 +02:00
cgfhtw 39bbcac217 Widget controller & model & table 2022-10-12 08:58:48 +02:00
cgfhtw a3ad8eb337 dashboard.tbl_widget new fields 2022-10-11 15:41:43 +02:00
cgfhtw 4f3e8dcb3c Basic VUE Components & Test WidgetController 2022-10-05 10:43:43 +02:00
Harald Bamberger 90e006feb5 allow widgets array for add operations 2022-10-04 08:22:27 +02:00
Harald Bamberger d14608ed28 level funktion_kurzbz added to presets and overrides 2022-10-03 07:59:11 +02:00
Harald Bamberger ad369bbe44 add dashboard schema and tables create script 2022-09-28 16:53:48 +02:00
Harald Bamberger 252abeafcb dummy config changed to test function level in config 2022-09-28 15:26:45 +02:00
Harald Bamberger fb7f445e22 progress on api endpoints to add and remove presets and overrides 2022-09-21 11:38:16 +02:00
Harald Bamberger 5c9c4b7e2d store configs as json in database and merge them 2022-09-16 10:46:29 +02:00
Harald Bamberger ff93c957cd dashboard config api first steps 2022-09-14 19:05:29 +02:00
Cris 7daa289bb1 Merge branch 'master' into feature-18073/No-Reply-for-Sanchomails 2022-05-10 10:57:50 +02:00
Cris c39174980c Fixed function _getSTGLMailAddress to return same array structure
Different structure was causing errors in handling.
2022-05-09 15:34:22 +02:00
Cris efcef48f89 Changed Sanchomail 'From' to noreply 2022-05-09 11:14:01 +02:00
ma0068 d2e0f34d9e Reset Defaulstundensatz bei Neuanlage Projektbetreuer 2022-05-07 12:02:51 +02:00
ma0068 bdee476a74 Adaptierungen Stundensatz: Aktualisierung Anzeige Defaultstundensatz, Zuordnung externe Betreuer 2022-05-02 11:53:14 +02:00
ma0068 9dbf59d1a1 Adaptierungen Codesniffer 2022-04-26 12:27:58 +02:00
ma0068 a4378b4592 Add Default Stundensatz 2022-04-26 09:48:22 +02:00
ma0048 4101929cd5 stammkostenstelle anzeigen bei fixangestellten / fallback falls keine eingetragen ist 2021-10-15 12:57:18 +02:00
638 changed files with 73787 additions and 9254 deletions
+2
View File
@@ -2,6 +2,8 @@ documents/
vendor/
/nbproject/
.vscode
composer.phar
/.idea/
.settings
.project
+13 -1
View File
@@ -1,6 +1,6 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
if (!defined('BASEPATH')) exit('No direct script access allowed');
// Deadline for Application given as Time-Interval after Semesterstart.
@@ -21,3 +21,15 @@ $config['grades_blocking_application'] = array(
$config['fbl'] = FALSE;
//Enables Info Mails
$config['send_mail'] = TRUE;
// Display fields to explain equivalence of ECTS and LV-Inhalte
$config['explain_equivalence'] = TRUE;
// Displays infobox if set to true
$config['display_infobox'] = [
'fristen' => TRUE,
'referenzbeispiele_ects' => TRUE,
'voraussetzungen' => TRUE,
'nachweisdokumente' => TRUE,
'herkunft_kenntnisse' => TRUE
];
+9
View File
@@ -0,0 +1,9 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// CMS Content Id for CIS4 Menu Root
$config['cis_menu_root_content_id'] = 11066;
// send Mails for ProfilUpdate
$config['cis_send_profil_update_mails'] = true;
+7
View File
@@ -0,0 +1,7 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// use vuejs dev version
$config['use_vuejs_dev_version'] = false;
// use bundled javascript
$config['use_bundled_javascript'] = false;
+15
View File
@@ -32,3 +32,18 @@ $config['validate'] = false; // If true then the email address will be validated
// If enabled will be logged info about emails in Codeigniter error logs
$config['enable_debug'] = false;
// default sender
$config['sancho_mail_default_sender'] = defined('SANCHO_MAIL_DEFAULT_SENDER') ? SANCHO_MAIL_DEFAULT_SENDER : '';
// If to use images for custom mails
$config['sancho_mail_use_images'] = defined('SANCHO_MAIL_USE_IMAGES') ? SANCHO_MAIL_USE_IMAGES : false;
// image path for sancho mail, relativ to document root
$config['sancho_mail_img_path'] = defined('SANCHO_MAIL_IMG_PATH') ? SANCHO_MAIL_IMG_PATH : '';
// header image for custom mails
$config['sancho_mail_header_img'] = defined('SANCHO_MAIL_HEADER_IMG') ? SANCHO_MAIL_HEADER_IMG : '';
// footer image for custom mails
$config['sancho_mail_footer_img'] = defined('SANCHO_MAIL_FOOTER_IMG') ? SANCHO_MAIL_FOOTER_IMG : '';
+36
View File
@@ -0,0 +1,36 @@
<?php
/**
* Copyright (C) 2023 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
$config['migratecontract_oe_default'] = 'TODO_OE_DEFAULT';
$config['migratecontract_matching_ba1_vertragsart'] = array(
'101'=>'dvbund',
'102'=>'dvanderengk',
'103'=>'echterdv',
'104'=>'studentischehilfskr',
'105'=>'externerlehrender',
'106'=>'dvanderenbet',
'107'=>'werkvertrag',
'108'=>'studentischehilfskr',
'109'=>'ueberlassungsvertrag',
'110'=>'echterfreier',
'111'=>'echterdv' //All-In
);
+24 -4
View File
@@ -1,6 +1,12 @@
<?php
// Header menu
if(defined('CIS4') && CIS4) {
$root = APP_ROOT;
} else {
$root = CIS_ROOT;
}
$config['navigation_header'] = array(
'*' => array(
'fhcomplete' => array(
@@ -50,11 +56,17 @@ $config['navigation_header'] = array(
'requiredPermissions' => 'basis/vilesci:r',
'children' => array(
'cis' => array(
'link' => CIS_ROOT,
'link' => $root,
'icon' => '',
'description' => 'CIS',
'sort' => 10
),
'lehrveranstaltungen' => array(
'link' => site_url('lehre/lvplanung/LvTemplateUebersicht'),
'icon' => '',
'description' => 'Lehrveranstaltungen',
'sort' => 15
),
'reihungstest' => array(
'link' => site_url('organisation/Reihungstest'),
'description' => 'Reihungstests',
@@ -217,7 +229,7 @@ $config['navigation_menu']['organisation/Reihungstest/index'] = array(
'target' => '_blank'
),
'auswertung' => array(
'link' => CIS_ROOT.'/cis/testtool/admin/auswertung.php',
'link' => $root.'/cis/testtool/admin/auswertung.php',
'description' => 'Auswertung',
'icon' => 'list-alt',
'sort' => 1,
@@ -287,6 +299,15 @@ $config['navigation_menu']['lehre/lehrauftrag/LehrauftragErteilen/*'] = array(
)
);
$config['navigation_menu']['lehre/lvplanung/LvTemplateUebersicht/index'] = array(
'lvTemplateUebersicht' => array(
'link' => site_url('lehre/lvplanung/LvTemplateUebersicht'),
'description' => 'LV Template Übersicht',
'icon' => '',
'sort' => 1
)
);
$config['navigation_menu']['system/issues/Issues/*'] = array(
'fehlerzustaendigkeiten' => array(
'link' => site_url('system/issues/IssuesZustaendigkeiten'),
@@ -304,5 +325,4 @@ $config['navigation_menu']['system/issues/Issues/*'] = array(
'target' => '_blank',
'requiredPermissions' => array('admin:rw')
),
);
);
+5 -3
View File
@@ -50,7 +50,7 @@ defined('BASEPATH') OR exit('No direct script access allowed');
| Examples: my-controller/index -> my_controller/index
| my-controller/my-method -> my_controller/my_method
*/
$route['default_controller'] = 'Vilesci';
$route['default_controller'] = defined('CIS4') && CIS4 ? 'Cis4' : 'Vilesci';
$route['translate_uri_dashes'] = FALSE;
// Class name conflicts
@@ -61,6 +61,9 @@ $route['api/v1/organisation/[O|o]rganisationseinheit/(:any)'] = 'api/v1/organisa
$route['api/v1/ressource/[B|b]etriebsmittelperson/(:any)'] = 'api/v1/ressource/betriebsmittelperson2/$1';
$route['api/v1/system/[S|s]prache/(:any)'] = 'api/v1/system/sprache2/$1';
$route['CisVue'] = 'CisVue/dashboard';
$route['Cis/Stundenplan/(:any)'] = 'Cis/Stundenplan';
// load routes from extensions
$subdir = 'application/config/extensions';
$dirlist = scandir($subdir);
@@ -81,5 +84,4 @@ if ($dirlist)
}
}
}
}
}
+77
View File
@@ -0,0 +1,77 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Auth extends FHC_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct();
// Load Helpers
$this->load->helper('form');
$this->load->helper('hlp_authentication');
// Loads phrases system
$this->loadPhrases([
'global'
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function login()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|trim|callback_validation');
$this->form_validation->set_rules('password', 'Password', 'required|trim');
if ($this->form_validation->run())
{
redirect($this->authlib->getLandingPage('/CisVue/Dashboard'));
}
else
{
$this->load->view('Cis/Login');
}
}
/**
* @return boolean
*/
public function validation()
{
$username = $this->input->post('username');
$password = $this->input->post('password');
$this->load->library('AuthLib', [false]); // without authentication otherwise loooooop!
$login = $this->authlib->loginLDAP($username, $password);
if (isSuccess($login))
return true;
$this->form_validation->set_message('validation', 'Incorrect username/password.');
return false;
}
/**
* @return void
*/
public function logout()
{
$this->load->library('AuthLib');
$this->authlib->logout();
redirect('/Cis/Auth/login', 'refresh');
}
}
+192
View File
@@ -0,0 +1,192 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \stdClass as stdClass;
/**
*
*/
class Documents extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => [self::PERM_LOGGED],
'student' => ['admin:r'],
'download' => [self::PERM_LOGGED]
]);
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->loadPhrases([
'global',
'tools'
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
return $this->showDocuments(getAuthUID());
}
/**
* @param string $uid Administratoren dürfen die UID als Parameter übergeben um die Dokumente von anderen Personen anzuzeigen
* @return void
*/
public function student($uid)
{
return $this->showDocuments($uid);
}
/**
* @param string $uid
* @return void
*/
protected function showDocuments($uid)
{
$this->load->model('crm/Konto_model', 'KontoModel');
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$stati = $this->PrestudentstatusModel->loadWhereUid($uid, null, true);
if (isError($stati))
return $this->load->view('errors/html/error_db.php', [
'heading' => 'Database Error',
'message' => getError($stati)
]);
$stati = getData($stati);
if (!$stati)
return $this->load->view('errors/html/error_general.php', [
'heading' => 'User ist kein Student',
'message' => 'Es konnten keine Studiensemester gefunden werden in denen der User als Student inskripiert ist'
]);
$stgs = [];
$stsemArray = [];
$buchungstypen = implode('\',\'', defined("CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN") ? unserialize(CIS_DOKUMENTE_STUDIENBEITRAG_TYPEN) : []);
$person_ids = [];
foreach ($stati as $status) {
$person_ids[] = $status->person_id;
if(!in_array($status->studiensemester_kurzbz, $stsemArray)) {
$stsemArray[] = $status->studiensemester_kurzbz;
}
if (!isset($stgs[$status->studiengang_kz])) {
$stg = $this->StudiengangModel->load($status->studiengang_kz);
if (isError($stg))
return $this->load->view('errors/html/error_db.php', [
'heading' => 'Database Error',
'message' => getError($stg)
]);
$stg = getData($stg);
if (!$stg)
return $this->load->view('errors/html/error_db.php', [
'heading' => 'Database Error',
'message' => 'No Studiengang found for studiengang_kz ' . $status->studiengang_kz
]);
$stgs[$status->studiengang_kz] = current($stg);
$stgs[$status->studiengang_kz]->studiensemester = [];
}
if (!isset($stgs[$status->studiengang_kz]->studiensemester[$status->studiensemester_kurzbz])) {
$stgs[$status->studiengang_kz]->studiensemester[$status->studiensemester_kurzbz] = new stdClass();
$stgs[$status->studiengang_kz]->studiensemester[$status->studiensemester_kurzbz]->inskriptionsbestaetigung = (boolean)getData(
$this->KontoModel->checkStudienbeitragFromPrestudent(
$status->prestudent_id,
$status->studiensemester_kurzbz,
$buchungstypen
)
);
}
}
$person_ids = array_unique($person_ids);
$selfservice = null;
if (!defined('CIS_DOKUMENTE_SELFSERVICE') || CIS_DOKUMENTE_SELFSERVICE) {
$this->load->model('crm/Akte_model', 'AkteModel');
$selfservice = [];
foreach ($person_ids as $person_id) {
$result = $this->AkteModel->getArchiv($person_id, null, true);
if (isError($result))
return $this->load->view('errors/html/error_db.php', [
'heading' => 'Database Error',
'message' => getError($result)
]);
$selfservice = array_merge($selfservice, getData($result) ?: []);
}
}
$this->load->view('Cis/Documents', [
'stsemArray' => $stsemArray,
'stgs' => $stgs,
'uid' => $uid,
'studienbuchblatt' => defined('CIS_DOKUMENTE_STUDIENBUCHLBATT_DRUCKEN') && CIS_DOKUMENTE_STUDIENBUCHLBATT_DRUCKEN,
'studienerfolgsbestaetigung' => defined('CIS_DOKUMENTE_STUDIENERFOLGSBESTAETIGUNG_DRUCKEN') && CIS_DOKUMENTE_STUDIENERFOLGSBESTAETIGUNG_DRUCKEN,
'selfservice' => $selfservice
]);
}
/**
* @param integer $akte_id
* @param string $uid (optional) Administratoren dürfen die UID als Parameter übergeben um die Dokumente von anderen Personen anzuzeigen
*
* @return void
*/
public function download($akte_id, $uid = null)
{
if (!is_numeric($akte_id))
return show_404();
$this->load->model('crm/Akte_model', 'AkteModel');
$result = $this->AkteModel->load($akte_id);
if (isError($result))
return show_error(getError($result));
$akte = getData($result);
if (!$akte)
return show_404();
$akte = current($akte);
$admin_access = false;
if ($uid !== null && $this->permissionlib->isBerechtigt('admin')) {
$stati = $this->PrestudentstatusModel->loadWhereUid($uid, null, true);
if (hasData($stati)) {
$person_ids = array_map(function ($status) {
return $status->person_id;
}, getData($stati));
$person_ids = array_unique($person_ids);
if (count($person_ids) == 1 && current($person_ids) == $akte->person_id) {
$admin_access = true;
}
}
}
if (!$admin_access && ($akte->person_id != getAuthPersonId() || !$akte->stud_selfservice))
return show_error('Forbidden', 403);
// NOTE(chris): Log bei einem Download vom Becheid
if (isset($akte->dokument_kurzbz) && ($akte->dokument_kurzbz === 'Bescheid' || $akte->dokument_kurzbz === 'BescheidEng')) {
$this->load->model('system/Webservicelog_model', 'WebservicelogModel');
$this->WebservicelogModel->insert([
'webservicetyp_kurzbz' => 'content',
'request_id' => (isset($akte->akte_id) && !empty($akte->akte_id)) ? $akte->akte_id : null,
'beschreibung' => 'Bescheidbestaetigungsdownload',
'request_data' => $_SERVER['QUERY_STRING'],
'execute_time' => date('c'),
'execute_user' => getAuthUID()
]);
}
$this->output->set_content_type($akte->mimetype);
$this->output->set_output(base64_decode($akte->inhalt));
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class MyLv extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r'],
'Info' => [self::PERM_LOGGED]
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$this->load->view('Cis/MyLv');
}
public function Info($studien_semester,$lvid)
{
$this->load->view('Cis/LvInfo',['lvid'=> $lvid, 'studien_semester' => $studien_semester]);
}
}
+737
View File
@@ -0,0 +1,737 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
class Profil extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis:r'],
'foto_sperre_function' => ['basis/cis:r'],
'getView' => ['basis/cis:r'],
'View' => ['basis/cis:r'],
'isMitarbeiter' => ['basis/cis:r'],
'isStudent' => ['basis/cis:r'],
'getZustellAdresse' => ['basis/cis:r'],
'getZustellKontakt' => ['basis/cis:r'],
'getAllNationen' => ['basis/cis:r'],
'getGemeinden' => ['basis/cis:r'],
]);
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('content/DmsVersion_model', 'DmsVersionModel');
//? put the uid and pid inside the controller for reusability
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* index loads the Profil view
* @access public
* @return void
*/
public function index()
{
$this->load->view('Cis/Profil');
}
/**
* redirects to the index function (needed to allow calling this URI)
* @access public
* @return void
*/
public function View($uid)
{
$this->load->view('Cis/Profil');
}
/**
* checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php)
* @access public
* @param $uid the userID used to check if it is a mitarbeiter
* @return boolean
*/
public function isStudent($uid)
{
$result = $this->StudentModel->isStudent($uid);
if (isError($result)) {
show_error("error when calling Student_model function isStudent with uid " . $uid);
}
$result = getData($result);
echo json_encode($result);
}
/**
* checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php)
* @access public
* @param $uid the userID used to check if it is a mitarbeiter
* @return boolean
*/
public function isMitarbeiter($uid)
{
$result = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($result)) {
show_error("error when calling Mitarbeiter_model function isMitarbeiter with uid " . $uid);
}
$result = getData($result);
echo json_encode($result);
}
/**
* gets the adressen that are marked as zustell from the currenlty logged in user
* @access public
* @return array a list of adresse_id's
*/
public function getZustellAdresse()
{
$this->AdresseModel->addSelect(["adresse_id"]);
$adressen_res = $this->AdresseModel->loadWhere(['person_id' => $this->pid, 'zustelladresse' => true]);
$adressen_res = hasData($adressen_res) ? getData($adressen_res) : null;
$adressen_res = array_map(function ($item) {
return $item->adresse_id;
}, $adressen_res);
echo json_encode($adressen_res);
}
/**
* gets the kontakte that are marked as zustell from the currenlty logged in user
* @access public
* @return array a list of kontakt_id's
*/
public function getZustellKontakt()
{
$this->KontaktModel->addSelect(["kontakt_id"]);
$kontakt_res = $this->KontaktModel->loadWhere(['person_id' => $this->pid, 'zustellung' => true]);
$kontakt_res = hasData($kontakt_res) ? getData($kontakt_res) : null;
$kontakt_res = array_map(function ($item) {
return $item->kontakt_id;
}, $kontakt_res);
echo json_encode($kontakt_res);
}
/**
* function that returns the data used for the corresponding view
* the client side parses the @param $uid and calls this function to get the data to the correct view
* @access public
* @param boolean $uid the userID used to identify which information should be retrieved for which view
* @return stdClass all the data corresponding to a view of a user
*/
public function getView($uid)
{
$res = new stdClass();
// if parsing the URL did not found a UID then the UID of the logged in user is used
if ($uid == "Profil" || $uid == $this->uid) {
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($this->uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $this->uid . " is a mitarbeiter");
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "MitarbeiterProfil";
$res->data = $this->mitarbeiterProfil();
$res->data->pid = $this->pid;
} else {
$res->view = "StudentProfil";
$res->data = $this->studentProfil();
$res->data->pid = $this->pid;
}
}
// UID is availabe when accessing Profil/View/:uid
else {
$this->PersonModel->addSelect(["person_id"]);
$pid = $this->PersonModel->getByUid($uid);
if (isError($pid)) {
show_error("error while trying to update table public.tbl_person while searching for a person with UID: " . $uid);
}
$pid = hasData($pid) ? getData($pid)[0] : null;
if (!$pid) {
show_error("Person with UID: " . $uid . " does not exist");
}
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $uid . " is a mitarbeiter");
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "ViewMitarbeiterProfil";
$res->data = $this->viewMitarbeiterProfil($uid);
} else {
$res->view = "ViewStudentProfil";
$res->data = $this->viewStudentProfil($uid);
}
}
echo json_encode($res);
}
/**
* update column foto_sperre in public.tbl_person
* @access public
* @param boolean $value new value for the column
* @return boolean the new value added to the column in public.tbl_person
*/
public function foto_sperre_function($value)
{
$res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]);
if (isError($res)) {
show_error("error while trying to update table public.tbl_person");
}
$this->PersonModel->addSelect("foto_sperre");
$res = $this->PersonModel->load($this->pid);
if (isError($res)) {
show_error("error while trying to query table public.tbl_person");
}
$res = hasData($res) ? getData($res)[0] : null;
echo json_encode($res);
}
/**
* gets all nations in the table bis.tbl_nation
*
* @access public
* @return array all the nations in table bis.tbl_nation
*/
public function getAllNationen()
{
$this->load->model('codex/Nation_model', "NationModel");
$this->NationModel->addSelect(["nation_code as code", "langtext"]);
$nation_res = $this->NationModel->load();
if (isError($nation_res)) {
show_error("error while trying to query table codex.tbl_nation");
}
$nation_res = hasData($nation_res) ? getData($nation_res) : null;
echo json_encode($nation_res);
}
/**
* gets specific gemeinden which are related to the ZIP and the Nation passed in the body of the get request
* @access public
* @var $_GET function uses GET request payload
* @return boolean the new value added to the column in public.tbl_person
*/
public function getGemeinden()
{
/** @var $nation value parsed out of the body of the get request */
$nation = $this->input->get('nation', true);
/** @var $zip value parsed out of the body of the get request and converted to a php integer with json_decode */
$zip = json_decode($this->input->get('zip', true));
$this->load->model('codex/Gemeinde_model', "GemeindeModel");
$this->GemeindeModel->addDistinct();
$this->GemeindeModel->addSelect(["name"]);
if ($nation == "A") {
if (isset($zip) && $zip > 999 && $zip < 32000) {
$gemeinde_res = $this->GemeindeModel->loadWhere(['plz' => $zip]);
if (isError($gemeinde_res)) {
show_error("error while trying to query bis.tbl_gemeinde");
}
$gemeinde_res = hasData($gemeinde_res) ? getData($gemeinde_res) : null;
$gemeinde_res = array_map(function ($obj) {
return $obj->name;
}, $gemeinde_res);
echo json_encode($gemeinde_res);
} else {
echo json_encode(error("ortschaftskennziffer code was not valid"));
}
} else {
echo json_encode(error("Nation was not 'A' (Austria)"));
}
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* function that returns the data used for viewing another mitarbeiter profile
* @access private
* @param integer $uid the userID to retrieve the mitarbeiter data
* @return stdClass restricted mitarbeiter data
*/
private function viewMitarbeiterProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$benutzer_funktion_res = $this->getBenutzerFunktion($uid);
$benutzer_res = $this->getBenutzerAlias($uid);
$person_res = $this->getPersonInfo($uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($uid);
$telefon_res = $this->getTelefonInfo($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Info
foreach ($person_res as $key => $val) {
$res->$key = $val;
}
//? Mitarbeiter Info
foreach ($mitarbeiter_res as $key => $val) {
$res->$key = $val;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $benutzer_res->alias . "@" . DOMAIN;
$res->emails = array($intern_email, $extern_email);
$res->funktionen = $benutzer_funktion_res;
$res->mailverteiler = $mailverteiler_res;
$res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null;
return $res;
}
/**
* function that returns the data used for viewing another student profile
* @access private
* @param integer $uid the userID to retrieve the student data
* @return stdClass restricted student data
*/
private function viewStudentProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$person_res = $this->getPersonInfo($uid);
$student_res = $this->getStudentInfo($uid);
$matr_res = $this->getMatrikelNummer($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = $value;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->matrikelnummer = $matr_res->matr_nr;
$res->mailverteiler = $mailverteiler_res;
return $res;
}
/**
* function that returns the data used for the mitarbeiter profile
* @access private
* @return stdClass mitarbeiter data
*/
private function mitarbeiterProfil()
{
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$benutzer_funktion_res = $this->getBenutzerFunktion($this->uid);
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$telefon_res = $this->getTelefonInfo($this->uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Mitarbeiter Information
foreach ($mitarbeiter_res as $key => $value) {
$res->$key = $value;
}
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->mailverteiler = $mailverteiler_res;
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $mitarbeiter_res->alias . "@" . DOMAIN;
$res->emails = [$intern_email, $extern_email];
$res->funktionen = $benutzer_funktion_res;
$res->standort_telefon = $telefon_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* function that returns the data used for the student profile
* @access private
* @return stdClass student data
*/
private function studentProfil()
{
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$zutrittsgruppe_res = $this->getZutrittsgruppen($this->uid);
$student_res = $this->getStudentInfo($this->uid);
$matr_res = $this->getMatrikelNummer($this->uid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = trim($value);
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->matrikelnummer = $matr_res->matr_nr;
$res->zuttritsgruppen = $zutrittsgruppe_res;
$res->mailverteiler = $mailverteiler_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe
* @access private
* @param integer $uid the userID used to retrieve the mailverteiler
* @return array returns the mailvertailer corresponding to a userID
*/
private function getMailverteiler($uid)
{
$this->PersonModel->addSelect('gruppe_kurzbz, beschreibung');
$this->PersonModel->addJoin('tbl_benutzer', 'person_id');
$this->PersonModel->addJoin('tbl_benutzergruppe', 'uid');
$this->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$mailverteiler_res = $this->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid));
if (isError($mailverteiler_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($mailverteiler_res));
}
$mailverteiler_res = hasData($mailverteiler_res) ? getData($mailverteiler_res) : null;
$mailverteiler_res = array_map(function ($element) {
$element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN;
return $element;
}, $mailverteiler_res);
return $mailverteiler_res;
}
/**
* gets all the Benutzerfunktionen of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Benutzerfunktionen
* @return array returns the Benutzerfunktionen corresponding to a userID
*/
private function getBenutzerFunktion($uid)
{
$this->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]);
$this->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz");
$benutzer_funktion_res = $this->BenutzerfunktionModel->loadWhere(array('uid' => $uid));
if (isError($benutzer_funktion_res)) {
show_error("was not able to query the table public.tbl_benutzerfunktion:" . getData($benutzer_funktion_res));
}
$benutzer_funktion_res = hasData($benutzer_funktion_res) ? getData($benutzer_funktion_res) : null;
return $benutzer_funktion_res;
}
/**
* gets all the Betriebsmittel of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Betriebsmittel
* @return array returns the Betriebsmittel corresponding to a userID
*/
private function getBetriebsmittelInfo($pid)
{
$this->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]);
//? betriebsmittel are not needed in a view
$betriebsmittelperson_res = $this->BetriebsmittelpersonModel->getBetriebsmittel($pid);
if (isError($betriebsmittelperson_res)) {
show_error("was not able to query the table public.tbl_betriebsmittelperson:" . getData($betriebsmittelperson_res));
}
$betriebsmittelperson_res = hasData($betriebsmittelperson_res) ? getData($betriebsmittelperson_res) : null;
return $betriebsmittelperson_res;
}
/**
* gets the alias of a corresponding user
* @access private
* @param integer $uid the userID used to get the alias
* @return string the alias of the userID
*/
private function getBenutzerAlias($uid)
{
$this->BenutzerModel->addSelect(["alias"]);
$benutzer_res = $this->BenutzerModel->load([$uid]);
if (isError($benutzer_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($benutzer_res));
} else {
$benutzer_res = hasData($benutzer_res) ? getData($benutzer_res)[0] : null;
}
return $benutzer_res;
}
/**
* gets the person information corresponding to a user
* @access private
* @param integer $uid the userID used to get the person information
* @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not
* @return array all the person informaion corresponding to a userID
*/
private function getPersonInfo($uid, $geburtsInfo = null)
{
$selectClause = ["foto", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"];
/** @param integer $geburtsInfo */
if ($geburtsInfo) {
array_push($selectClause, "gebort");
array_push($selectClause, "gebdatum");
array_push($selectClause, "foto_sperre");
}
$this->BenutzerModel->addSelect($selectClause);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$person_res = $this->BenutzerModel->load([$uid]);
if (isError($person_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($person_res));
} else {
$person_res = hasData($person_res) ? getData($person_res)[0] : null;
}
return $person_res;
}
/**
* gets the mitarbeiter information corresponding to a user
* @access private
* @param integer $uid the userID used to get the mitarbeiter information
* @return array all the mitarbeiter informaion corresponding to a userID
*/
private function getMitarbeiterInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]);
$this->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid");
$mitarbeiter_res = $this->MitarbeiterModel->load($uid);
if (isError($mitarbeiter_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($mitarbeiter_res));
} else {
$mitarbeiter_res = hasData($mitarbeiter_res) ? getData($mitarbeiter_res)[0] : null;
}
return $mitarbeiter_res;
}
/**
* gets the telefon information corresponding to a user
* @access private
* @param integer $uid the userID used to get the telefon information
* @return array all the telefon informaion corresponding to a userID
*/
private function getTelefonInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kontakt"]);
$this->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id");
$this->MitarbeiterModel->addLimit(1);
$telefon_res = $this->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]);
if (isError($telefon_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($telefon_res));
}
$telefon_res = hasData($telefon_res) ? getData($telefon_res)[0] : null;
return $telefon_res;
}
/**
* gets the student information corresponding to a user
* @access private
* @param integer $uid the userID used to get the student information
* @return array all the student informaion corresponding to a userID
*/
private function getStudentInfo($uid)
{
$this->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']);
$this->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz");
$student_res = $this->StudentModel->load([$uid]);
if (isError($student_res)) {
show_error("was not able to query the table public.tbl_student:" . getData($student_res));
}
$student_res = hasData($student_res) ? getData($student_res)[0] : null;
return $student_res;
}
/**
* gets the profil updates corresponding to a user
* @access private
* @param integer $uid the userID used to get the profil updates
* @return array all the profil updates corresponding to a userID
*/
private function getProfilUpdates($uid)
{
$profilUpdates = $this->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]);
if (isError($profilUpdates)) {
show_error("was not able to query the table public.tbl_profil_update:" . getData($profilUpdates));
}
$profilUpdates = hasData($profilUpdates) ? getData($profilUpdates) : null;
return $profilUpdates;
}
/**
* gets the Matrikelnummer corresponding to a user
* @access private
* @param integer $uid the userID used to get the Matrikelnummer
* @return integer the Matrikelnummer corresponding to a userID
*/
private function getMatrikelNummer($uid)
{
$this->BenutzerModel->addSelect(["matr_nr"]);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$matr_res = $this->BenutzerModel->load([$uid]);
if (isError($matr_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($matr_res));
}
$matr_res = hasData($matr_res) ? getData($matr_res)[0] : [];
return $matr_res;
}
/**
* gets the Zutrittsgruppen corresponding to a user
* @access private
* @param integer $uid the userID used to get the Zutrittsgruppen
* @return array all the Zutrittsgruppen corresponding to a userID
*/
private function getZutrittsgruppen($uid)
{
$this->BenutzergruppeModel->addSelect(['bezeichnung']);
$this->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$zutrittsgruppe_res = $this->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true));
if (isError($zutrittsgruppe_res)) {
show_error("was not able to query the table public.tbl_benutzergruppe:" . getData($zutrittsgruppe_res));
}
$zutrittsgruppe_res = hasData($zutrittsgruppe_res) ? getData($zutrittsgruppe_res) : null;
return $zutrittsgruppe_res;
}
/**
* gets the address information corresponding to a user
* @access private
* @param integer $uid the userID used to get the address information
* @return array all the address information corresponding to a userID
*/
private function getAdressenInfo($pid)
{
$adresse_res = $this->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]);
$adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC");
$adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz");
$adresse_res = $this->AdresseModel->loadWhere(["person_id" => $pid]);
if (isError($adresse_res)) {
show_error("was not able to query the table public.tbl_adresse:" . getData($adresse_res));
}
$adresse_res = hasData($adresse_res) ? getData($adresse_res) : null;
return $adresse_res;
}
/**
* gets the kontakt information corresponding to a user
* @access private
* @param integer $uid the userID used to get the kontakt information
* @return array all the kontakt information corresponding to a userID
*/
private function getKontaktInfo($pid)
{
$this->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']);
$this->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT');
$this->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT');
$this->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum');
$kontakte_res = $this->KontaktModel->loadWhere(['person_id' => $pid]);
if (isError($kontakte_res)) {
show_error("was not able to query the table public.tbl_kontakt:" . getData($kontakte_res));
}
$kontakte_res = hasData($kontakte_res) ? getData($kontakte_res) : null;
return $kontakte_res;
}
/**
* gets the date of issue of the FH access card corresponding to a user
* @access private
* @param integer $uid the userID used to get the date of issue of the FH access card
* @return string the date of issue of the FH access card corresponding to a userID
*/
private function getZutrittskarteDatum($uid)
{
$zutrittskarte_ausgegebenam = $this->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte");
if (isError($zutrittskarte_ausgegebenam)) {
show_error("was not able to query the table wavi.tbl_bentriebsmittelperson:" . getData($zutrittskarte_ausgegebenam));
}
$zutrittskarte_ausgegebenam = hasData($zutrittskarte_ausgegebenam) ? getData($zutrittskarte_ausgegebenam)[0]->ausgegebenam : null;
//? formats date from 01-01-2000 to 01.01.2000
$zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam);
return $zutrittskarte_ausgegebenam;
}
}
@@ -0,0 +1,814 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
/**
*
*/
class ProfilUpdate extends Auth_Controller
{
public static $STATUS_PENDING = NULL;
public static $STATUS_ACCEPTED = NULL;
public static $STATUS_REJECTED = NULL;
public static $TOPICS = [];
public function __construct()
{
parent::__construct([
'index' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'id' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'getProfilUpdateWithPermission' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'acceptProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'denyProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'show' => ['basis/cis:r'],
'insertProfilRequest' => ['basis/cis:rw'],
'updateProfilRequest' => ['basis/cis:rw'],
'deleteProfilRequest' => ['basis/cis:rw'],
'selectProfilRequest' => ['basis/cis:r'],
'insertFile' => ['basis/cis:rw'],
'getProfilRequestFiles' => ['basis/cis:r'],
'getStatus' => ['basis/cis:r'],
'getTopic' => ['basis/cis:r'],
]);
$this->load->config('cis');
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Adressentyp_model', 'AdressenTypModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->load->model('person/Profil_update_status_model', 'ProfilUpdateStatusModel');
$this->load->model('person/Profil_update_topic_model', 'ProfilUpdateTopicModel');
// Load language phrases
$this->loadPhrases(
array(
'ui',
'global',
'person',
'profil',
'profilUpdate'
)
);
$this->load->library('DmsLib');
$this->load->library('PermissionLib');
//? put the uid and pid inside the controller for reusability
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
// setup the ProfilUpdate states
$this->ProfilUpdateStatusModel->addSelect(['status_kurzbz']);
$status_kurzbz = $this->ProfilUpdateStatusModel->load();
if (hasData($status_kurzbz)) {
list($status_pending, $status_accepted, $status_rejected) = getData($status_kurzbz);
self::$STATUS_PENDING = $status_pending->status_kurzbz;
self::$STATUS_ACCEPTED = $status_accepted->status_kurzbz;
self::$STATUS_REJECTED = $status_rejected->status_kurzbz;
}
// setup the ProfilUpdate topics
$this->ProfilUpdateTopicModel->addSelect(['topic_kurzbz']);
$topic_kurzbz = $this->ProfilUpdateTopicModel->load();
if (hasData($topic_kurzbz)) {
foreach (getData($topic_kurzbz) as $topic) {
self::$TOPICS[$topic->topic_kurzbz] = $topic->topic_kurzbz;
}
}
}
public function index()
{
$this->load->view('Cis/ProfilUpdate');
}
public function id($profil_update_id = null)
{
$this->load->view('Cis/ProfilUpdate', ['profil_update_id' => $profil_update_id]);
}
public function getStatus()
{
echo json_encode([self::$STATUS_PENDING => self::$STATUS_PENDING, self::$STATUS_ACCEPTED => self::$STATUS_ACCEPTED, self::$STATUS_REJECTED => self::$STATUS_REJECTED]);
}
public function getTopic()
{
echo json_encode(self::$TOPICS);
}
private function sendEmail_onProfilUpdate_response($uid, $topic, $status)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$email = $uid . "@" . DOMAIN;
function languageQuery($language)
{
return "select index from public.tbl_sprache where sprache = '" + $language + "'";
}
$this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]);
$status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]);
if (isError($status_translation)) {
show_error($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError'));
}
$status_translation = hasData($status_translation) ? getData($status_translation)[0] : null;
if (isset($status_translation)) {
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending')));
if (!$mail_res) {
show_error($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
private function sendEmail_onProfilUpdate_insertion($uid, $profil_update_id, $topic)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$emails = [];
$isMitarbeiter_res = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($isMitarbeiter_res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
$isMitarbeiter_res = getData($isMitarbeiter_res);
//! if the $uid is a mitarbeiter and student, only the hr is notified by email
if ($isMitarbeiter_res) {
//? user is not a student therefore he is a mitarbeiter, send email to Personalverwaltung
//? use constant variable MAIL_GST to mail to the personalverwaltung
$this->MitarbeiterModel->addSelect([TRUE]);
$this->MitarbeiterModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid");
//? check if the the userID is a mitarbeiter and if the benutzer is active
$res = $this->MitarbeiterModel->loadWhere(["public.tbl_mitarbeiter.mitarbeiter_uid" => $uid, "public.tbl_benutzer.aktiv" => TRUE]);
if (isError($res)) {
show_error("was not able to query the mitarbeiter and benutzer by the uid: " . $uid);
}
if (hasData($res)) {
array_push($emails, MAIL_GST);
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
} else {
//? if it is not a mitarbeiter, check whether it is a student and send email to studiengang
$isStudent_res = $this->StudentModel->isStudent($uid);
if (isError($isStudent_res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_studentCheck_error'));
}
$isStudent_res = getData($isStudent_res);
if ($isStudent_res) {
//? Send email to the Studiengangsassistentinnen
$this->StudentModel->addSelect(["public.tbl_studiengang.email"]);
$this->StudentModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_student.student_uid");
$this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id");
$this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id");
$this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz");
//* check if the benutzer itself is active
//* check if the student status is Student or Diplomand (active students)
$this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']);
$res = $this->StudentModel->loadWhere(["public.tbl_benutzer.aktiv" => TRUE, "public.tbl_student.student_uid" => $uid]);
if (isError($res)) {
show_error(getData($res));
} else {
$res = hasData($res) ? getData($res) : [];
foreach ($res as $emailObj) {
array_push($emails, $emailObj->email);
}
}
}
}
$mail_res = [];
//? sending email
foreach ($emails as $email) {
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid)));
}
foreach ($mail_res as $m_res) {
if (!$m_res) {
show_error($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
public function show($dms_id)
{
$profil_update = $this->ProfilUpdateModel->loadWhere(['attachment_id' => $dms_id]);
$profil_update = hasData($profil_update) ? getData($profil_update)[0] : null;
//? checks if an profil update exists with the dms_id requested from the user
if ($profil_update) {
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($profil_update->uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($profil_update->uid));
if (
$this->permissionlib->isBerechtigt('student/stammdaten:r') && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten:r') && $is_mitarbeiter_profil_update ||
$this->uid == $profil_update->uid
) {
// Get file to be downloaded from DMS
$newFilename = $this->uid . "/document_" . $dms_id;
$download = $this->dmslib->download($dms_id);
if (isError($download))
return $download;
// Download file
$this->outputFile(getData($download));
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
return;
}
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_dms_error'));
return;
}
}
public function insertFile($replace)
{
$replace = json_decode($replace);
if (!count($_FILES)) {
echo json_encode([]);
return;
}
//? if replace is set it contains the profil_update_id in which the attachment_id has to be replaced
if (isset($replace)) {
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$profilUpdate = $this->ProfilUpdateModel->load([$replace]);
if (isError($profilUpdate)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error')));
}
//? get the attachmentID
$dms_id = hasData($profilUpdate) ? getData($profilUpdate)[0]->attachment_id : null;
//? delete old dms_file of Profil Update
$this->deleteOldVersionFile($dms_id);
}
$files = $_FILES['files'];
$file_count = count($files['name']);
$res = [];
for ($i = 0; $i < $file_count; $i++) {
$_FILES['files']['name'] = $files['name'][$i];
$_FILES['files']['type'] = $files['type'][$i];
$_FILES['files']['tmp_name'] = $files['tmp_name'][$i];
$_FILES['files']['error'] = $files['error'][$i];
$_FILES['files']['size'] = $files['size'][$i];
$dms = [
"kategorie_kurzbz" => "profil_aenderung",
"version" => 0,
"name" => $_FILES['files']['name'],
"mimetype" => $_FILES['files']['type'],
"beschreibung" => $this->uid . " Profil Änderung",
"insertvon" => $this->uid,
"insertamum" => "NOW()",
];
$tmp_res = $this->dmslib->upload($dms, 'files', array("jpg", "png", "pdf"));
$tmp_res = hasData($tmp_res) ? getData($tmp_res) : null;
array_push($res, $tmp_res);
}
echo json_encode($res);
}
public function selectProfilRequest()
{
$_GET = json_decode($this->input->raw_input_stream, true);
$uid = $this->input->get('uid');
$id = $this->input->get('id');
$whereClause = ['uid' => $this->uid];
if (isset($uid))
$whereClause['uid'] = $uid;
if (isset($id))
$whereClause['id'] = $id;
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere($whereClause);
$res = hasData($res) ? getData($res) : null;
echo json_encode($res);
}
public function getProfilRequestFiles()
{
$id = json_decode($this->input->raw_input_stream);
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$attachmentID = $this->ProfilUpdateModel->load([$id]);
if (isError($attachmentID)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_loading_error')));
}
//? get the attachmentID
$dms_id = hasData($attachmentID) ? getData($attachmentID)[0]->attachment_id : null;
//? get the name to the file
$this->DmsVersionModel->addSelect(["name", "dms_id"]);
$attachment = $this->DmsVersionModel->load([$dms_id, 0]);
if (isError($attachment)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error')));
}
$attachment = hasData($attachment) ? getData($attachment) : null;
//? returns {name:..., dms_id:...}
echo json_encode($attachment);
}
public function insertProfilRequest()
{
$json = json_decode($this->input->raw_input_stream);
$payload = $json->payload;
$identifier = property_exists($json->payload, "kontakt_id") ? "kontakt_id" : (property_exists($json->payload, "adresse_id") ? "adresse_id" : null);
$data = ["topic" => $json->topic, "uid" => $this->uid, "requested_change" => json_encode($payload), "insertamum" => "NOW()", "insertvon" => $this->uid, "status" => self::$STATUS_PENDING ?: 'Pending'];
//? insert fileID in the dataset if sent with post request
if (isset($json->fileID)) {
$data['attachment_id'] = $json->fileID;
}
//? loops over all updateRequests from a user to validate if the new request is valid
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere(["uid" => $this->uid]);
if (isError($res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_loading_error'));
}
$res = hasData($res) ? getData($res) : null;
//? the user cannot delete a zustelladresse/kontakt
if (isset($payload->delete) && $payload->{$identifier == "kontakt_id" ? "zustellung" : "zustelladresse"}) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')));
return;
}
//? if the user tries to delete a adresse, checks whether the adresse is a heimatadresse, if so an error is raised
if (isset($payload->delete) && $identifier == "adresse_id") {
$adr = $this->AdresseModel->load($payload->$identifier);
$adr = getData($adr)[0];
if ($adr->heimatadresse) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error')));
return;
}
}
if ($res) {
$pending_changes = array_filter($res, function ($element) {
return $element->status == (self::$STATUS_PENDING ?: "Pending");
});
foreach ($pending_changes as $update_request) {
$existing_change = $update_request->requested_change;
//? the user can add as many new kontakte/adressen as he likes
if (!isset($payload->add) && property_exists($existing_change, $identifier) && property_exists($payload, $identifier) && $existing_change->$identifier == $payload->$identifier) {
//? the kontakt_id / adresse_id of a change has to be unique
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTwice_error')));
return;
}
//? if it is not updating any kontakt/adresse, the topic has to be unique
elseif (!$identifier && $update_request->topic == $json->topic) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_changeTopicTwice_error', ['0' => $update_request->topic])));
return;
}
}
}
$insertID = $this->ProfilUpdateModel->insert($data);
if (isError($insertID)) {
show_error(getData($insertID));
} else {
$insertID = hasData($insertID) ? getData($insertID) : null;
//? sends emails to the correspondents of the $uid
$this->sendEmail_onProfilUpdate_insertion($this->uid, $insertID, $json->topic);
echo json_encode(success($insertID));
}
}
public function updateProfilRequest()
{
$json = json_decode($this->input->raw_input_stream);
$updateData = ["requested_change" => json_encode($json->payload), "updateamum" => "NOW()", "updatevon" => $this->uid];
if (isset($json->fileID)) {
$updateData['attachment_id'] = json_decode($json->fileID);
}
$updateID = $this->ProfilUpdateModel->update([$json->ID], $updateData);
//? insert fileID in the dataset if sent with post request
if (isError($updateID)) {
//catch error
} else {
$updateID = hasData($updateID) ? getData($updateID)[0] : null;
//TODO: should an email be sent to the responsable people when the user changes his profil update
echo json_encode(success($updateID));
}
}
public function deleteProfilRequest()
{
$json = json_decode($this->input->raw_input_stream);
$delete_res = $this->ProfilUpdateModel->delete([$json]);
echo json_encode($delete_res);
}
public function getProfilUpdateWithPermission($status = null)
{
// early return if no status has been passed as argument
if (!isset($status)) {
echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission());
return;
}
// get the sprache of the user
$sprachenIndex = $this->SpracheModel->loadWhere(["sprache" => getUserLanguage()]);
$sprachenIndex = hasData($sprachenIndex) ? getData($sprachenIndex)[0]->index : null;
if (isset($sprachenIndex) && isset($status)) {
// get the corresponding status kurz_bz primary key out of the translation
$status = $this->ProfilUpdateStatusModel->execReadOnlyQuery("select * from public.tbl_profil_update_status where ? = ANY(bezeichnung_mehrsprachig)", [$status]);
$status = hasData($status) ? getData($status)[0]->status_kurzbz : null;
$res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null);
echo json_encode($res);
}
}
private function getOE_from_student($student_uid)
{
//? returns the oe_einheit eines Studenten
$query = "SELECT public.tbl_studiengang.oe_kurzbz
FROM public.tbl_student
JOIN public.tbl_studiengang ON tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
WHERE public.tbl_student.student_uid = ?;";
$res = $this->StudentModel->execReadOnlyQuery($query, [$student_uid]);
if (!isSuccess($res)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_loadingOE_error'));
}
$res = hasData($res) ? getData($res) : [];
$res = array_map(
function ($item) {
return $item->oe_kurzbz;
},
$res
);
return $res;
}
public function acceptProfilRequest()
{
$_POST = json_decode($this->input->raw_input_stream, true);
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
//? fetching person_id using UID
$personID = $this->PersonModel->getByUid($uid);
$personID = hasData($personID) ? getData($personID)[0]->person_id : null;
$status_message = $this->input->post('status_message', true);
$topic = $this->input->post('topic', true);
//! somehow the xss check converted boolean false to empty string
$requested_change = $this->input->post('requested_change');
//! check for required information
if (!isset($id) || !isset($uid) || !isset($personID) || !isset($requested_change) || !isset($topic)) {
return json_encode(error($this->p->t('profilUpdate', 'profilUpdate_requiredInformation_error')));
}
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($uid));
//? check if the permissions are set correctly
if (
$this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update
) {
if (is_array($requested_change) && array_key_exists("adresse_id", $requested_change)) {
$insertID = $this->handleAdresse($requested_change, $personID);
$insertID = hasData($insertID) ? getData($insertID) : null;
if (isset($insertID)) {
$requested_change['adresse_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_address_error', [$insertID])));
return;
}
}
} else if (is_array($requested_change) && array_key_exists("kontakt_id", $requested_change)) {
$insertID = $this->handleKontakt($requested_change, $personID);
$insertID = hasData($insertID) ? getData($insertID) : null;
if (isset($insertID)) {
$requested_change['kontakt_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_kontakt_error', [$insertID])));
return;
}
}
} else {
switch ($topic) {
// mapping phrasen to database columns to make the update with the correct column names
case self::$TOPICS['Titel']:
$topic = "titelpre";
break;
case self::$TOPICS['Postnomen']:
$topic = "titelpost";
break;
case self::$TOPICS['Vorname']:
$topic = "vorname";
break;
case self::$TOPICS['Nachname']:
$topic = "nachname";
break;
default:
show_error($this->p->t('profilUpdate', 'profilUpdate_topic_error', [$topic]));
return;
}
$result = $this->PersonModel->update($personID, [$topic => $requested_change["value"]]);
if (isError($result)) {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_insert_error')));
return;
}
}
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_ACCEPTED);
echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_ACCEPTED, $status_message, $requested_change));
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
}
public function denyProfilRequest()
{
$_POST = json_decode($this->input->raw_input_stream, true);
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
$topic = $this->input->post('topic', true);
$status_message = $this->input->post('status_message', true);
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($uid));
if (
$this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid") && $is_mitarbeiter_profil_update
) {
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_REJECTED);
echo json_encode($this->setStatusOnUpdateRequest($id, self::$STATUS_REJECTED, $status_message));
} else {
show_error($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
}
private function updateRequestedChange($id, $requested_change)
{
return $this->ProfilUpdateModel->update([$id], ['requested_change' => json_encode($requested_change)]);
}
private function setStatusOnUpdateRequest($id, $status, $status_message)
{
return $this->ProfilUpdateModel->update([$id], ["status" => $status, "status_timestamp" => "NOW()", "status_message" => $status_message]);
}
private function deleteOldVersionFile($dms_id)
{
if (!isset($dms_id)) {
return;
}
//? collect all the results of the deleted versions in an array
$res = array();
//? delete all the different versions of the dms_file
$dmsVersions = $this->DmsVersionModel->loadWhere(["dms_id" => $dms_id]);
$dmsVersions = hasData($dmsVersions) ? getData($dmsVersions) : null;
if (isset($dmsVersions)) {
$zwischen_res = array_map(function ($item) {
return $item->version;
}, $dmsVersions);
foreach ($zwischen_res as $version) {
array_push($res, $this->DmsVersionModel->delete([$dms_id, $version]));
}
} else {
echo json_encode(error($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error')));
}
//? returns a result for each deleted dms_file
return $res;
}
private function handleKontakt($requested_change, $personID)
{
$kontakt_id = $requested_change["kontakt_id"];
//? removes the kontakt_id because we don't want to update the kontakt_id in the database
unset($requested_change["kontakt_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['person_id'] = $personID;
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$insertID = $this->KontaktModel->insert($requested_change);
$insert_kontakt_id = $insertID;
if (isError($insert_kontakt_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_insertKontakt_error'));
}
$insert_kontakt_id = hasData($insert_kontakt_id) ? getData($insert_kontakt_id) : null;
if ($insert_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $insert_kontakt_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$this->KontaktModel->delete($kontakt_id);
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_kontakt_id = $this->KontaktModel->update($kontakt_id, $requested_change);
if (isError($update_kontakt_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_updateKontakt_error'));
}
$update_kontakt_id = hasData($update_kontakt_id) ? getData($update_kontakt_id) : null;
if ($update_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $update_kontakt_id);
}
}
return isset($insertID) ? $insertID : null;
}
private function handleAdresse($requested_change, $personID)
{
$this->AdressenTypModel->addSelect(["adressentyp_kurzbz"]);
$adr_kurzbz = $this->AdressenTypModel->loadWhere(["bezeichnung" => $requested_change['typ']]);
$adr_kurzbz = hasData($adr_kurzbz) ? getData($adr_kurzbz)[0]->adressentyp_kurzbz : null;
//? replace the address_typ with its correct kurzbz foreign key
$requested_change['typ'] = $adr_kurzbz;
$adresse_id = $requested_change["adresse_id"];
//? removes the adresse_id because we don't want to update the kontakt_id in the database
unset($requested_change["adresse_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$requested_change['person_id'] = $personID;
//TODO: zustelladresse, heimatadresse, rechnungsadresse und nation werden nicht beachtet
$insertID = $this->AdresseModel->insert($requested_change);
$insert_adresse_id = $insertID;
if (isError($insert_adresse_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_insertAdresse_error'));
}
$insert_adresse_id = hasData($insert_adresse_id) ? getData($insert_adresse_id) : null;
if ($insert_adresse_id) {
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $insert_adresse_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$this->AdresseModel->delete($adresse_id);
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_adresse_id = $this->AdresseModel->update($adresse_id, $requested_change);
if (isError($update_adresse_id)) {
show_error($this->p->t('profilUpdate', 'profilUpdate_updateAdresse_error'));
}
$update_adresse_id = hasData($update_adresse_id) ? getData($update_adresse_id) : null;
if ($update_adresse_id) {
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $update_adresse_id);
}
}
return isset($insertID) ? $insertID : null;
}
private function handleDupplicateZustellKontakte($zustellung, $kontakt_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_kontakt.kontakt_id");
$this->PersonModel->addJoin("public.tbl_kontakt", "public.tbl_kontakt.person_id = public.tbl_person.person_id");
$zustellKontakteArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustellung" => TRUE]);
if (!isSuccess($zustellKontakteArray)) {
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellkontakte_error'));
}
$zustellKontakteArray = hasData($zustellKontakteArray) ? getData($zustellKontakteArray) : null;
if ($zustellung && count($zustellKontakteArray) > 0) {
$zustellKontakteArray = array_filter($zustellKontakteArray, function ($kontakt) use ($kontakt_id) {
return $kontakt->kontakt_id != $kontakt_id;
});
foreach ($zustellKontakteArray as $kontakt) {
$this->KontaktModel->update($kontakt->kontakt_id, ["zustellung" => FALSE]);
}
}
}
}
private function handleDupplicateZustellAdressen($zustellung, $adresse_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_adresse.adresse_id");
$this->PersonModel->addJoin("public.tbl_adresse", "public.tbl_adresse.person_id = public.tbl_person.person_id");
$zustellAdressenArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustelladresse" => TRUE]);
if (!isSuccess($zustellAdressenArray)) {
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellAdressen_error'));
}
$zustellAdressenArray = hasData($zustellAdressenArray) ? getData($zustellAdressenArray) : null;
if ($zustellung && count($zustellAdressenArray) > 0) {
$zustellAdressenArray = array_filter($zustellAdressenArray, function ($adresse) use ($adresse_id) {
return $adresse->adresse_id != $adresse_id;
});
foreach ($zustellAdressenArray as $adresse) {
$this->AdresseModel->update($adresse->adresse_id, ["zustelladresse" => FALSE]);
}
}
}
}
}
+167
View File
@@ -0,0 +1,167 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Pub extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'bild' => ['basis/cis:r']
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @param string $source [person|akte]
* @param integer $id
* @return void
*/
public function bild($source, $id)
{
$this->load->model('person/Person_model', 'PersonModel');
$person_id_user = '';
$serverzugriff = false;
// Wenn das Bild direkt aufgerufen wird, ist eine Authentifizierung erforderlich
// Wenn es vom Server selbst aufgerufen wird, ist keine Auth. notwendig
// (z.B. fuer die Erstellung von PDFs)
if ($_SERVER['REMOTE_ADDR'] != $_SERVER['SERVER_ADDR']) {
// Wenn Session gesetzt ist, keine Abfrage, da diese Personen noch keine UID haben
if (isset($_SESSION['incoming/user'])) { // Von Incomingtool
$result = $this->PersonModel->loadWhere([
'zugangscode' => $_SESSION['incoming/user']
]);
if (hasData($result))
$person_id_user = current(getData($result))->person_id;
} elseif (isset($_SESSION['prestudent/user'])) { // Von Prestudententool
$result = $this->PersonModel->loadWhere([
'zugangscode' => $_SESSION['prestudent/user']
]);
if (hasData($result))
$person_id_user = current(getData($result))->person_id;
} elseif (isset($_SESSION['bewerbung/personId'])) { // Von Bewerbungstool
$person_id_user = $_SESSION['bewerbung/personId'];
} else {
$person_id_user = getAuthPersonId();
}
} else {
$serverzugriff = true;
}
// Default Bild (Dummy Profilbild)
$cTmpHEX = base64_encode(file_get_contents(FHCPATH . 'skin/images/profilbild_dummy.jpg'));
if ($source == 'person' && $id) {
$foto_gesperrt = false;
// Person laden und Fotosperre überprüfen
$result = $this->PersonModel->load($id);
if (hasData($result)) {
$person = current(getData($result));
if ($person->foto_sperre) {
// Wenn der User selbst darauf zugreift darf er das Bild sehen
$foto_gesperrt = ($person_id_user != $id);
} elseif (!$person_id_user && !$serverzugriff) {
$foto_gesperrt = true;
}
if ($person->foto && !$foto_gesperrt) {
$cTmpHEX = base64_decode($person->foto);
}
}
}
if($source == 'akte' && $id != '')
{
$this->load->model('crm/Akte_model', 'AkteModel');
$this->AkteModel->addJoin('public.tbl_person', 'person_id');
$result = $this->AkteModel->loadWhere([
'person_id' => $id,
'dokument_kurzbz' => 'Lichtbil'
]);
if (hasData($result)) {
$foto_gesperrt = false;
$akte = current(getData($result));
if ($akte->foto_sperre) {
// Wenn der User selbst darauf zugreift darf er das Bild sehen
$foto_gesperrt = ($person_id_user != $id);
} elseif (!$person_id_user && !$serverzugriff) {
$foto_gesperrt = true;
}
// Wenn das Foto nicht im Inhalt steht wird aus aus dem DMS geladen
if (!$akte->inhalt && $akte->dms_id) {
$this->load->model('content/Dms_model', 'DmsModel');
$this->load->model('content/DmsVersion_model', 'DmsVersionModel');
$this->DmsModel->addJoin('campus.tbl_dms_version', 'dms_id');
$this->DmsModel->addOrder('version', 'DESC');
$this->DmsModel->addLimit(1);
$result = $this->DmsModel->load($akte->dms_id);
if (!hasData($result))
die('Kein Dokument vorhanden');
$dms = current(getData($result));
$filename = DMS_PATH . $dms->filename;
$this->DmsVersionModel->update([
'dms_id' => $dms->dms_id,
'version' => $dms->version
], [
'letzterzugriff' => date('c')
]);
if (file_exists($filename)) {
$handle = fopen($filename, "r");
if ($handle) {
while (!feof($handle)) {
$akte->inhalt .= fread($handle, 8192);
}
fclose($handle);
} else {
echo 'Fehler: Datei konnte nicht geoeffnet werden';
}
} else {
echo 'Die Datei existiert nicht';
}
}
if ($akte->inhalt && !$foto_gesperrt) {
$cTmpHEX = $akte->inhalt;
}
}
}
// die bilder werden, sofern es funktioniert, in jpg umgewandelt da es sonst zu fehlern beim erstellen
// von pdfs kommen kann.
$im = @imagecreatefromstring(base64_decode($cTmpHEX));
if ($im) {
@ob_clean();
header("Content-type: image/jpeg");
exit(imagejpeg($im));
} else {
// bei manchen Bildern funktioniert die konvertierung nicht
// diese werden dann einfach so angezeigt.
@ob_clean();
header("Content-type: image/gif");
exit($cTmpHEX);
}
}
}
@@ -3,30 +3,28 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Test VBform Vue Component
*
*/
class TestVBform extends Auth_Controller
class Stundenplan extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'index' => 'system/developer:r'
)
);
parent::__construct([
'index' => ['basis/cis:r']
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Everything has a beginning
* @return void
*/
public function index()
{
$this->load->view('system/logs/testVBform.php');
$this->load->view('Cis/Stundenplan');
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Cis4 extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'index' => 'basis/cis:r'
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$this->load->model('person/Person_model','PersonModel');
$personData = getData($this->PersonModel->getByUid(getAuthUID()))[0];
$viewData = array(
'uid' => getAuthUID(),
'name' => $personData->vorname,
'person_id' => $personData->person_id
);
$this->load->view('CisVue/Dashboard.php',['viewData' => $viewData]);
}
}
+127
View File
@@ -0,0 +1,127 @@
<?php
if (!defined('BASEPATH'))
exit('No direct script access allowed');
/**
*
*/
class Cms extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'content' => 'basis/cis:r',
'getNews' => 'basis/cis:r',
'getNewsRowCount' => 'basis/cis:r',
'getRoomInformation' => 'basis/cis:r',
'news' => 'basis/cis:r'
)
);
// Loads Libraries
$this->load->library('CmsLib');
// Loads phrases system
$this->loadPhrases([
'global'
]);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @param int $content_id
* @param int $version
* @param string $sprache
* @param boolean $sichtbar
*
* @return void
*/
public function content($content_id, $version = null, $sprache = null, $sichtbar = true)
{
// return early if the content_id for the content is missing
if (!isset($content_id))
$this->terminateWithError("content_id is missing");
$content = $this->ContentModel->load($content_id);
if (isError($content))
$this->terminateWithError(getError($content));
$content = getData($content);
if (NULL === $content)
$this->terminateWithError("Content not found");
$content = current($content);
$this->load->view('CisVue/Cms/Content', ['content_id' => $content_id, 'template_kurzbz' => $content->template_kurzbz, 'version' => $version, 'sprache' => $sprache, 'sichtbar' => $sichtbar]);
}
/**
* @param boolean $infoscreen
* @param string | null $studiengang_kz
* @param int | null $semester
* @param boolean $mischen
* @param string $titel
* @param boolean $edit
* @param boolean $sichtbar
*
* @return void
*/
public function news($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true)
{
$this->load->view('CisVue/Cms/Content', ['infoscreen' => $infoscreen, 'studiengang_kz' => $studiengang_kz, 'semester' => $semester, 'mischen' => $mischen, 'titel' => $titel, 'edit' => $edit, 'sichtbar' => $sichtbar]);
}
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true)
{
$get_page = intval($this->input->get('page', true));
$get_page_size = intval($this->input->get('page_size', true));
if ($get_page) {
$page = $get_page;
}
if ($get_page_size) {
$page_size = $get_page_size;
} else {
$page_size = $this->page_size;
}
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size);
if (isError($news)) {
$this->terminateWithJsonError(getError($news));
}
$news = hasData($news) ? getData($news) : null;
if ($news) {
echo json_encode($news);
} else {
show_error("News: No data found");
}
}
public function getNewsRowCount($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $fachbereich_kurzbz = null, $maxalter = 0, $edit = false, $sichtbar = true, $page = 1, $page_size = 10)
{
list($studiengang_kz, $semester) = $this->cmslib->getStgAndSem($studiengang_kz, $semester);
$all = $edit;
$num_rows = $this->NewsModel->countNewsWithContent(getSprache(), $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $this->page_size, $all, $mischen);
if (isError($num_rows)) {
$this->terminateWithJsonError(getError($num_rows));
}
$num_rows = hasData($num_rows) ? getData($num_rows) : null;
if ($num_rows) {
echo json_encode($num_rows);
} else {
show_error("News number rows: No data found");
}
}
public function getRoomInformation($ort_kurzbz){
$this->load->view('CisVue/Cms/RoomInformation',['ort_kurzbz'=>$ort_kurzbz]);
}
}
@@ -0,0 +1,45 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Dashboard extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'index' => 'dashboard/benutzer:r'
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @return void
*/
public function index()
{
$this->load->model('person/Person_model','PersonModel');
$begruesung = $this->PersonModel->getFirstName(getAuthUID());
if(isError($begruesung))
{
show_error("name couldn't be loaded for username ".getAuthUID());
}
$begruesung = getData($begruesung);
$viewData = array(
'name' => $begruesung
);
$this->load->view('CisVue/Dashboard.php', ['viewData' => $viewData]);
}
}
@@ -0,0 +1,40 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Studentenverwaltung extends Auth_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['admin:r', 'assistenz:r'];
parent::__construct($permissions);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
/**
* @return void
*/
public function _remap()
{
$this->load->view('Studentenverwaltung', [
'permissions' => [
'student/bpk' => $this->permissionlib->isBerechtigt('student/bpk'),
'student/alias' => $this->permissionlib->isBerechtigt('student/alias'),
'basis/prestudent' => $this->permissionlib->isBerechtigt('basis/prestudent'),
'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'),
'student/keine_studstatuspruefung' => $this->permissionlib->isBerechtigt('student/keine_studstatuspruefung'),
'lehre/reihungstestAufsicht' => $this->permissionlib->isBerechtigt('lehre/reihungstestAufsicht')
],
'variables' => [
'semester_aktuell' => $this->variablelib->getVar('semester_aktuell')
]
]);
}
}
-16
View File
@@ -1,16 +0,0 @@
<?php
if ( !defined("PHPUNIT_TEST") ) {
show_404();
}
class Test extends CI_Controller
{
public function index()
{
// Yep... This is all we need.
ini_set('error_reporting', E_ALL); // or error_reporting(E_ALL);
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
}
}
@@ -0,0 +1,163 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (FAS) and the AntragLib (back-end)
* This controller works with calls on the HTTP GET or POST and the output is always RDF
*/
class Wiederholung extends Auth_Controller
{
/**
* Calls the parent's constructor and loads the FilterCmptLib
*/
public function __construct()
{
parent::__construct([
'getLvs' => ['student/studierendenantrag:r', 'student/noten:r'],
'moveLvsToZeugnis' => ['student/studierendenantrag:w', 'student/noten:w']
]);
// Libraries
$this->load->library('AntragLib');
// Load language phrases
$this->loadPhrases([
'global',
'studierendenantrag'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getLvs($prestudent_id)
{
// header für no cache
$this->output->set_header("Cache-Control: no-cache");
$this->output->set_header("Cache-Control: post-check=0, pre-check=0", false);
$this->output->set_header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
$this->output->set_header("Pragma: no-cache");
$this->output->set_header("Content-type: application/xhtml+xml");
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$sem_akt = $this->variablelib->getVar('semester_aktuell');
$result = $this->antraglib->getLvsForPrestudent($prestudent_id, $sem_akt);
if (isError($result))
return $result;
$lvs = $result->retval;
$rdf_url = 'http://www.technikum-wien.at/antragnote';
$this->load->view('lehre/Antrag/Wiederholung/getLvs.rdf.php', [
'url' => $rdf_url,
'lvs' => $lvs
]);
}
public function moveLvsToZeugnis()
{
$anzahl = $this->input->post('anzahl');
$student_uid = $this->input->post('student_uid');
$this->load->model('education/Studierendenantraglehrveranstaltung_model', 'StudierendenantraglehrveranstaltungModel');
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$errormsg = array();
for($i=0; $i<$anzahl; $i++)
{
$id = $this->input->post('studierendenantrag_lehrveranstaltung_id_' . $i);
$result =$this->StudierendenantraglehrveranstaltungModel->load($id);
if(isError($result))
{
$errormsg[] = getError($result);
}
elseif(!hasData($result))
{
$errormsg[] = $this->p->t('studierendenantrag', 'error_no_lv_in_application');
}
else
{
$antragLv = getData($result)[0];
$result= $this->ZeugnisnoteModel->load([
'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id,
'student_uid'=> $student_uid,
'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz
]);
if(isError($result))
{
$errormsg[] = getError($result);
}
else
{
if (hasData($result))
{
$result = $this->ZeugnisnoteModel->update(
[
'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id,
'student_uid'=> $student_uid,
'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz
],
[
'note'=> $antragLv->note,
'uebernahmedatum' => date('c'),
'benotungsdatum' => $antragLv->insertamum,
'updateamum' => date('c'),
'bemerkung'=>$antragLv->anmerkung,
'updatevon'=>getAuthUID()
]
);
}
else
{
$result = $this->ZeugnisnoteModel->insert([
'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id,
'student_uid'=> $student_uid,
'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz,
'note'=> $antragLv->note,
'uebernahmedatum' => date('c'),
'benotungsdatum' => $antragLv->insertamum,
'insertamum' => date('c'),
'bemerkung'=>$antragLv->anmerkung,
'insertvon'=>getAuthUID()
]);
}
if(isError($result))
{
$errormsg[] = getError($result);
}
}
}
}
if($errormsg)
$return = false;
else
$return = true;
$this->load->view('lehre/Antrag/Wiederholung/moveLvs.rdf.php', [
'return' => $return,
'errormsg' => $errormsg
]);
}
}
@@ -0,0 +1,145 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
class Ampeln extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'open' => self::PERM_LOGGED,
'all' => self::PERM_LOGGED,
'confirm' => self::PERM_LOGGED,
'alleAmpeln' => self::PERM_LOGGED,
]);
$this->load->model('content/Ampel_model', 'AmpelModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* confirms ampel and inserts ampel_id in public.tbl_ampel_benutzer_bestaetigt
* @access public
*
*/
public function confirm($ampel_id)
{
$this->load->library('form_validation');
$this->form_validation->set_data(['ampel_id'=> $ampel_id]);
$this->form_validation->set_rules('ampel_id', 'Ampel ID', 'required|integer');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
// load Ampel_benutzer_bestaetigt_model to confirm the ampel
$this->load->model('content/Ampel_Benutzer_Bestaetigt_model', 'AmpelBenutzerBestaetigtModel');
$insert_into_result = $this->AmpelBenutzerBestaetigtModel->insert(["ampel_id"=> $ampel_id, "uid"=> $this->uid]);
$insert_into_result = $this->getDataOrTerminateWithError($insert_into_result);
$this->terminateWithSuccess($insert_into_result);
}
/**
* queries active and not confirmed ampeln by the user
* @access public
*
*/
public function open()
{
$userAmpeln = array();
// fetch active ampeln
$activeAmpeln = $this->AmpelModel->openActive($this->uid, false);
$activeAmpeln = $this->getDataOrTerminateWithError($activeAmpeln);
foreach ($activeAmpeln as $ampel) {
// only include non confirmed active ampeln in the result
if (!$ampel->bestaetigt) {
// check if the user was assigned to the ampel
$zugeteilt = $this->AmpelModel->isZugeteilt($this->uid, $ampel->benutzer_select);
$zugeteilt = $this->getDataOrTerminateWithError($zugeteilt);
if($zugeteilt) $userAmpeln[] = $ampel;
}
}
$this->terminateWithSuccess($userAmpeln);
}
/**
* queries all ampeln of the user
* @access public
*
*/
public function all()
{
$userAmpeln = array();
$ampel_result = $this->AmpelModel->active(false, $this->uid);
$ampel_result = $this->getDataOrTerminateWithError($ampel_result);
foreach ($ampel_result as $ampel) {
// check if the ampel was assigned to the user
$zugeteilt = $this->AmpelModel->isZugeteilt($this->uid, $ampel->benutzer_select);
$zugeteilt = $this->getDataOrTerminateWithError($zugeteilt);
if ($zugeteilt) $userAmpeln[] = $ampel;
}
$this->terminateWithSuccess($userAmpeln);
}
/**
* queries all ampeln that were assigned to the user until start of first work day
* @access public
*
*/
public function alleAmpeln()
{
//fetch all ampeln
$alle_ampeln = $this->AmpelModel->alleAmpeln($this->uid);
$alle_ampeln = $this->getDataOrTerminateWithError($alle_ampeln);
$alle_ampeln = array_map(function ($ampel) {
// check if ampel is confirmed by user
$confirmedByUser = $this->AmpelModel->isConfirmed($ampel->ampel_id, $this->uid);
$ampel->bestaetigt = $confirmedByUser;
return $ampel;
}, $alle_ampeln);
$this->terminateWithSuccess($alle_ampeln);
}
}
@@ -0,0 +1,109 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Bookmark extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getBookmarks' => self::PERM_LOGGED,
'delete' => self::PERM_LOGGED,
'insert' => self::PERM_LOGGED,
]);
$this->load->model('dashboard/Bookmark_model', 'BookmarkModel');
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* gets the bookmarks associated to a user
* @access public
* @return void
*/
public function getBookmarks()
{
$bookmarks = $this->BookmarkModel->loadWhere(["uid"=>$this->uid]);
$bookmarks = $this->getDataOrTerminateWithError($bookmarks);
$this->terminateWithSuccess($bookmarks);
}
/**
* deletes bookmark from associated user
* @access public
* @return void
*/
public function delete($bookmark_id)
{
$bookmark = $this->BookmarkModel->load($bookmark_id);
$bookmark = current($this->getDataOrTerminateWithError($bookmark));
// only delete bookmark if the user is the owner of the bookmark
if($bookmark->uid == $this->uid || $this->permissionlib->isBerechtigt('admin')){
$delete_result = $this->BookmarkModel->delete($bookmark_id);
$delete_result = $this->getDataOrTerminateWithError($delete_result);
$this->terminateWithSuccess($delete_result);
}else{
$this->_outputAuthError(['delete' => ['admin:rw']]);
}
}
/**
* inserts new bookmark into the bookmark table
* @access public
* @return void
*/
public function insert()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_rules('url', 'URL', 'required|valid_url|max_length[511]');
$this->form_validation->set_rules('title', 'Title', 'required|max_length[255]');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$url = $this->input->post('url',true);
$title = $this->input->post('title',true);
$tag = $this->input->post('tag', true);
$insert_into_result = $this->BookmarkModel->insert(['uid'=>$this->uid, 'url'=>$url, 'title'=>$title,'tag'=>$tag, 'insertvon'=>$this->uid, 'updateamum'=>NULL, 'updatevon'=>NULL]);
$insert_into_result = $this->getDataOrTerminateWithError($insert_into_result);
$this->terminateWithSuccess($insert_into_result);
}
}
@@ -0,0 +1,195 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class Cms extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
// NOTE(chris): additional permission checks will be done in SearchBarLib
parent::__construct([
'ContentID' => self::PERM_LOGGED,
'getOrtKurzbzContent' => self::PERM_LOGGED,
'content' => self::PERM_LOGGED,
'news' => self::PERM_LOGGED,
'getNewsRowCount' => self::PERM_LOGGED,
'getNews' => self::PERM_LOGGED,
]);
$this->load->model('content/News_model', 'NewsModel');
// setting up the papgination_size
$this->page_size = 10;
$this->load->library('CmsLib');
// Loads phrases system
$this->loadPhrases([
'global'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* fetches the content with the content_id and additional parameters
*/
public function content()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('content_id','Content ID','required|is_natural');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
// getting the get parameters
$content_id = $this->input->get("content_id",TRUE);
$version = $this->input->get("version",TRUE);
$sprache = $this->input->get("sprache",TRUE);
$sichtbar = $this->input->get("sichtbar",TRUE);
$content = $this->cmslib->getContent($content_id, $version, $sprache, $sichtbar);
$content = $this->getDataOrTerminateWithError($content);
$this->terminateWithSuccess($content);
}
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
public function ContentID()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('ort_kurzbz', 'Ort', 'required');
if ($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$ort_kurzbz = $this->input->get('ort_kurzbz',TRUE);
$content_id = $this->OrtModel->getContentID($ort_kurzbz);
$content_id = current($this->getDataOrTerminateWithError($content_id))->content_id;
$this->terminateWithSuccess($content_id);
}
//todo: there is the method news and getNews but only one should exist
public function news()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('limit','Limit','required|is_natural_no_zero');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
$this->load->model('content/news_model', 'NewsModel');
$limit = $this->input->get('limit',TRUE);
//query the news
$news = $this->NewsModel->getAll($limit);
//get the data or terminate with error
$news = $this->getDataOrTerminateWithError($news);
// collect the content of the news
foreach($news as $news_element){
$this->addMeta("content_id",$news_element->content_id);
//todo: quick fix, for query builder error when fetching content
$this->NewsModel->resetQuery();
$content = $this->cmslib->getContent($news_element->content_id);
$content = getData($content);
$news_element->content_obj = $content;
}
$withContent = function($news) {
return $news->content_obj != null;
};
$newsWithContent = array_filter($news, $withContent);
$this->terminateWithSuccess($newsWithContent);
}
public function getNewsRowCount($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $fachbereich_kurzbz = null, $maxalter = 0, $edit = false, $sichtbar = true, $page = 1, $page_size = 10)
{
list($studiengang_kz, $semester) = $this->cmslib->getStgAndSem($studiengang_kz, $semester);
$all = $edit;
$this->load->model('content/News_model','NewsModel');
$num_rows = $this->NewsModel->countNewsWithContent(getSprache(), $studiengang_kz, $semester, $fachbereich_kurzbz, $sichtbar, $maxalter, $page, $page_size, $all, $mischen);
$num_rows = $this->getDataOrTerminateWithError($num_rows);
$this->terminateWithSuccess($num_rows);
}
public function getNews($infoscreen = false, $studiengang_kz = null, $semester = null, $mischen = true, $titel = '', $edit = false, $sichtbar = true)
{
//form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('page','Page','required|is_natural');
$this->form_validation->set_rules('page_size', 'PageSize', 'is_natural');
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
// getting the GET parameters
$page = intval($this->input->get('page', true));
$page_size = intval($this->input->get('page_size', true));
// default value for the page_size is 10
$page_size = $page_size ?? 10;
$news = $this->cmslib->getNews($infoscreen, $studiengang_kz, $semester, $mischen, $titel, $edit, $sichtbar, $page, $page_size);
$news = $this->getDataOrTerminateWithError($news);
$this->addMeta('test', $this->p->t('global', 'studiengangsleitung'));
$this->addMeta('phrases', json_decode($this->p->getJson()));
$this->terminateWithSuccess($news);
}
}
@@ -0,0 +1,231 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the FilterCmptLib (back-end)
* Provides data to the ajax get calls about the filter component
* Listens to ajax post calls to change the filter data
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Filter extends FHCAPI_Controller
{
const FILTER_UNIQUE_ID = 'filterUniqueId'; // Name of the filter cmpt unique id (mandatory)
const FILTER_TYPE = 'filterType'; // The filter type (PHP filter definition) used (mandatory)
const FILTER_ID = 'filterId'; // The id of the used filter (optional)
/**
* Calls the parent's constructor and loads the FilterCmptLib
*/
public function __construct()
{
// NOTE: FilterCmpt has its own permissions checks
parent::__construct([
'getFilter' => self::PERM_LOGGED,
'removeFilterField' => self::PERM_LOGGED,
'addFilterField' => self::PERM_LOGGED,
'applyFilterFields' => self::PERM_LOGGED,
'removeCustomFilter' => self::PERM_LOGGED,
'saveCustomFilter' => self::PERM_LOGGED,
'reloadDataset' => self::PERM_LOGGED
]);
// Loads the FiltersModel
$this->load->model('system/Filters_model', 'FiltersModel');
// Loads the FilterCmptLib with HTTP GET/POST parameters
$this->_startFilterCmptLib();
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Retrieves data about the current filter from the session and will be written on the output in JSON format
*/
public function getFilter()
{
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$session = $this->filtercmptlib->getSession();
if (is_object($session)) {
// If stdClass it is an retval object
$session = $this->getDataOrTerminateWithError($session);
}
$this->terminateWithSuccess($session);
}
/**
* Remove an applied filter (SQL where condition) from the current filter
*/
public function removeFilterField()
{
$this->form_validation->set_rules('filterField', 'filterField', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->removeFilterField($this->input->post('filterField'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Field removed');
}
/**
* Add a filter (SQL where clause) to be applied to the current filter
*/
public function addFilterField()
{
$this->form_validation->set_rules('filterField', 'filterField', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->addFilterField($this->input->post('filterField'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Field added');
}
/**
* Apply the filter changes
*/
public function applyFilterFields()
{
$this->form_validation->set_rules('filterFields[]', 'filterFields', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->applyFilterFields($this->input->post('filterFields'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Applied');
}
/**
* Save the current filter as a custom filter for this user with the given description
*/
public function saveCustomFilter()
{
$this->form_validation->set_rules('customFilterName', 'customFilterName', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->saveCustomFilter($this->input->post('customFilterName'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Saved');
}
/**
* Remove a custom filter by its filterId
*/
public function removeCustomFilter()
{
$this->form_validation->set_rules('filterId', 'filterId', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->filtercmptlib->removeCustomFilter($this->input->post('filterId'));
if (!$result)
$this->terminateWithError('Error occurred', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess('Removed');
}
/**
* Reloads the dataset
*/
public function reloadDataset()
{
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$this->filtercmptlib->reloadDataset();
$this->terminateWithSuccess('Success');
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Loads the FilterCmptLib with the FILTER_UNIQUE_ID parameter
* If the parameter FILTER_UNIQUE_ID is not given then the execution of the controller is terminated and
* an error message is printed
*/
private function _startFilterCmptLib()
{
$filterUniqueId = null;
$filterType = null;
$filterId = null;
$validations = [
[
'field' => self::FILTER_UNIQUE_ID,
'label' => self::FILTER_UNIQUE_ID,
'rules' => 'required'
],
[
'field' => self::FILTER_TYPE,
'label' => self::FILTER_TYPE,
'rules' => 'required'
],
];
$this->load->library('form_validation');
if ($this->input->method() == 'get')
$this->form_validation->set_data($this->input->get());
$this->form_validation->set_rules($validations);
if ($this->form_validation->run()) {
$filterUniqueId = $this->input->post_get(self::FILTER_UNIQUE_ID);
$filterType = $this->input->post_get(self::FILTER_TYPE);
$filterId = $this->input->post_get(self::FILTER_ID);
// Loads the FilterCmptLib that contains all the used logic
$this->load->library(
'FilterCmptLib',
array(
'filterUniqueId' => $filterUniqueId,
'filterType' => $filterType,
'filterId' => $filterId
)
);
// Start the component
$this->filtercmptlib->start();
}
}
}
@@ -0,0 +1,85 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Lehre extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'lvStudentenMail' => self::PERM_LOGGED,
'LV' => self::PERM_LOGGED,
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* constructs the emails of the groups from a lehrveranstaltung
*/
public function lvStudentenMail()
{
$lehreinheit_id = $this->input->get("lehreinheit_id",TRUE);
// return early if the required parameter is missing
if(!isset($lehreinheit_id))
{
$this->terminateWithError('Missing required parameter', self::ERROR_TYPE_GENERAL);
}
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$studentenMails = $this->LehreinheitModel->getStudentenMail($lehreinheit_id);
$studentenMails = $this->getDataOrTerminateWithError($studentenMails);
//convert array of objects into array of strings
$studentenMails = array_map(function($element){
return $element->mail;
}, $studentenMails);
$this->terminateWithSuccess($studentenMails);
}
public function LV($studiensemester_kurzbz, $lehrveranstaltung_id)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage(), $lehrveranstaltung_id);
$result = current($this->getDataOrTerminateWithError($result));
$this->terminateWithSuccess($result);
}
}
@@ -0,0 +1,532 @@
<?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 SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class LvMenu extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getLvMenu' => self::PERM_LOGGED
]);
$this->load->model("ressource/Mitarbeiter_model");
$this->load->model("education/Lehreinheit_model");
$this->load->model("education/Lehrveranstaltung_model");
$this->load->model("organisation/Studiengang_model");
$this->load->model("accounting/Vertrag_model");
$this->load->model("system/Variable_model");
$this->load->model("person/Benutzergruppe_model");
$this->load->model("education/Lvangebot_model");
$this->load->model("ressource/Lehretools_model");
$this->load->library("PermissionLib", null, 'PermissionLib');
$this->load->library("PhrasesLib");
$this->loadPhrases(array('global', 'lehre'));
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
*
*/
public function getLvMenu($lvid, $studiensemester_kurzbz)
{
// return early if parameters are missing
if(!isset($lvid) || !isset($studiensemester_kurzbz))
$this->terminateWithError('Missing parameters', self::ERROR_TYPE_GENERAL);
// get the sprache
$sprache = getUserLanguage();
// get the user
if (!$user=getAuthUID())
$this->terminateWithError($this->p->t('global', 'nichtAngemeldet'));
// check if is_lector
$is_lector = false;
$mares = $this->Mitarbeiter_model->isMitarbeiter($user);
if(hasData($mares))
{
$is_lector = getData($mares);
}
// definition of user_is_allowed_to_upload
$user_is_allowed_to_upload=false;
$angezeigtes_stsem = $studiensemester_kurzbz;
// load lehrveranstaltung
$lvres = $this->Lehrveranstaltung_model->load($lvid);
if(!hasData($lvres))
{
$this->terminateWithError('LV ' . $lvid . ' not found.');
}
$lv = (getData($lvres))[0];
// define studiengang_kz / semester / lehrverzeichnis
$studiengang_kz = $lv->studiengang_kz;
$semester = $lv->semester;
$short = $lv->lehreverzeichnis;
// load studiengang
$stgres = $this->Studiengang_model->load($lv->studiengang_kz);
if(!hasData($stgres))
{
$this->terminateWithError('Stg ' . $lv->studiengang_kz . ' nof found.');
}
$stg = (getData($stgres))[0];
$kurzbz = strtoupper($stg->typ . $stg->kurzbz);
$short_name = $lv->bezeichnung;
$short_short_name = $lv->lehreverzeichnis;
// angemeldet
$angemeldet = true;
if(defined('CIS_LEHRVERANSTALTUNG_WENNANGEMELDET_DETAILS_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_WENNANGEMELDET_DETAILS_ANZEIGEN && !$is_lector)
{
$angemeldet = false;
$lesres = $this->Lehreinheit_model->getLehreinheitenForStudentAndStudienSemester(
$lvid, $user, $angezeigtes_stsem
);
if(hasData($lesres) && count(getData($lesres)) > 0)
$angemeldet = true;
}
// lehrfach
$lehrfach_id='';
if(defined('CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_LEHRFACH_ANZEIGEN)
{
// Wenn der eingeloggte User zu einer der Lehreinheiten zugeteilt ist
// wird zusätzlich das Lehrfach der Lehreinheit angezeigt.
if($is_lector )
{
$result = $this->Lehreinheit_model->getLehrfachIdMitarbeiter($angezeigtes_stsem,$user,$lvid);
}
else
{
$result = $this->Lehreinheit_model->getLehrfachIdStudierender($angezeigtes_stsem,$user,$lvid);
}
// Wenn die LV mehrere verschiedenen Lehrfaecher hat, und der User zu mehreren davon zugeteilt ist
// wird das Lehrfach nicht angezeigt damit es nicht zu verwirrungen kommt.
if( ($lehrfaecher = getData($result)) && count($lehrfaecher)==1 && ($lehrfach = $lehrfaecher[0]))
{
$lehrfach_id=$lehrfach->lehrfach_id;
}
}
// lektor der lv
$lektor_der_lv=false;
$leinfores = $this->Lehreinheit_model->getLehreinheitInfo($lvid,$angezeigtes_stsem,$lehrfach_id);
$db_result = hasData($leinfores) ? getData($leinfores) : array();
foreach($db_result as $row_lector)
{
// Lektor wird erst angezeigt wenn der Auftrag erteilt wurde
if (defined('CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON')
&& CIS_LV_LEKTORINNENZUTEILUNG_VERTRAGSPRUEFUNG_VON != '')
{
if (!$this->Vertrag_model->isVertragErteiltLV($lvid, $angezeigtes_stsem, $row_lector->uid))
{
continue;
}
}
if($user == $row_lector->uid)
{
$lektor_der_lv=true;
$user_is_allowed_to_upload=true;
}
// style of the link
if($row_lector->lvleiter === true)
$style='style="font-weight: bold"';
else
$style='';
}
//Berechtigungen auf Fachbereichsebene
$lehrfach_oe_kurzbz_arr = array();
$fbres = $this->Lehrveranstaltung_model->getBerechtigungenAufFachberechsebene($lvid, $angezeigtes_stsem);
$fbs = (hasData($fbres)) ? getData($fbres) : array();
foreach($fbs as $row)
{
$lehrfach_oe_kurzbz_arr[] = $row->oe_kurzbz;
if($this->PermissionLib->isBerechtigt('lehre', null, $row->oe_kurzbz)
|| $this->PermissionLib->isBerechtigt('assistenz', null, $stg->oe_kurzbz))
{
$user_is_allowed_to_upload=true;
}
}
// FH-Core Menu Logic
// ##########################################################################################
$menu = array();
$this->fhc_menu_lvinfo($menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr);
$this->fhc_menu_feedback($menu, $angemeldet, $lvid);
$this->fhc_menu_gesamtnote($menu, $angemeldet, $lvid, $lv, $is_lector, $angezeigtes_stsem);
$this->fhc_menu_emailStudierende($menu, $user, $angemeldet, $lvid, $angezeigtes_stsem);
$this->fhc_menu_abmeldung($menu, $user, $is_lector, $lvid, $angezeigtes_stsem);
$this->fhc_menu_lehretools($menu, $lvid, $angezeigtes_stsem, $sprache);
$this->fhc_menu_anrechnungStudent($menu, $lvid, $angezeigtes_stsem);
$this->fhc_menu_anrechnungLector($menu, $angezeigtes_stsem);
// Addons Menu Logic
// ##########################################################################################
$params = [
'sprache'=>$sprache,
//'p'=>$p,
'ci_p'=> $this->p,
//'db'=>$db,
'user'=>$user,
'is_lector'=>$is_lector,
'user_is_allowed_to_upload'=>$user_is_allowed_to_upload,
//'rechte'=>$rechte,
'angezeigtes_stsem'=>$angezeigtes_stsem,
//'lehreinheit'=>$lehreinheit,
'lv_obj'=>$lv,
'lv'=>$lv,
'lvid'=>$lvid,
'studiengang_kz'=>$studiengang_kz,
'semester'=>$semester,
'short'=>$short,
'stg_obj'=>$stg,
'kurzbz'=>$kurzbz,
'short_name'=>$short_name,
'short_short_name'=>$short_short_name,
//'dir_name'=>$dir_name,
'angemeldet'=>$angemeldet,
'lehrfach_id'=>$lehrfach_id,
'lektor_der_lv'=>$lektor_der_lv,
'lehrfach_oe_kurzbz_arr'=>$lehrfach_oe_kurzbz_arr,
];
Events::trigger('lvMenuBuild',
// passing $menu per reference
function & () use (&$menu) {
return $menu;
},
$params
);
// Menu sortieren
// ##########################################################################################
foreach ($menu as $key => $row){
// removes menu points that are not needed in the c4 lvUebersicht
if( !array_key_exists('c4_link',$row) || !array_key_exists('c4_icon',$row)){
unset($menu[$key]);
continue;
}
// fills pos array to sort the menu
$pos[$key] = $row['position'];
}
array_multisort($pos, SORT_ASC, SORT_NUMERIC, $menu);
// HTTP response
// ##########################################################################################
$this->terminateWithSuccess($menu);
}
private function fhc_menu_digitale_anwesenheiten(&$menu, $angemeldet, $studiengang_kz, $semester, $lvid, $angezeigtes_stsem){
// DIGITALE ANWESENHEITEN
if (defined('CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN') && CIS_LEHRVERANSTALTUNG_ANWESENHEIT_ANZEIGEN && $angemeldet) {
$menu[] = array
(
'id' => 'core_menu_digitale_anwesenheitslisten',
'position' => '50',
'name' => $this->p->t('lehre', 'digiAnw'),
'c4_icon' => base_url('skin/images/button_kreuzerltool.png'),
'c4_link' => base_url("index.ci.php/extensions/FHC-Core-Anwesenheiten/?stg_kz=$studiengang_kz&sem=$semester&lvid=$lvid&sem_kurzbz=$angezeigtes_stsem&nav=false"),
'c4_linkList' => []
);
}
}
private function fhc_menu_lvinfo(&$menu, $lvid, $studiengang_kz, $lektor_der_lv, $is_lector, $lehrfach_oe_kurzbz_arr){
// LVINFO
if(!defined('CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_LVINFO_ANZEIGEN)
{
$c4_linkList=array();
// Bearbeiten Button anzeigen wenn Lektor der LV und bearbeiten fuer Lektoren aktiviert ist
// Oder Berechtigung zum Bearbeiten eingetragen ist
if((!defined('CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT') && $lektor_der_lv)
|| (defined('CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT') && CIS_LEHRVERANSTALTUNG_LVINFO_LEKTOR_EDIT==true && $lektor_der_lv)
|| $this->PermissionLib->isBerechtigt('lehre/lvinfo',$studiengang_kz)
|| $this->PermissionLib->isBerechtigtMultipleOe('lehre/lvinfo', $lehrfach_oe_kurzbz_arr)
)
{
$c4_linkList[]= [$this->p->t('lehre', 'lvInfoBearbeiten'), 'ects/index.php?lvid='.$lvid];
}
elseif ($is_lector)
{
$c4_linkList[]= ["Bearbeiten der LV-Infos derzeit gesperrt",'#'];
}
$menu[]=array
(
'id'=>'core_menu_lvinfo',
'position'=>'10',
'name'=>$this->p->t('lehre', 'lehrveranstaltungsinformation'),
'icon'=>'../../../skin/images/button_lvinfo.png',
'link'=>'',
'c4_icon'=> base_url('skin/images/button_lvinfo.png'),
'c4_link'=>'',
'c4_linkList'=>$c4_linkList
);
}
}
private function fhc_menu_feedback(&$menu, $angemeldet, $lvid){
//FEEDBACK
if((!defined('CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_FEEDBACK_ANZEIGEN) && $angemeldet)
{
$menu[]=array
(
'id'=>'core_menu_feedback',
'position'=>'60',
'name'=>$this->p->t('lehre', 'feedback'),
'c4_icon'=> base_url('skin/images/button_feedback.png'),
'c4_link'=> base_url('feedback.php?lvid='.$lvid),
);
}
}
private function fhc_menu_gesamtnote(&$menu, $angemeldet, $lvid, $lv_obj, $is_lector, $angezeigtes_stsem){
//Gesamtnote
if($is_lector && ((!defined('CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_GESAMTNOTE_ANZEIGEN) && $angemeldet))
{
if($lv_obj->benotung)
{
$menu[]=array
(
'id'=>'core_menu_gesamtnote',
'position'=>'80',
'name'=>$this->p->t('lehre', 'gesamtnote'),
'c4_icon'=> base_url('skin/images/button_endnote.png'),
'c4_link'=> base_url('cis/private/lehre/benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
//'c4_link'=> base_url('benotungstool/lvgesamtnoteverwalten.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem))
);
}
else
{
$menu[]=array
(
'id'=>'core_menu_gesamtnote',
'position'=>'80',
'name'=>$this->p->t('lehre', 'gesamtnote'),
'c4_icon'=>base_url('skin/images/button_endnote.png'),
'c4_link'=>'#',
'c4_linkList'=>[[$this->p->t('lehre', 'noteneingabedeaktiviert'),'#']],
);
}
}
}
private function fhc_menu_emailStudierende(&$menu, $user, $angemeldet, $lvid, $angezeigtes_stsem){
// Email an Studierende
if((!defined('CIS_LEHRVERANSTALTUNG_MAILSTUDIERENDE_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_MAILSTUDIERENDE_ANZEIGEN) && $angemeldet)
{
$mailto='mailto:';
$c4_linkList=array();
$studentMailsRes = $this->Lehrveranstaltung_model->getStudentEMail($lvid, $angezeigtes_stsem);
// get the data of the database result and map the array of objects to their object property
$studentMails = $this->getDataOrTerminateWithError($studentMailsRes, 'No student mails found');
$nomail='';
$variablesres = $this->Variable_model->getVariables($user);
$variables = (hasData($variablesres)) ? getData($variablesres) : array();
foreach ($studentMails as $row)
{
if($row->gruppe_kurzbz != '')
{
$bngrp_uids = $this->Benutzergruppe_model->getUids($row->gruppe_kurzbz, $angezeigtes_stsem);
if(count($bngrp_uids) > 0)
{
if(!$row->mailgrp)
{
$nomail = $row->gruppe_kurzbz . ' ';
}
else
{
$mailto .= mb_strtolower($row->gruppe_kurzbz . '@'
. DOMAIN . $variables['emailadressentrennzeichen']);
}
}
}
else
{
$mailto .= mb_strtolower($row->stg_typ . $row->stg_kurzbz
. $row->semester . trim($row->verband) . trim($row->gruppe)
. '@' . DOMAIN . $variables['emailadressentrennzeichen']);
}
}
if($nomail != '')
{
$c4_linkList[] = array(
$this->p->t('lehre', 'keinMailverteiler', array('nomail' => $nomail)),
'#'
);
$link_onclick = 'alert(\''.$this->p->t('lehre', 'keinMailverteiler', array('nomail' => $nomail)) . '\');';
}
else
{
$link_onclick = '';
}
$menu[]=array
(
'id'=>'core_menu_mailanstudierende',
'position'=>'100',
'name'=>$this->p->t('lehre', 'mail'),
'c4_icon'=>base_url('skin/images/button_feedback.png'),
'c4_icon2' => 'fa-regular fa-envelope',
'c4_link'=>$mailto,
'c4_linkList'=>$c4_linkList,
'link_onclick'=>$link_onclick
);
}
}
private function fhc_menu_abmeldung(&$menu, $user, $is_lector, $lvid, $angezeigtes_stsem){
if(!defined('CIS_LEHRVERANSTALTUNG_ABMELDUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ABMELDUNG_ANZEIGEN)
{
if(!$is_lector)
{
$gruppen = $this->Lvangebot_model->AbmeldungMoeglich($lvid, $angezeigtes_stsem, $user);
if(count($gruppen) > 0)
{
$menu[]=array
(
'id'=>'core_menu_abmeldung',
'position'=>'120',
'name'=>$this->p->t('lehre', 'abmelden'),
'c4_icon'=>base_url('skin/images/button_studiupload.png'),
'c4_link'=>base_url('abmeldung.php?lvid='.urlencode($lvid).'&stsem='.urlencode($angezeigtes_stsem)),
);
}
}
}
}
private function fhc_menu_lehretools(&$menu, $lvid, $angezeigtes_stsem, $sprache){
//Anzeigen von zusaetzlichen Lehre-Tools
$lehretools = $this->Lehretools_model->getTools($lvid, $angezeigtes_stsem, $sprache);
foreach($lehretools as $row)
{
$menu[] = array(
'id' => 'core_menu_lehretools_' . $row->lehre_tools_id,
'position' => '1000',
'name' => $row->bezeichnung,
'c4_icon' => base_url('cms/dms.php?id='.$row->logo_dms_id),
'c4_link' => $row->basis_url,
);
}
}
private function fhc_menu_anrechnungStudent(&$menu, $lvid, $angezeigtes_stsem){
// Anerkennung nachgewiesener Kenntnisse (Anrechnung) - Anzeige fuer Studenten
if((!defined('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN)
&& $this->PermissionLib->isBerechtigt('student/anrechnung_beantragen'))
{
$menu[]=array
(
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse',
'position' => '128',
'name' => $this->p->t('lehre', 'anrechnung'),
'c4_icon' => base_url('skin/images/button_listen.png'),
'c4_icon2' => 'fa-regular fa-folder-open',
'c4_link' => base_url('cis.php/lehre/anrechnung/RequestAnrechnung?studiensemester='.urlencode($angezeigtes_stsem).'&lv_id='.urlencode($lvid))
);
}
}
private function fhc_menu_anrechnungLector(&$menu, $angezeigtes_stsem){
// Anerkennung nachgewiesener Kenntnisse (Anrechnung) - Anzeige fuer LektorInnen
if((!defined('CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN') || CIS_LEHRVERANSTALTUNG_ANRECHNUNG_ANZEIGEN)
&& $this->PermissionLib->isBerechtigt('lehre/anrechnung_empfehlen'))
{
$menu[]=array
(
'id' => 'core_menu_anerkennungNachgewiesenerKenntnisse_empfehlen',
'position' => '128',
'name' => $this->p->t('lehre', 'anrechnungen'),
'c4_icon'=> base_url('skin/images/button_listen.png'),
'c4_icon2' => 'fa-regular fa-folder-open',
'c4_link' => base_url('cis.php/lehre/anrechnung/ReviewAnrechnungUebersicht?studiensemester='.urlencode($angezeigtes_stsem))
);
}
}
}
@@ -0,0 +1,101 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the NavigationLib (back-end)
* Provides data to the ajax get calls about the filter
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Navigation extends FHCAPI_Controller
{
const NAVIGATION_PAGE_PARAM = 'navigation_page'; // Navigation page parameter name
/**
* Loads the NavigationLib where the used logic lies
*/
public function __construct()
{
parent::__construct([
'menu' => self::PERM_LOGGED,
'header' => self::PERM_LOGGED
]);
$this->_loadNavigationLib(); // Loads the NavigationLib with parameters
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* This function creates the left Menu for each Page
* @param NAVIGATION_PAGE_PARAM GET Parameter witch holds the currently called Page
* @return JSON object with the Menu Entries
*/
public function menu()
{
$menuArray = $this->navigationlib->getMenuArray($this->input->get(self::NAVIGATION_PAGE_PARAM));
$this->terminateWithSuccess($menuArray);
}
/**
* This function creates the Top Menu for each Page
* @param NAVIGATION_PAGE_PARAM GET Parameter witch holds the currently called Page
* @return JSON object with the Menu Entries
*/
public function header()
{
$headerArray = $this->navigationlib->getHeaderArray($this->input->get(self::NAVIGATION_PAGE_PARAM));
$this->terminateWithSuccess($headerArray);
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Loads the NavigationLib with the NAVIGATION_PAGE_PARAM parameter
* If the parameter NAVIGATION_PAGE_PARAM is not given then the execution of the controller is terminated and
* an error message is printed
*/
private function _loadNavigationLib()
{
// If the parameter NAVIGATION_PAGE_PARAM is present in the HTTP GET or POST
if (isset($_GET[self::NAVIGATION_PAGE_PARAM]) || isset($_POST[self::NAVIGATION_PAGE_PARAM]))
{
// If it is present in the HTTP GET
if (isset($_GET[self::NAVIGATION_PAGE_PARAM]))
{
$navigationPage = $this->input->get(self::NAVIGATION_PAGE_PARAM); // is retrieved from the HTTP GET
}
elseif (isset($_POST[self::NAVIGATION_PAGE_PARAM])) // Else if it is present in the HTTP POST
{
$navigationPage = $this->input->post(self::NAVIGATION_PAGE_PARAM); // is retrieved from the HTTP POST
}
// Loads the NavigationLib that contains all the used logic
$this->load->library('NavigationLib', array(self::NAVIGATION_PAGE_PARAM => $navigationPage));
}
else // Otherwise an error will be written in the output
{
show_error('Parameter "' . self::NAVIGATION_PAGE_PARAM . '" not provided!');
}
}
}
@@ -0,0 +1,95 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class Ort extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
// NOTE(chris): additional permission checks will be done in SearchBarLib
parent::__construct([
'ContentID' => self::PERM_LOGGED,
'getOrtKurzbzContent' => self::PERM_LOGGED,
]);
$this->load->model('ressource/Ort_model', 'OrtModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
public function ContentID()
{
// if error
//$this->terminateWithError(SearchBarLib::ERROR_WRONG_JSON, self::ERROR_TYPE_GENERAL);
$ort_kurzbz = $this->input->get('ort_kurzbz',TRUE);
if(!$ort_kurzbz){
$this->terminateWithError("missing ort_kurzbz parameter", self::ERROR_TYPE_GENERAL);
}
$result = $this->OrtModel->getContentID($ort_kurzbz);
if(isError($result)){
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$result = hasData($result) ? current(getData($result)) : null;
$this->terminateWithSuccess($result->content_id ?? NULL);
}
/**
* @param int $version
* @param string $sprache
* @param boolean $sichtbar
*
* @return $content
*/
public function getOrtKurzbzContent($version = null, $sprache = null, $sichtbar = true)
{
$content_id = $this->input->get("content_id",TRUE);
$this->load->library('CmsLib');
$content = $this->cmslib->getContent($content_id, $version, $sprache, $sichtbar);
if (isError($content))
$this->terminateWithError(getError($content), self::ERROR_TYPE_GENERAL);
$content = hasData($content) ? getData($content) : null;
$this->terminateWithSuccess($content);
}
}
@@ -0,0 +1,84 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the PhrasesLib (back-end)
* Provides data to the ajax get calls about the Phrasen plugin
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class Phrasen extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'loadModule' => self::PERM_ANONYMOUS,
'setLanguage' => self::PERM_ANONYMOUS,
'getLanguage' => self::PERM_ANONYMOUS,
'getAllLanguages' => self::PERM_ANONYMOUS,
]);
$this->load->helper('hlp_language');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* @param string $module
*/
public function loadModule($module)
{
$this->load->library('PhrasesLib', [$module], 'pj');
$this->terminateWithSuccess(json_decode($this->pj->getJSON()));
}
public function setLanguage()
{
$postParams = $this->getPostJSON();
$language = $postParams->language;
$categories = $postParams->categories;
setUserLanguage($language);
$this->load->library('PhrasesLib', array($categories, $language), 'p');
$phrases = $this->p->setPhrases($categories, $language);
$this->terminateWithSuccess($phrases);
}
// gets the langauge of the currently logged in user session and otherwhise the system language
public function getLanguage()
{
$lang = getUserLanguage();
$this->terminateWithSuccess($lang);
}
// gets all languages that are set as active in the database
public function getAllLanguages()
{
$langs = getDBActiveLanguages();
$langs = $this->getDataOrTerminateWithError($langs);
$langs = array_map(function($lang){
return $lang->sprache;
}, $langs);
$this->terminateWithSuccess($langs);
}
}
@@ -0,0 +1,695 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Profil extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getView' => self::PERM_LOGGED,
'fotoSperre' => self::PERM_LOGGED,
'getGemeinden' => self::PERM_LOGGED,
'getAllNationen' => self::PERM_LOGGED,
'isMitarbeiter' => self::PERM_LOGGED,
]);
$this->load->library('PermissionLib');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->load->model('person/Benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('content/DmsVersion_model', 'DmsVersionModel');
//? put the uid and pid inside the controller for reusability
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* function that returns the data used for the corresponding view
* the client side parses the @param $uid and calls this function to get the data to the correct view
* @access public
* @param boolean $uid the userID used to identify which information should be retrieved for which view
* @return stdClass all the data corresponding to a view of a user
*/
public function getView($uid)
{
$res = new stdClass();
$editAllowed = getAuthUID() == $uid || $this->permissionlib->isBerechtigt('admin');
// if parsing the URL did not found a UID then the UID of the logged in user is used
if ($uid == "Profil" || $uid == $this->uid) {
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($this->uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $this->uid . " is a mitarbeiter");
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "MitarbeiterProfil";
$res->data = $this->mitarbeiterProfil();
$res->data->pid = $this->pid;
} else {
$res->view = "StudentProfil";
$res->data = $this->studentProfil();
$res->data->pid = $this->pid;
}
// editing your own profil - true
$editAllowed = true;
}
// UID is availabe when accessing Profil/View/:uid
else {
$this->PersonModel->addSelect(["person_id"]);
$pid = $this->PersonModel->getByUid($uid);
if (isError($pid)) {
show_error("error while trying to update table public.tbl_person while searching for a person with UID: " . $uid);
}
$pid = hasData($pid) ? getData($pid)[0] : null;
if (!$pid) {
show_error("Person with UID: " . $uid . " does not exist");
}
$isMitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($isMitarbeiter)) {
show_error("error while checking if UID: " . $uid . " is a mitarbeiter");
}
$isMitarbeiter = getData($isMitarbeiter);
if ($isMitarbeiter) {
$res->view = "ViewMitarbeiterProfil";
$res->data = $this->viewMitarbeiterProfil($uid);
} else {
$res->view = "ViewStudentProfil";
$res->data = $this->viewStudentProfil($uid);
}
}
$res->data->editAllowed = $editAllowed;
$this->terminateWithSuccess($res);
}
/**
* update column foto_sperre in public.tbl_person
* @access public
* @param boolean $value new value for the column
* @return boolean the new value added to the column in public.tbl_person
*/
public function fotoSperre($value)
{
if(!isset($value)){
$this->terminateWithError("Missing parameter", self::ERROR_TYPE_GENERAL);
}
$res = $this->PersonModel->update($this->pid, ["foto_sperre" => $value]);
if (isError($res)) {
show_error("error while trying to update table public.tbl_person");
}
$this->PersonModel->addSelect("foto_sperre");
$res = $this->PersonModel->load($this->pid);
if (isError($res)) {
show_error("error while trying to query table public.tbl_person");
}
$res = $this->getDataOrTerminateWithError($res);
$this->terminateWithSuccess(current($res));
}
/**
* gets all nations in the table bis.tbl_nation
*
* @access public
* @return array all the nations in table bis.tbl_nation
*/
public function getAllNationen()
{
// load the nationen from the database
$this->load->model('codex/Nation_model', "NationModel");
$this->NationModel->addSelect(["nation_code as code", "langtext"]);
$nation_res = $this->NationModel->load();
if (isError($nation_res)) {
$this->terminateWithError("error while trying to query table codex.tbl_nation", self::ERROR_TYPE_GENERAL);
}
$nation_res = $this->getDataOrTerminateWithError($nation_res);
$this->terminateWithSuccess($nation_res);
}
public function getGemeinden($nation, $zip)
{
if(!isset($nation) || !isset($zip)){
echo json_encode(error("Missing parameters"));
return;
}
$this->load->model('codex/Gemeinde_model', "GemeindeModel");
$gemeinde_res = $this->GemeindeModel->getGemeindeByPlz($zip);
if (isError($gemeinde_res)) {
$this->terminateWithError(getError($gemeinde_res),self::ERROR_TYPE_GENERAL);
}
$gemeinde_res = $this->getDataOrTerminateWithError($gemeinde_res);
/* $gemeinde_res = array_map(function ($obj) {
return $obj->ortschaftsname;
}, $gemeinde_res); */
$this->terminateWithSuccess($gemeinde_res);
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* function that returns the data used for viewing another mitarbeiter profile
* @access private
* @param integer $uid the userID to retrieve the mitarbeiter data
* @return stdClass restricted mitarbeiter data
*/
private function viewMitarbeiterProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$benutzer_funktion_res = $this->getBenutzerFunktion($uid);
$benutzer_res = $this->getBenutzerAlias($uid);
$person_res = $this->getPersonInfo($uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($uid);
$telefon_res = $this->getTelefonInfo($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Info
foreach ($person_res as $key => $val) {
$res->$key = $val;
}
//? Mitarbeiter Info
foreach ($mitarbeiter_res as $key => $val) {
$res->$key = $val;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $benutzer_res->alias . "@" . DOMAIN;
$res->emails = array($intern_email, $extern_email);
$res->funktionen = $benutzer_funktion_res;
$res->mailverteiler = $mailverteiler_res;
$res->standort_telefon = isset($telefon_res) ? $telefon_res->kontakt : null;
return $res;
}
/**
* function that returns the data used for viewing another student profile
* @access private
* @param integer $uid the userID to retrieve the student data
* @return stdClass restricted student data
*/
private function viewStudentProfil($uid)
{
$mailverteiler_res = $this->getMailverteiler($uid);
$person_res = $this->getPersonInfo($uid);
$student_res = $this->getStudentInfo($uid);
$matr_res = $this->getMatrikelNummer($uid);
$res = new stdClass();
$res->username = $uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = $value;
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->matrikelnummer = $matr_res->matr_nr;
$res->mailverteiler = $mailverteiler_res;
return $res;
}
/**
* checks whether a specific userID is a mitarbeiter or not (foreword declaration of the function isMitarbeiter in Mitarbeiter_model.php)
* @access public
* @param $uid the userID used to check if it is a mitarbeiter
* @return boolean
*/
public function isMitarbeiter($uid)
{
if(!$uid) $this->terminateWithError("No uid provided", self::ERROR_TYPE_GENERAL);
$result = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($result)) {
$this->terminateWithError("error when calling Mitarbeiter_model function isMitarbeiter with uid " . $uid, self::ERROR_TYPE_GENERAL);
}
$result = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($result);
}
/**
* function that returns the data used for the mitarbeiter profile
* @access private
* @return stdClass mitarbeiter data
*/
private function mitarbeiterProfil()
{
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$benutzer_funktion_res = $this->getBenutzerFunktion($this->uid);
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$telefon_res = $this->getTelefonInfo($this->uid);
$mitarbeiter_res = $this->getMitarbeiterInfo($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Mitarbeiter Information
foreach ($mitarbeiter_res as $key => $value) {
$res->$key = $value;
}
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->mailverteiler = $mailverteiler_res;
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$extern_email = array();
$extern_email["type"] = "alias";
$extern_email["email"] = $mitarbeiter_res->alias . "@" . DOMAIN;
$res->emails = [$intern_email, $extern_email];
$res->funktionen = $benutzer_funktion_res;
$res->standort_telefon = $telefon_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* function that returns the data used for the student profile
* @access private
* @return stdClass student data
*/
private function studentProfil()
{
$betriebsmittelperson_res = $this->getBetriebsmittelInfo($this->pid);
$kontakte_res = $this->getKontaktInfo($this->pid);
$zutrittskarte_ausgegebenam = $this->getZutrittskarteDatum($this->uid);
$adresse_res = $this->getAdressenInfo($this->pid);
$mailverteiler_res = $this->getMailverteiler($this->uid);
$person_res = $this->getPersonInfo($this->uid, true);
$zutrittsgruppe_res = $this->getZutrittsgruppen($this->uid);
$student_res = $this->getStudentInfo($this->uid);
$matr_res = $this->getMatrikelNummer($this->uid);
$profilUpdates = $this->getProfilUpdates($this->uid);
$res = new stdClass();
$res->username = $this->uid;
//? Person Information
foreach ($person_res as $key => $value) {
$res->$key = $value;
}
//? Student Information
foreach ($student_res as $key => $value) {
$res->$key = trim($value);
}
$intern_email = array();
$intern_email["type"] = "intern";
$intern_email["email"] = $this->uid . "@" . DOMAIN;
$res->emails = [$intern_email];
$res->adressen = $adresse_res;
$res->zutrittsdatum = $zutrittskarte_ausgegebenam;
$res->kontakte = $kontakte_res;
$res->mittel = $betriebsmittelperson_res;
$res->matrikelnummer = $matr_res->matr_nr;
$res->zuttritsgruppen = $zutrittsgruppe_res;
$res->mailverteiler = $mailverteiler_res;
$res->profilUpdates = $profilUpdates;
return $res;
}
/**
* gets all the mailverteiler using the tables: tbl_benutzer, tbl_benutzergruppe, tbl_gruppe
* @access private
* @param integer $uid the userID used to retrieve the mailverteiler
* @return array returns the mailvertailer corresponding to a userID
*/
private function getMailverteiler($uid)
{
$this->PersonModel->addSelect('gruppe_kurzbz, beschreibung');
$this->PersonModel->addJoin('tbl_benutzer', 'person_id');
$this->PersonModel->addJoin('tbl_benutzergruppe', 'uid');
$this->PersonModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$mailverteiler_res = $this->PersonModel->loadWhere(array('mailgrp' => true, 'uid' => $uid));
if (isError($mailverteiler_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($mailverteiler_res));
}
$mailverteiler_res = hasData($mailverteiler_res) ? getData($mailverteiler_res) : null;
$mailverteiler_res = array_map(function ($element) {
$element->mailto = "mailto:" . $element->gruppe_kurzbz . "@" . DOMAIN;
return $element;
}, $mailverteiler_res);
return $mailverteiler_res;
}
/**
* gets all the Benutzerfunktionen of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Benutzerfunktionen
* @return array returns the Benutzerfunktionen corresponding to a userID
*/
private function getBenutzerFunktion($uid)
{
$this->BenutzerfunktionModel->addSelect(["tbl_benutzerfunktion.bezeichnung as Bezeichnung", "tbl_organisationseinheit.bezeichnung as Organisationseinheit", "datum_von as Gültig_von", "datum_bis as Gültig_bis", "wochenstunden as Wochenstunden"]);
$this->BenutzerfunktionModel->addJoin("tbl_organisationseinheit", "oe_kurzbz");
$benutzer_funktion_res = $this->BenutzerfunktionModel->loadWhere(array('uid' => $uid));
if (isError($benutzer_funktion_res)) {
show_error("was not able to query the table public.tbl_benutzerfunktion:" . getData($benutzer_funktion_res));
}
$benutzer_funktion_res = hasData($benutzer_funktion_res) ? getData($benutzer_funktion_res) : null;
return $benutzer_funktion_res;
}
/**
* gets all the Betriebsmittel of a corresponding user
* @access private
* @param integer $uid the userID used to retrieve the Betriebsmittel
* @return array returns the Betriebsmittel corresponding to a userID
*/
private function getBetriebsmittelInfo($pid)
{
$this->BetriebsmittelpersonModel->addSelect(["CONCAT(betriebsmitteltyp, ' ' ,beschreibung) as Betriebsmittel", "nummer as Nummer", "ausgegebenam as Ausgegeben_am"]);
//? betriebsmittel are not needed in a view
$betriebsmittelperson_res = $this->BetriebsmittelpersonModel->getBetriebsmittel($pid);
if (isError($betriebsmittelperson_res)) {
show_error("was not able to query the table public.tbl_betriebsmittelperson:" . getData($betriebsmittelperson_res));
}
$betriebsmittelperson_res = hasData($betriebsmittelperson_res) ? getData($betriebsmittelperson_res) : null;
return $betriebsmittelperson_res;
}
/**
* gets the alias of a corresponding user
* @access private
* @param integer $uid the userID used to get the alias
* @return string the alias of the userID
*/
private function getBenutzerAlias($uid)
{
$this->BenutzerModel->addSelect(["alias"]);
$benutzer_res = $this->BenutzerModel->load([$uid]);
if (isError($benutzer_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($benutzer_res));
} else {
$benutzer_res = hasData($benutzer_res) ? getData($benutzer_res)[0] : null;
}
return $benutzer_res;
}
/**
* gets the person information corresponding to a user
* @access private
* @param integer $uid the userID used to get the person information
* @param integer $geburtsInfo flag wether to add the columns gebort, gebdatum, foto_sperre or not
* @return array all the person informaion corresponding to a userID
*/
private function getPersonInfo($uid, $geburtsInfo = null)
{
$selectClause = ["foto", "foto_sperre", "anrede", "titelpost as postnomen", "titelpre as titel", "vorname", "nachname"];
/** @param integer $geburtsInfo */
if ($geburtsInfo) {
array_push($selectClause, "gebort");
array_push($selectClause, "gebdatum");
}
$this->BenutzerModel->addSelect($selectClause);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$person_res = $this->BenutzerModel->load([$uid]);
if (isError($person_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($person_res));
} else {
$person_res = hasData($person_res) ? getData($person_res)[0] : null;
}
if( ($person_res->foto === null) || (($this->uid !== $uid) && ($person_res->foto_sperre !== false)) )
{
$dummy_foto = base64_encode(file_get_contents(DOC_ROOT.'skin/images/profilbild_dummy.jpg'));
$person_res->foto = $dummy_foto;
}
return $person_res;
}
/**
* gets the mitarbeiter information corresponding to a user
* @access private
* @param integer $uid the userID used to get the mitarbeiter information
* @return array all the mitarbeiter informaion corresponding to a userID
*/
private function getMitarbeiterInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kurzbz", "telefonklappe", "alias", "ort_kurzbz"]);
$this->MitarbeiterModel->addJoin("tbl_benutzer", "tbl_benutzer.uid = tbl_mitarbeiter.mitarbeiter_uid");
$mitarbeiter_res = $this->MitarbeiterModel->load($uid);
if (isError($mitarbeiter_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($mitarbeiter_res));
} else {
$mitarbeiter_res = hasData($mitarbeiter_res) ? getData($mitarbeiter_res)[0] : null;
}
return $mitarbeiter_res;
}
/**
* gets the telefon information corresponding to a user
* @access private
* @param integer $uid the userID used to get the telefon information
* @return array all the telefon informaion corresponding to a userID
*/
private function getTelefonInfo($uid)
{
$this->MitarbeiterModel->addSelect(["kontakt"]);
$this->MitarbeiterModel->addJoin("tbl_kontakt", "tbl_mitarbeiter.standort_id = tbl_kontakt.standort_id");
$this->MitarbeiterModel->addLimit(1);
$telefon_res = $this->MitarbeiterModel->loadWhere(["mitarbeiter_uid" => $uid, "kontakttyp" => "telefon"]);
if (isError($telefon_res)) {
show_error("was not able to query the table public.tbl_mitarbeiter:" . getData($telefon_res));
}
$telefon_res = hasData($telefon_res) ? getData($telefon_res)[0] : null;
return $telefon_res;
}
/**
* gets the student information corresponding to a user
* @access private
* @param integer $uid the userID used to get the student information
* @return array all the student informaion corresponding to a userID
*/
private function getStudentInfo($uid)
{
$this->StudentModel->addSelect(['tbl_studiengang.bezeichnung as studiengang', 'tbl_student.semester', 'tbl_student.verband', 'tbl_student.gruppe', 'tbl_student.matrikelnr as personenkennzeichen']);
$this->StudentModel->addJoin('tbl_studiengang', "tbl_studiengang.studiengang_kz=tbl_student.studiengang_kz");
$student_res = $this->StudentModel->load([$uid]);
if (isError($student_res)) {
show_error("was not able to query the table public.tbl_student:" . getData($student_res));
}
$student_res = hasData($student_res) ? getData($student_res)[0] : null;
return $student_res;
}
/**
* gets the profil updates corresponding to a user
* @access private
* @param integer $uid the userID used to get the profil updates
* @return array all the profil updates corresponding to a userID
*/
private function getProfilUpdates($uid)
{
$profilUpdates = $this->ProfilUpdateModel->getProfilUpdatesWhere(['uid' => $uid]);
if (isError($profilUpdates)) {
show_error("was not able to query the table public.tbl_profil_update:" . getData($profilUpdates));
}
$profilUpdates = hasData($profilUpdates) ? getData($profilUpdates) : null;
return $profilUpdates;
}
/**
* gets the Matrikelnummer corresponding to a user
* @access private
* @param integer $uid the userID used to get the Matrikelnummer
* @return integer the Matrikelnummer corresponding to a userID
*/
private function getMatrikelNummer($uid)
{
$this->BenutzerModel->addSelect(["matr_nr"]);
$this->BenutzerModel->addJoin("tbl_person", "person_id");
$matr_res = $this->BenutzerModel->load([$uid]);
if (isError($matr_res)) {
show_error("was not able to query the table public.tbl_benutzer:" . getData($matr_res));
}
$matr_res = hasData($matr_res) ? getData($matr_res)[0] : [];
return $matr_res;
}
/**
* gets the Zutrittsgruppen corresponding to a user
* @access private
* @param integer $uid the userID used to get the Zutrittsgruppen
* @return array all the Zutrittsgruppen corresponding to a userID
*/
private function getZutrittsgruppen($uid)
{
$this->BenutzergruppeModel->addSelect(['bezeichnung']);
$this->BenutzergruppeModel->addJoin('tbl_gruppe', 'gruppe_kurzbz');
$zutrittsgruppe_res = $this->BenutzergruppeModel->loadWhere(array("uid" => $uid, "zutrittssystem" => true));
if (isError($zutrittsgruppe_res)) {
show_error("was not able to query the table public.tbl_benutzergruppe:" . getData($zutrittsgruppe_res));
}
$zutrittsgruppe_res = hasData($zutrittsgruppe_res) ? getData($zutrittsgruppe_res) : null;
return $zutrittsgruppe_res;
}
/**
* gets the address information corresponding to a user
* @access private
* @param integer $uid the userID used to get the address information
* @return array all the address information corresponding to a userID
*/
private function getAdressenInfo($pid)
{
$adresse_res = $this->AdresseModel->addSelect(["adresse_id", "strasse", "tbl_adressentyp.bezeichnung as typ", "plz", "ort", "zustelladresse", "gemeinde", "nation"]);
$adresse_res = $this->AdresseModel->addOrder("zustelladresse", "DESC");
$adresse_res = $this->AdresseModel->addJoin("tbl_adressentyp", "typ=adressentyp_kurzbz");
$adresse_res = $this->AdresseModel->loadWhere(["person_id" => $pid]);
if (isError($adresse_res)) {
show_error("was not able to query the table public.tbl_adresse:" . getData($adresse_res));
}
$adresse_res = hasData($adresse_res) ? getData($adresse_res) : null;
return $adresse_res;
}
/**
* gets the kontakt information corresponding to a user
* @access private
* @param integer $uid the userID used to get the kontakt information
* @return array all the kontakt information corresponding to a userID
*/
private function getKontaktInfo($pid)
{
$this->KontaktModel->addSelect(['kontakttyp', 'kontakt_id', 'kontakt', 'tbl_kontakt.anmerkung', 'tbl_kontakt.zustellung']);
$this->KontaktModel->addJoin('public.tbl_standort', 'standort_id', 'LEFT');
$this->KontaktModel->addJoin('public.tbl_firma', 'firma_id', 'LEFT');
$this->KontaktModel->addOrder('kontakttyp, kontakt, tbl_kontakt.updateamum, tbl_kontakt.insertamum');
$kontakte_res = $this->KontaktModel->loadWhere(['person_id' => $pid]);
if (isError($kontakte_res)) {
show_error("was not able to query the table public.tbl_kontakt:" . getData($kontakte_res));
}
$kontakte_res = hasData($kontakte_res) ? getData($kontakte_res) : null;
return $kontakte_res;
}
/**
* gets the date of issue of the FH access card corresponding to a user
* @access private
* @param integer $uid the userID used to get the date of issue of the FH access card
* @return string the date of issue of the FH access card corresponding to a userID
*/
private function getZutrittskarteDatum($uid)
{
$zutrittskarte_ausgegebenam = $this->BetriebsmittelpersonModel->getBetriebsmittelByUid($uid, "Zutrittskarte");
if (isError($zutrittskarte_ausgegebenam)) {
show_error("was not able to query the table wavi.tbl_bentriebsmittelperson:" . getData($zutrittskarte_ausgegebenam));
}
$zutrittskarte_ausgegebenam = hasData($zutrittskarte_ausgegebenam) ? getData($zutrittskarte_ausgegebenam)[0]->ausgegebenam : null;
//? formats date from 01-01-2000 to 01.01.2000
$zutrittskarte_ausgegebenam = str_replace("-", ".", $zutrittskarte_ausgegebenam);
return $zutrittskarte_ausgegebenam;
}
}
@@ -0,0 +1,837 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class ProfilUpdate extends FHCAPI_Controller
{
public static $STATUS_PENDING = NULL;
public static $STATUS_ACCEPTED = NULL;
public static $STATUS_REJECTED = NULL;
public static $TOPICS = [];
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getStatus' => self::PERM_LOGGED,
'getTopic' => self::PERM_LOGGED,
'getProfilRequestFiles' => self::PERM_LOGGED,
'getProfilUpdateWithPermission' => ['student/stammdaten:r', 'mitarbeiter/stammdaten:r'],
'denyProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'acceptProfilRequest' => ['student/stammdaten:rw', 'mitarbeiter/stammdaten:rw'],
'selectProfilRequest' => self::PERM_LOGGED,
'insertProfilRequest' => self::PERM_LOGGED,
'updateProfilRequest' => self::PERM_LOGGED,
'deleteProfilRequest' => self::PERM_LOGGED,
'insertFile' => self::PERM_LOGGED,
'show' => self::PERM_LOGGED,
]);
$this->load->config('cis');
// Load language phrases
$this->loadPhrases(
array(
'ui',
'global',
'person',
'profil',
'profilUpdate'
)
);
$this->load->model('person/Profil_update_model', 'ProfilUpdateModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('person/Adressentyp_model', 'AdressenTypModel');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->load->model('person/Profil_update_status_model', 'ProfilUpdateStatusModel');
$this->load->model('person/Profil_update_topic_model', 'ProfilUpdateTopicModel');
$this->load->library('DmsLib');
$this->load->library('PermissionLib');
//? put the uid and pid inside the controller for reusability
$this->uid = getAuthUID();
$this->pid = getAuthPersonID();
// setup the ProfilUpdate states
$this->ProfilUpdateStatusModel->addSelect(['status_kurzbz']);
$status_kurzbz = $this->ProfilUpdateStatusModel->load();
if (hasData($status_kurzbz)) {
list($status_pending, $status_accepted, $status_rejected) = getData($status_kurzbz);
self::$STATUS_PENDING = $status_pending->status_kurzbz;
self::$STATUS_ACCEPTED = $status_accepted->status_kurzbz;
self::$STATUS_REJECTED = $status_rejected->status_kurzbz;
}
// setup the ProfilUpdate topics
$this->ProfilUpdateTopicModel->addSelect(['topic_kurzbz']);
$topic_kurzbz = $this->ProfilUpdateTopicModel->load();
if (hasData($topic_kurzbz)) {
foreach (getData($topic_kurzbz) as $topic) {
self::$TOPICS[$topic->topic_kurzbz] = $topic->topic_kurzbz;
}
}
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getStatus()
{
$this->terminateWithSuccess([self::$STATUS_PENDING => self::$STATUS_PENDING, self::$STATUS_ACCEPTED => self::$STATUS_ACCEPTED, self::$STATUS_REJECTED => self::$STATUS_REJECTED]);
}
public function getTopic()
{
if(!count(self::$TOPICS)){
$this->terminateWithError('No topics found');
}
$this->terminateWithSuccess(self::$TOPICS);
}
public function show($dms_id)
{
$profil_update = $this->ProfilUpdateModel->loadWhere(['attachment_id' => $dms_id]);
$profil_update = hasData($profil_update) ? getData($profil_update)[0] : null;
//? checks if an profil update exists with the dms_id requested from the user
if ($profil_update) {
$is_mitarbeiter_profil_update = getData($this->MitarbeiterModel->isMitarbeiter($profil_update->uid));
$is_student_profil_update = getData($this->StudentModel->isStudent($profil_update->uid));
if (
$this->permissionlib->isBerechtigt('student/stammdaten:r') && $is_student_profil_update ||
$this->permissionlib->isBerechtigt('mitarbeiter/stammdaten:r') && $is_mitarbeiter_profil_update ||
$this->uid == $profil_update->uid
) {
// Get file to be downloaded from DMS
$download = $this->dmslib->download($dms_id);
$download = $this->getDataOrTerminateWithError($download);
// Download file
$this->outputFile($download);
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_dms_error'));
}
}
public function selectProfilRequest()
{
$uid = $this->input->get('uid',true);
$id = $this->input->get('id',true);
$whereClause = ['uid' => $this->uid];
if (isset($uid))
$whereClause['uid'] = $uid;
if (isset($id))
$whereClause['id'] = $id;
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere($whereClause);
$res = $this->getDataOrTerminateWithError($res);
$this->terminateWithSuccess($res);
}
public function insertProfilRequest()
{
$payload = $this->input->post('payload');
$topic = $this->input->post('topic',true);
$fileID = $this->input->post('fileID',true);
if(!isset($payload) || !isset($topic)){
$this->terminateWithError("required parameters are missing");
}
$identifier = array_key_exists("kontakt_id", $payload) ? "kontakt_id" : (array_key_exists("adresse_id", $payload) ? "adresse_id" : null);
$data = ["topic" => $topic, "uid" => $this->uid, "requested_change" => json_encode($payload), "insertamum" => "NOW()", "insertvon" => $this->uid, "status" => self::$STATUS_PENDING ?: 'Pending'];
//? insert fileID in the dataset if sent with post request
if (isset($fileID)) {
$data['attachment_id'] = $fileID;
}
//? loops over all updateRequests from a user to validate if the new request is valid
$res = $this->ProfilUpdateModel->getProfilUpdatesWhere(["uid" => $this->uid]);
$res = $this->getDataOrTerminateWithError($res);
//? the user cannot delete a zustelladresse/kontakt
if (isset($payload["delete"]) && $payload[$identifier == "kontakt_id" ? "zustellung" : "zustelladresse"]) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error'));
}
//? if the user tries to delete a adresse, checks whether the adresse is a heimatadresse, if so an error is raised
if (isset($payload["delete"]) && $identifier == "adresse_id") {
$adr = $this->AdresseModel->load($payload[$identifier]);
$adr = $this->getDataOrTerminateWithError($adr)[0];
if ($adr->heimatadresse) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_deleteZustellung_error'));
}
}
if ($res) {
$pending_changes = array_filter($res, function ($element) {
return $element->status == (self::$STATUS_PENDING ?: "Pending");
});
foreach ($pending_changes as $update_request) {
$existing_change = $update_request->requested_change;
//? the user can add as many new kontakte/adressen as he likes
if (!isset($payload["add"]) && property_exists($existing_change, $identifier) && array_key_exists($identifier,$payload) && $existing_change->$identifier == $payload[$identifier]) {
//? the kontakt_id / adresse_id of a change has to be unique
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_changeTwice_error'));
}
//? if it is not updating any kontakt/adresse, the topic has to be unique
elseif (!$identifier && $update_request->topic == $topic) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_changeTopicTwice_error', ['0' => $update_request->topic]));
}
}
}
$insertID = $this->ProfilUpdateModel->insert($data);
if (isError($insertID)) {
$this->terminateWithError(getError($insertID));
} else {
$insertID = hasData($insertID) ? getData($insertID) : null;
//? sends emails to the correspondents of the $uid
$this->sendEmail_onProfilUpdate_insertion($this->uid, $insertID, $topic);
$this->terminateWithSuccess(success($insertID));
}
}
public function updateProfilRequest()
{
$topic = $this->input->post('topic', true);
$payload = $this->input->post('payload', true);
$ID = $this->input->post('ID', true);
$fileID = $this->input->post('fileID', true);//optional
if(!isset($topic) || !isset($payload) || !isset($ID)){
$this->terminateWithError("required parameters are missing");
}
$updateData = ["requested_change" => json_encode($payload), "updateamum" => "NOW()", "updatevon" => $this->uid];
if (isset($fileID)) {
$updateData['attachment_id'] = json_decode($fileID);
}
$updateID = $this->ProfilUpdateModel->update([$ID], $updateData);
//? insert fileID in the dataset if sent with post request
if (isError($updateID)) {
$this->terminateWithError(getError($updateID));
}
$updateID = $this->getDataOrTerminateWithError($updateID)[0];
$this->terminateWithSuccess(success($updateID));
}
public function deleteProfilRequest()
{
$requestID = $this->input->post('requestID', true);
$result = $this->ProfilUpdateModel->delete([$requestID]);
if (isError($result)) {
$this->terminateWithError(getError($result));
}
$this->terminateWithSuccess($result);
}
public function getProfilRequestFiles($id)
{
if(!$id){
$this->terminateWithError("parameter id is missing");
}
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$attachmentID = $this->ProfilUpdateModel->load([$id]);
if (isError($attachmentID)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_loading_error'),self::ERROR_TYPE_GENERAL);
}
//? get the attachmentID
$dms_id = $this->getDataOrTerminateWithError($attachmentID)[0]->attachment_id;
//? get the name to the file
$this->DmsVersionModel->addSelect(["name", "dms_id"]);
$attachment = $this->DmsVersionModel->load([$dms_id, 0]);
if (isError($attachment)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_dmsVersion_error'),self::ERROR_TYPE_GENERAL);
}
$attachment = $this->getDataOrTerminateWithError($attachment);
//? returns {name:..., dms_id:...}
$this->terminateWithSuccess($attachment);
}
public function denyProfilRequest()
{
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
$topic = $this->input->post('topic', true);
$status_message = $this->input->post('status_message', true); //optional
if(!isset($id) || !isset($uid) || !isset($topic)){
$this->terminateWithError("parameter id, uid, topic or status_message is missing");
}
$is_mitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
$is_mitarbeiter = $this->getDataOrTerminateWithError($is_mitarbeiter);
$is_student = $this->StudentModel->isStudent($uid);
$is_student = $this->getDataOrTerminateWithError($is_student);
if (
$is_student && $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) ||
$is_mitarbeiter && $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid")
) {
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_REJECTED);
$this->terminateWithSuccess($this->setStatusOnUpdateRequest($id, self::$STATUS_REJECTED, $status_message));
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_permission_error'),self::ERROR_TYPE_GENERAL);
}
}
public function acceptProfilRequest()
{
$id = $this->input->post('profil_update_id', true);
$uid = $this->input->post('uid', true);
$topic = $this->input->post('topic', true);
$requested_change = $this->input->post('requested_change');
$status_message = $this->input->post('status_message', true); //optional
//? fetching person_id using UID
$personID = $this->PersonModel->getByUid($uid);
$personID = $this->getDataOrTerminateWithError($personID)[0]->person_id;
//! check for required information
if (!isset($id) || !isset($uid) || !isset($personID) || !isset($requested_change) || !isset($topic)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_requiredInformation_error'));
}
$is_mitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
$is_mitarbeiter = $this->getDataOrTerminateWithError($is_mitarbeiter);
$is_student = $this->StudentModel->isStudent($uid);
$is_student = $this->getDataOrTerminateWithError($is_student);
//? check if the permissions are set correctly
if (
$is_student && $this->permissionlib->isBerechtigt('student/stammdaten', "suid", $this->getOE_from_student($uid)) ||
$is_mitarbeiter && $this->permissionlib->isBerechtigt('mitarbeiter/stammdaten', "suid")
) {
if (is_array($requested_change) && array_key_exists("adresse_id", $requested_change)) {
$insertID = $this->handleAdresse($requested_change, $personID);
$insertID = getData($insertID);
if (isset($insertID)) {
$requested_change['adresse_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_address_error', [$insertID]));
}
}
} else if (is_array($requested_change) && array_key_exists("kontakt_id", $requested_change)) {
$insertID = $this->handleKontakt($requested_change, $personID);
$insertID = getData($insertID);
if (isset($insertID)) {
$requested_change['kontakt_id'] = $insertID;
$update_res = $this->updateRequestedChange($id, $requested_change);
if (isError($update_res)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_kontakt_error', [$insertID]));
}
}
} else {
switch ($topic) {
// mapping phrasen to database columns to make the update with the correct column names
case self::$TOPICS['Titel']:
$topic = "titelpre";
break;
case self::$TOPICS['Postnomen']:
$topic = "titelpost";
break;
case self::$TOPICS['Vorname']:
$topic = "vorname";
break;
case self::$TOPICS['Nachname']:
$topic = "nachname";
break;
default:
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_topic_error', [$topic]));
}
$result = $this->PersonModel->update($personID, [$topic => $requested_change["value"]]);
if (isError($result)) $this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_insert_error'));
}
$this->sendEmail_onProfilUpdate_response($uid, $topic, self::$STATUS_ACCEPTED);
$this->terminateWithSuccess($this->setStatusOnUpdateRequest($id, self::$STATUS_ACCEPTED, $status_message, $requested_change));
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_permission_error'));
}
}
public function insertFile($replace)
{
$replace = json_decode($replace);
if (!count($_FILES)) {
$this->terminateWithError("No file available for upload");
}
//? if replace is set it contains the profil_update_id in which the attachment_id has to be replaced
if (isset($replace)) {
$this->ProfilUpdateModel->addSelect(["attachment_id"]);
$profilUpdate = $this->ProfilUpdateModel->load([$replace]);
if (isError($profilUpdate)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_loading_error'));
}
//? get the attachmentID
$dms_id = $this->getDataOrTerminateWithError($profilUpdate)[0]->attachment_id;
//? delete old dms_file of Profil Update
$deleteOldFile_result = $this->deleteOldVersionFile($dms_id);
if(!$deleteOldFile_result){
$this->terminateWithError("error while deleting the old file");
}
}
$files = $_FILES['files'];
$file_count = count($files['name']);
$res = [];
for ($i = 0; $i < $file_count; $i++) {
$_FILES['files']['name'] = $files['name'][$i];
$_FILES['files']['type'] = $files['type'][$i];
$_FILES['files']['tmp_name'] = $files['tmp_name'][$i];
$_FILES['files']['error'] = $files['error'][$i];
$_FILES['files']['size'] = $files['size'][$i];
$dms = [
"kategorie_kurzbz" => "profil_aenderung",
"version" => 0,
"name" => $_FILES['files']['name'],
"mimetype" => $_FILES['files']['type'],
"beschreibung" => $this->uid . " Profil Änderung",
"insertvon" => $this->uid,
"insertamum" => "NOW()",
];
$tmp_res = $this->dmslib->upload($dms, 'files', array("jpg", "png", "pdf"));
if(isError($tmp_res)){
$this->addError(getError($tmp_res));
}
$tmp_res = $this->getDataOrTerminateWithError($tmp_res);
array_push($res, $tmp_res);
}
$this->terminateWithSuccess($res);
}
public function getProfilUpdateWithPermission($status = null)
{
// early return if no status has been passed as argument
if (!isset($status)) {
echo json_encode($this->ProfilUpdateModel->getProfilUpdateWithPermission());
return;
}
// get the sprache of the user
$sprachenIndex = $this->SpracheModel->loadWhere(["sprache" => getUserLanguage()]);
$sprachenIndex = hasData($sprachenIndex) ? getData($sprachenIndex)[0]->index : null;
if (isset($sprachenIndex) && isset($status)) {
// get the corresponding status kurz_bz primary key out of the translation
$status = $this->ProfilUpdateStatusModel->execReadOnlyQuery("select * from public.tbl_profil_update_status where ? = ANY(bezeichnung_mehrsprachig)", [$status]);
$status = hasData($status) ? getData($status)[0]->status_kurzbz : null;
$res = $this->ProfilUpdateModel->getProfilUpdateWithPermission(isset($status) ? ['status' => $status] : null);
echo json_encode($res);
}
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
private function sendEmail_onProfilUpdate_insertion($uid, $profil_update_id, $topic)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$emails = [];
$is_mitarbeiter = $this->MitarbeiterModel->isMitarbeiter($uid);
if (isError($is_mitarbeiter)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
$is_mitarbeiter = $this->getDataOrTerminateWithError($is_mitarbeiter);
//! if the $uid is a mitarbeiter and student, only the hr is notified by email
if ($is_mitarbeiter) {
//? user is not a student therefore he is a mitarbeiter, send email to Personalverwaltung
//? use constant variable MAIL_GST to mail to the personalverwaltung
$this->MitarbeiterModel->addSelect([TRUE]);
$this->MitarbeiterModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_mitarbeiter.mitarbeiter_uid");
//? check if the the userID is a mitarbeiter and if the benutzer is active
$res = $this->MitarbeiterModel->loadWhere(["public.tbl_mitarbeiter.mitarbeiter_uid" => $uid, "public.tbl_benutzer.aktiv" => TRUE]);
if (isError($res)) {
$this->terminateWithError("was not able to query the mitarbeiter and benutzer by the uid: " . $uid);
}
if (hasData($res)) {
array_push($emails, MAIL_GST);
} else {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_mitarbeiterCheck_error'));
}
} else {
//? if it is not a mitarbeiter, check whether it is a student and send email to studiengang
$is_student = $this->StudentModel->isStudent($uid);
if (isError($is_student)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_studentCheck_error'));
}
$is_student = $this->getDataOrTerminateWithError($is_student);
if ($is_student) {
//? Send email to the Studiengangsassistentinnen
$this->StudentModel->addSelect(["public.tbl_studiengang.email"]);
$this->StudentModel->addJoin("public.tbl_benutzer", "public.tbl_benutzer.uid = public.tbl_student.student_uid");
$this->StudentModel->addJoin("public.tbl_prestudent", "public.tbl_benutzer.person_id = public.tbl_prestudent.person_id");
$this->StudentModel->addJoin("public.tbl_prestudentstatus", "public.tbl_prestudentstatus.prestudent_id = public.tbl_prestudent.prestudent_id");
$this->StudentModel->addJoin("public.tbl_studiengang", "public.tbl_studiengang.studiengang_kz = public.tbl_prestudent.studiengang_kz");
//* check if the benutzer itself is active
//* check if the student status is Student or Diplomand (active students)
$this->StudentModel->db->where_in("public.tbl_prestudentstatus.status_kurzbz", ['Student', 'Diplomand']);
$res = $this->StudentModel->loadWhere(["public.tbl_benutzer.aktiv" => TRUE, "public.tbl_student.student_uid" => $uid]);
if (isError($res)) {
$this->terminateWithError(getError($res));
} else {
$res = $this->getDataOrTerminateWithError($res);
foreach ($res as $emailObj) {
array_push($emails, $emailObj->email);
}
}
}
}
$mail_res = [];
//? sending email
foreach ($emails as $email) {
array_push($mail_res, sendSanchoMail("profil_update", ['uid' => $uid, 'topic' => $topic, 'href' => APP_ROOT . 'Cis/ProfilUpdate/id/' . $profil_update_id], $email, ("Profil Änderung von " . $uid)));
}
foreach ($mail_res as $m_res) {
if (!$m_res) {
$this->addError($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
private function sendEmail_onProfilUpdate_response($uid, $topic, $status)
{
if($this->config->item('cis_send_profil_update_mails') === false)
{
return;
}
$this->load->helper('hlp_sancho_helper');
$email = $uid . "@" . DOMAIN;
function languageQuery($language)
{
return "select index from public.tbl_sprache where sprache = '" + $language + "'";
}
$this->ProfilUpdateStatusModel->addSelect(["bezeichnung_mehrsprachig[(" . languageQuery('German') . ")] as status_de", "bezeichnung_mehrsprachig[(" . languageQuery('English') . ")] as status_en"]);
$status_translation = $this->ProfilUpdateStatusModel->loadWhere(["status_kurzbz" => $status]);
if (isError($status_translation)) {
$this->terminateWithError($this->p->t('profilUpdate', 'ProfilUpdateStatusTranslationError'));
}
$status_translation = hasData($status_translation) ? getData($status_translation)[0] : null;
if (isset($status_translation)) {
$mail_res = sendSanchoMail("profil_update_response", ['topic' => $topic, 'status_de' => $status_translation->status_de, 'status_en' => $status_translation->status_en, 'href' => APP_ROOT . 'Cis/Profil'], $email, ("Profil Änderung " . $this->p->t('profilUpdate', 'pending')));
if (!$mail_res) {
$this->addError($this->p->t('profilUpdate', 'profilUpdate_email_error'));
}
}
}
private function setStatusOnUpdateRequest($id, $status, $status_message)
{
return $this->ProfilUpdateModel->update([$id], ["status" => $status, "status_timestamp" => "NOW()", "status_message" => $status_message]);
}
private function updateRequestedChange($id, $requested_change)
{
return $this->ProfilUpdateModel->update([$id], ['requested_change' => json_encode($requested_change)]);
}
private function deleteOldVersionFile($dms_id)
{
// starting the transaction
$this->db->trans_start();
if (!isset($dms_id)) {
return;
}
//? delete the file from the profilUpdate first
$profilUpdateFileDelete = $this->ProfilUpdateModel->removeFileFromProfilUpdate($dms_id);
if(isError($profilUpdateFileDelete)){
$this->terminateWithError(getError($profilUpdateFileDelete));
}
//? delete all the different versions of the dms_file
$dmsVersions = $this->DmsVersionModel->loadWhere(["dms_id" => $dms_id]);
$dmsVersions = $this->getDataOrTerminateWithError($dmsVersions);
$dms_versions = array_map(function ($item) {
return $item->version;
}, $dmsVersions);
$test_array = array();
foreach ($dms_versions as $version) {
$delete_result = $this->dmslib->removeVersion($dms_id, $version);
array_push($test_array, $delete_result);
if(isError($delete_result)){
$this->addError(getError($delete_result));
}
}
// transaction complete
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
return false;
}
else
{
return true;
}
}
private function getOE_from_student($student_uid)
{
//? returns the oe_einheit eines Studenten
$query = "SELECT public.tbl_studiengang.oe_kurzbz
FROM public.tbl_student
JOIN public.tbl_studiengang ON tbl_student.studiengang_kz = public.tbl_studiengang.studiengang_kz
WHERE public.tbl_student.student_uid = ?;";
$res = $this->StudentModel->execReadOnlyQuery($query, [$student_uid]);
$res = $this->getDataOrTerminateWithError($res, $this->p->t('profilUpdate', 'profilUpdate_loadingOE_error'));
$res = array_map(
function ($item) {
return $item->oe_kurzbz;
},
$res
);
return $res;
}
private function handleAdresse($requested_change, $personID)
{
$this->AdressenTypModel->addSelect(["adressentyp_kurzbz"]);
$adr_kurzbz = $this->AdressenTypModel->loadWhere(["bezeichnung" => $requested_change['typ']]);
$adr_kurzbz = $this->getDataOrTerminateWithError($adr_kurzbz)[0]->adressentyp_kurzbz;
//? replace the address_typ with its correct kurzbz foreign key
$requested_change['typ'] = $adr_kurzbz;
$adresse_id = $requested_change["adresse_id"];
//? removes the adresse_id because we don't want to update the kontakt_id in the database
unset($requested_change["adresse_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$requested_change['person_id'] = $personID;
//TODO: zustelladresse, heimatadresse, rechnungsadresse und nation werden nicht beachtet
$insertID = $this->AdresseModel->insert($requested_change);
$insert_adresse_id = $insertID;
$insert_adresse_id = $this->getDataOrTerminateWithError($insert_adresse_id, $this->p->t('profilUpdate', 'profilUpdate_insertAdresse_error'));
if ($insert_adresse_id) {
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $insert_adresse_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$result = $this->AdresseModel->delete($adresse_id);
if (isError($result)) {
$this->terminateWithError(getError($result));
}
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_adresse_id = $this->AdresseModel->update($adresse_id, $requested_change);
$update_adresse_id = $this->getDataOrTerminateWithError($update_adresse_id, $this->p->t('profilUpdate', 'profilUpdate_updateAdresse_error'));
$this->handleDupplicateZustellAdressen($requested_change['zustelladresse'], $update_adresse_id);
}
return $insertID ?? null;
}
private function handleKontakt($requested_change, $personID)
{
$kontakt_id = $requested_change["kontakt_id"];
//? removes the kontakt_id because we don't want to update the kontakt_id in the database
unset($requested_change["kontakt_id"]);
//! ADD
if (array_key_exists('add', $requested_change) && $requested_change['add']) {
//? removes add flag
unset($requested_change['add']);
$requested_change['person_id'] = $personID;
$requested_change['insertamum'] = "NOW()";
$requested_change['insertvon'] = getAuthUID();
$insertID = $this->KontaktModel->insert($requested_change);
$insert_kontakt_id = $insertID;
$insert_kontakt_id = $this->getDataOrTerminateWithError($insert_kontakt_id, $this->p->t('profilUpdate', 'profilUpdate_insertKontakt_error'));
if ($insert_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $insert_kontakt_id);
}
}
//! DELETE
elseif (array_key_exists('delete', $requested_change) && $requested_change['delete']) {
$result = $this->KontaktModel->delete($kontakt_id);
if (isError($result)) {
$this->terminateWithError(getError($result));
}
}
//! UPDATE
else {
$requested_change['updateamum'] = "NOW()";
$requested_change['updatevon'] = getAuthUID();
$update_kontakt_id = $this->KontaktModel->update($kontakt_id, $requested_change);
$update_kontakt_id = $this->getDataOrTerminateWithError($update_kontakt_id, $this->p->t('profilUpdate', 'profilUpdate_updateKontakt_error'));
if ($update_kontakt_id) {
$this->handleDupplicateZustellKontakte($requested_change['zustellung'], $update_kontakt_id);
}
}
return isset($insertID) ? $insertID : null;
}
private function handleDupplicateZustellAdressen($zustellung, $adresse_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_adresse.adresse_id");
$this->PersonModel->addJoin("public.tbl_adresse", "public.tbl_adresse.person_id = public.tbl_person.person_id");
$zustellAdressenArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustelladresse" => TRUE]);
if (isError($zustellAdressenArray)) {
$this->terminateWithError($this->p->t('profilUpdate', 'profilUpdate_loadingZustellAdressen_error'));
}
$zustellAdressenArray = $this->getDataOrTerminateWithError($zustellAdressenArray);
if (count($zustellAdressenArray) > 0) {
$zustellAdressenArray = array_filter($zustellAdressenArray, function ($adresse) use ($adresse_id) {
return $adresse->adresse_id != $adresse_id;
});
// remove the zustelladresse from all other zustelladressen
foreach ($zustellAdressenArray as $adresse) {
$this->AdresseModel->update($adresse->adresse_id, ["zustelladresse" => FALSE]);
}
}
}
}
private function handleDupplicateZustellKontakte($zustellung, $kontakt_id)
{
if ($zustellung) {
$this->PersonModel->addSelect("public.tbl_kontakt.kontakt_id");
$this->PersonModel->addJoin("public.tbl_kontakt", "public.tbl_kontakt.person_id = public.tbl_person.person_id");
$zustellKontakteArray = $this->PersonModel->loadWhere(["public.tbl_person.person_id" => $this->pid, "zustellung" => TRUE]);
if (!isSuccess($zustellKontakteArray)) {
return error($this->p->t('profilUpdate', 'profilUpdate_loadingZustellkontakte_error'));
}
$zustellKontakteArray = hasData($zustellKontakteArray) ? getData($zustellKontakteArray) : null;
if ($zustellung && count($zustellKontakteArray) > 0) {
$zustellKontakteArray = array_filter($zustellKontakteArray, function ($kontakt) use ($kontakt_id) {
return $kontakt->kontakt_id != $kontakt_id;
});
foreach ($zustellKontakteArray as $kontakt) {
$this->KontaktModel->update($kontakt->kontakt_id, ["zustellung" => FALSE]);
}
}
}
}
}
@@ -0,0 +1,69 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the SearchBarLib (back-end)
* Provides data to the ajax get calls about the searchbar component
* This controller works with JSON calls on the HTTP GET and the output is always JSON
*/
class Searchbar extends FHCAPI_Controller
{
const SEARCHSTR_PARAM = 'searchstr';
const TYPES_PARAM = 'types';
/**
* Object initialization
*/
public function __construct()
{
// NOTE(chris): additional permission checks will be done in SearchBarLib
parent::__construct([
'search' => self::PERM_LOGGED
]);
// Load the library SearchBarLib
$this->load->library('SearchBarLib');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Gets a JSON body via HTTP POST and provides the parameters
*/
public function search()
{
$this->load->library('form_validation');
// Checks if the searchstr and the types parameters are in the POSTed JSON
$this->form_validation->set_rules(self::SEARCHSTR_PARAM, null, 'required');
$this->form_validation->set_rules(self::TYPES_PARAM . '[]', null, 'required');
if (!$this->form_validation->run())
$this->terminateWithError(SearchBarLib::ERROR_WRONG_JSON, self::ERROR_TYPE_GENERAL);
// Convert to json the result from searchbarlib->search
$result = $this->searchbarlib->search($this->input->post(self::SEARCHSTR_PARAM), $this->input->post(self::TYPES_PARAM));
if (property_exists($result, 'error'))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess($result);
}
}
@@ -0,0 +1,564 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Stundenplan extends FHCAPI_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'getRoomplan' => self::PERM_LOGGED,
'Stunden' => self::PERM_LOGGED,
'Reservierungen' => self::PERM_LOGGED,
'getStundenplan' => self::PERM_LOGGED,
'getLehreinheitStudiensemester' => self::PERM_LOGGED,
]);
$this->load->library('LogLib');
$this->loglib->setConfigs(array(
'classIndex' => 5,
'functionIndex' => 5,
'lineIndex' => 4,
'dbLogType' => 'API', // required
'dbExecuteUser' => 'RESTful API'
));
$this->load->library('form_validation');
//load models
$this->load->model('ressource/Stundenplan_model', 'StundenplanModel');
$this->load->model('ressource/Reservierung_model', 'ReservierungModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* fetches Stunden layout from database
* @access public
*
*/
public function Stunden()
{
$this->load->model('ressource/Stunde_model', 'StundeModel');
$stunden = $this->StundeModel->load();
$stunden = $this->getDataOrTerminateWithError($stunden);
$this->terminateWithSuccess($stunden);
}
/**
* fetches room events from a certain date
* @access public
*
*/
public function getRoomplan()
{
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('ort_kurzbz',"Ort","required");
$this->form_validation->set_rules('start_date',"start_date","required");
$this->form_validation->set_rules('end_date',"end_date","required");
if($this->form_validation->run() === FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$ort_kurzbz = $this->input->get('ort_kurzbz', TRUE);
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
$roomplan_data = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getRoomQuery($ort_kurzbz, $start_date, $end_date));
$roomplan_data = $this->getDataOrTerminateWithError($roomplan_data);
$this->expand_object_information($roomplan_data);
$this->terminateWithSuccess($roomplan_data);
}
/**
* fetches stundenplan events from a UID and start/end date
* @access public
*
*/
//TODO: getStundenplan fuer Mitarbeiter anpassen
public function getStundenplan(){
$this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel');
$this->load->model('organisation/Studiensemester_model','StudiensemesterModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->model('person/Benutzergruppe_model','BenutzergruppeModel');
// form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('start_date', "start_date", "required");
$this->form_validation->set_rules('end_date', "end_date", "required");
if ($this->form_validation->run() === FALSE)
$this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
$student_uid = getAuthUID();
if(is_null($student_uid))
{
$this->terminateWithError("No UID");
}
$is_mitarbeiter = getData($this->MitarbeiterModel->isMitarbeiter($student_uid));
if($is_mitarbeiter)
{
$this->terminateWithError("Not possible to look at the Student Calendar as a Mitarbeiter");
}
$semester_range = $this->studienSemesterErmitteln($start_date,$end_date);
$this->sortStudienSemester($semester_range);
$this->applyLoadUeberSemesterHaelfte($semester_range);
// getting the gruppen_kurzbz of the student in the different studiensemester
$benutzer_gruppen = $this->fetchBenutzerGruppenFromStudiensemester($semester_range);
// getting the student_lehrverbaende of the student in the different studiensemester
$student_lehrverband = $this->fetchStudentlehrverbandFromStudiensemester($semester_range);
$stundenplan_query = $this->StundenplanModel->getStundenplanQuery($start_date, $end_date, $semester_range, $benutzer_gruppen, $student_lehrverband);
if(!$stundenplan_query)
{
$this->terminateWithSuccess([]);
}
$stundenplan_data = $this->StundenplanModel->stundenplanGruppierung($stundenplan_query);
$stundenplan_data = $this->getDataOrTerminateWithError($stundenplan_data) ?? [];
$this->expand_object_information($stundenplan_data);
$this->terminateWithSuccess($stundenplan_data);
}
// gets the reservierungen of a room if the ort_kurzbz parameter is supplied otherwise gets the reservierungen of the stundenplan of a student
public function Reservierungen($ort_kurzbz = null)
{
//form validation
$this->load->library('form_validation');
$this->form_validation->set_data($_GET);
$this->form_validation->set_rules('start_date', "StartDate", "required");
$this->form_validation->set_rules('end_date', "EndDate", "required");
if($this->form_validation->run() == FALSE) $this->terminateWithValidationErrors($this->form_validation->error_array());
// storing the get parameter in local variables
$start_date = $this->input->get('start_date', TRUE);
$end_date = $this->input->get('end_date', TRUE);
// querying the reservierungen
$reservierungen = $this->ReservierungModel->getReservierungen($start_date, $end_date, $ort_kurzbz);
$reservierungen = $this->getDataOrTerminateWithError($reservierungen) ?? [];
$this->expand_object_information($reservierungen);
$this->terminateWithSuccess($reservierungen);
}
public function getLehreinheitStudiensemester($lehreinheit_id){
$this->load->model('education/Lehreinheit_model', 'LehreinheitModel');
$this->LehreinheitModel->addSelect(["studiensemester_kurzbz"]);
$result = $this->LehreinheitModel->load($lehreinheit_id);
$result = current($this->getDataOrTerminateWithError($result))->studiensemester_kurzbz;
$this->terminateWithSuccess($result);
}
// ################# Private Functions
private function expand_object_information($data){
foreach ($data as $item)
{
$lektor_obj_array = array();
$gruppe_obj_array = array();
// load lektor object
foreach ($item->lektor as $lv_lektor)
{
$this->StundenplanModel->addLimit(1);
$lektor_object = $this->StundenplanModel->execReadOnlyQuery("
SELECT mitarbeiter_uid, vorname, nachname, kurzbz
FROM public.tbl_mitarbeiter
JOIN public.tbl_benutzer benutzer ON benutzer.uid = mitarbeiter_uid
JOIN public.tbl_person person ON person.person_id = benutzer.person_id
WHERE kurzbz = ?", [$lv_lektor]);
if (isError($lektor_object)) {
$this->show_error(getError($lektor_object));
}
$lektor_object = $this->getDataOrTerminateWithError($lektor_object);
if(count($lektor_object) == 0)
{
$this->terminateWithError("No lektor object");
}
$lektor_object = current($lektor_object);
// only provide needed information of the mitarbeiter object
$lektor_obj_array[] = $lektor_object;
}
// load gruppe object
foreach ($item->gruppe as $lv_gruppe)
{
$lv_gruppe = strtr($lv_gruppe, ['(' => '', ')' => '', '"' => '']);
$lv_gruppe_array = explode(",", $lv_gruppe);
list($gruppe, $verband, $semester, $studiengang_kz, $gruppen_kuerzel) = $lv_gruppe_array;
$lv_gruppe_object = new stdClass();
$lv_gruppe_object->gruppe = $gruppe;
$lv_gruppe_object->verband = $verband;
$lv_gruppe_object->semester = $semester;
$lv_gruppe_object->studiengang_kz = $studiengang_kz;
$lv_gruppe_object->kuerzel = $gruppen_kuerzel;
$gruppe_obj_array[] = $lv_gruppe_object;
}
$item->gruppe = $gruppe_obj_array;
$item->lektor = $lektor_obj_array;
}
}
// function used to sort an array of studiensemester strings
private function sortStudienSemester(&$semester_range){
usort(
$semester_range,
function($first,$second)
{
$sem_first = null;
$year_first = null;
$match_first = null;
$sem_second = null;
$year_second = null;
$match_second = null;
preg_match('/([WS]+)([0-9]+)/',$first,$match_first);
preg_match('/([WS]+)([0-9]+)/',$second,$match_second);
$sem_first = $match_first[1];
$year_first = intval($match_first[2]);
$sem_second = $match_second[1];
$year_second = intval($match_second[2]);
if($year_first < $year_second)
{
return -1;
}
else if($year_first > $year_second)
{
return 1;
}
else if($year_first == $year_second && $sem_first > $sem_second)
{
return 1;
}
else if($year_first == $year_second && $sem_first < $sem_second)
{
return -1;
}
return 0;
}
);
}
private function fetchBenutzerGruppenFromStudiensemester($semester_range){
$student_uid = getAuthUID();
$benutzer_gruppen = [];
// for each studiensemester fetch the benutzer gruppen and add them to an associate $bentuzer_gruppen array
/*
[
['WS2023'] => [['gruppe1_SS2023','gruppe2_SS2023'],['gruppe1_WS2023','gruppe2_WS2023']],
['SS2024'] => [['gruppe1_WS2023','gruppe2_WS2023'],['gruppe1_SS2024','gruppe2_SS2024']],
['WS2024'] => [['gruppe1_SS2024','gruppe2_SS2024'],['gruppe1_WS2024','gruppe2_WS2024']],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$benutzer_gruppen[$semester_key] = [];
// each semester could have ajoint semesters that need to be checked
foreach($semester_array as $semester=>$semester_date_range)
{
// for each active semester query the benutzer_gruppen associated to the semester
$benutzer_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_benutzergruppe where uid = ? AND studiensemester_kurzbz = ?",[$student_uid, $semester]);
$benutzer_query_result = $this->getDataOrTerminateWithError($benutzer_query);
array_push(
$benutzer_gruppen[$semester_key],
array_map(
function($item)
{
return "'".$item->gruppe_kurzbz. "'";
},
$benutzer_query_result
)
);
}
}
// merge the gruppen of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => ['gruppe1_SS2023','gruppe2_SS2023','gruppe1_WS2023','gruppe2_WS2023'],
['SS2024'] => ['gruppe1_WS2023','gruppe2_WS2023','gruppe1_SS2024','gruppe2_SS2024'],
['WS2024'] => ['gruppe1_SS2024','gruppe2_SS2024','gruppe1_WS2024','gruppe2_WS2024'],
]
*/
$benutzer_gruppen = array_map(
function($gruppe)
{
$merged_gruppe = [];
foreach($gruppe as $gruppen_array)
{
$merged_gruppe = array_merge($merged_gruppe, $gruppen_array);
}
return $merged_gruppe;
},
$benutzer_gruppen
);
return $benutzer_gruppen;
}
private function fetchStudentlehrverbandFromStudiensemester($semester_range){
$student_uid = getAuthUID();
$student_lehrverband = [];
// for each studiensemester fetch the studentlehrverbaende and add them to an associate $student_lehrverband array
/*
[
['WS2023'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ] ],
['SS2024'] => [ [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ] ],
['WS2024'] => [ [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ], [ ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ] ],
]
*/
foreach($semester_range as $semester_key => $semester_array)
{
$student_lehrverband[$semester_key] = [];
foreach($semester_array as $semester=>$semester_date_range)
{
// for each active semester query the student_lehrverband associated to the semester
$lehrverband_query = $this->BenutzergruppeModel->execReadOnlyQuery("
SELECT * FROM tbl_studentlehrverband where student_uid = ? AND studiensemester_kurzbz = ?", [$student_uid, $semester]);
$lehrverband_query_result = $this->getDataOrTerminateWithError($lehrverband_query);
array_push($student_lehrverband[$semester_key], array_map(
function ($item)
{
$result = new stdClass();
$result->studiengang_kz = $item->studiengang_kz;
$result->semester = $item->semester;
$result->verband = $item->verband;
$result->gruppe = $item->gruppe;
return $result;
},
$lehrverband_query_result));
}
}
// merge the studentlehrverband of each studiensemester together for the original studiensemester
/*
[
['WS2023'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""] ],
['SS2024'] => [ ['stg_kz'=>298,'semester'=>1,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""] ],
['WS2024'] => [ ['stg_kz'=>298,'semester'=>2,'verband'=>"A",'gruppe'=>""], ['stg_kz'=>298,'semester'=>3,'verband'=>"A",'gruppe'=>""] ],
]
*/
$student_lehrverband = array_map(
function($studentlehrverband)
{
$merged_studentlehrverband = [];
foreach($studentlehrverband as $studentlehrverband_array)
{
$merged_studentlehrverband = array_merge($merged_studentlehrverband, $studentlehrverband_array);
}
return $merged_studentlehrverband;
},
$student_lehrverband
);
return $student_lehrverband;
}
private function applyLoadUeberSemesterHaelfte(&$semester_range){
/*
@var($semester_collection)
convert the array of studiensemester into an associative array with the studiensemester as the key
and the values of each key are the studiensemester needed for the query associated to that studiensemester
example:
#INPUT:
['WS2023','SS2024','WS2024']
#OUTPUT:
[
'WS2023' => ['SS2023','WS2023']
'SS2024' => ['WS2023','SS2024']
'WS2024' => ['SS2024','WS2024']
]
*/
$semester_collection = [];
foreach($semester_range as $studiensemester)
{
$previous_studiensemester = $this->StudiensemesterModel->getPreviousFrom($studiensemester);
$previous_studiensemester = $this->getDataOrTerminateWithError($previous_studiensemester);
if (count($previous_studiensemester) == 0) {
$this->terminateWithError("No previous semester");
}
$previous_studiensemester = current($previous_studiensemester)->studiensemester_kurzbz;
$semester_collection[$studiensemester] = [$previous_studiensemester, $studiensemester];
}
/*
@var($studienSemesterDateRanges)
fetches for each studiensemester the start and end date, (SS) summer studiensemester are extended by 1 month to cover the summerbreak
based on the LVPLAN_LOAD_UEBER_SEMESTERHAELFTE constant it will load both the semester and the previous semester with the full date range
or the semester with the full date range and the previous semester with the half date range:
#INPUT:
[
'WS2023' => ['SS2023','WS2023']
'SS2024' => ['WS2023','SS2024']
'WS2024' => ['SS2024','WS2024']
]
#OUTPUT: depends whether LVPLAN_LOAD_UEBER_SEMESTERHAELFTE is true or false
~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == true
[
"SS2024": [
"WS2023": [
"start"=> "2024-02-03",
"ende"=> "2024-08-31"
],
"SS2024": [
"start"=> "2024-02-03",
"ende"=> "2024-08-31"
]
]
]
~ if LVPLAN_LOAD_UEBER_SEMESTERHAELFTE == false
[
"SS2024": [
"WS2023": [
"start"=> "2024-02-03",
"ende"=> "2024-05-17"
],
"SS2024": [
"start"=> "2024-02-03",
"ende"=> "2024-08-31"
]
]
]
*/
$studienSemesterDateRanges=[];
foreach($semester_collection as $semester_original => $semester_adjoint)
{
$semester_start_ende = $this->StudiensemesterModel->getStartEndeFromStudiensemester($semester_original);
$semester_start_ende = current($this->getDataOrTerminateWithError($semester_start_ende));
// initialize empty arrays to add key value pairs
$studienSemesterDateRanges[$semester_original] = [];
// check if the studiensemester is a summer semester and add 1 month to bridge the school summer break
$match = null;
preg_match("/^(SS)([0-9]+)/",$semester_original,$match);
if(count($match) >0)
{
$one_month = new DateInterval('P1M');
$one_day = DateInterval::createFromDateString('1 days');
$summer_studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende);
$summer_studiensemester_end_date->add($one_month);
$summer_studiensemester_end_date->sub($one_day);
$semester_start_ende->ende = date_format($summer_studiensemester_end_date,'Y-m-d');
}
if (defined('LVPLAN_LOAD_UEBER_SEMESTERHAELFTE') && LVPLAN_LOAD_UEBER_SEMESTERHAELFTE === true)
{
foreach($semester_adjoint as $adjoint)
{
$studienSemesterDateRanges[$semester_original][$adjoint]=$semester_start_ende;
}
}
else
{
//TODO: half of a DateInterval might not be correctly calculated
// calculate the half of the studiensemester
$studiensemester_start_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->start);
$studiensemester_end_date = DateTime::createFromFormat('Y-m-d',$semester_start_ende->ende);
$studiensemester_time_difference = $studiensemester_start_date->diff($studiensemester_end_date);
$half_dateNumber = ceil($studiensemester_time_difference->d/2)+ceil(($studiensemester_time_difference->m*30)/2);
$half_dateInterval = new DateInterval('P'.strval($half_dateNumber) .'D');
$studiensemester_half = date_format($studiensemester_start_date->add($half_dateInterval),'Y-m-d');
$first_half = new stdClass();
$first_half->start = $semester_start_ende->start;
$first_half->ende = $studiensemester_half;
$studienSemesterDateRanges[$semester_original][$semester_adjoint[0]] = $first_half;
$studienSemesterDateRanges[$semester_original][$semester_adjoint[1]] = $semester_start_ende;
}
$semester_range = $studienSemesterDateRanges;
}
}
private function studienSemesterErmitteln($start_date,$end_date){
// gets all studiensemester from the student from start_date to end_date
$semester_range = $this->StudiensemesterModel->getByDate($start_date,$end_date);
$semester_range = array_map(
function($sem)
{
return $sem->studiensemester_kurzbz;
},
$this->getDataOrTerminateWithError($semester_range)
);
// if no studiensemester is found for the given timespan, get the nearest studiensemester
if(count($semester_range) == 0)
{
$aktuelle_studiensemester = $this->StudiensemesterModel->getNearest();
$aktuelle_studiensemester = $this->getDataOrTerminateWithError($aktuelle_studiensemester);
if (count($aktuelle_studiensemester) == 0) {
$this->terminateWithError("No aktuelles semester");
}
$aktuelle_studiensemester = current($aktuelle_studiensemester)->studiensemester_kurzbz;
// push aktuelles semester in active semester array
array_push($semester_range, $aktuelle_studiensemester);
}
return $semester_range;
}
}
@@ -0,0 +1,133 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the UDFLib (back-end)
* Provides data to the ajax get calls about the Udf component
* Listens to ajax post calls to change the Udf data
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Udf extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and prepares the UDFLib
*/
public function __construct()
{
// NOTE: UdfLib has its own permissions checks
parent::__construct([
'load' => self::PERM_LOGGED,
'save' => self::PERM_LOGGED
]);
// Libraries
$this->load->library('form_validation');
$this->load->library('UDFLib');
// Models
$this->load->model($this->getTargetModelPath(), 'TargetModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Load all UDFs for a dataset
*
* @return void
*/
public function load()
{
$pks = $this->TargetModel->getPks();
foreach ($pks as $id)
$this->form_validation->set_rules($id, $id, 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$id = [];
foreach ($pks as $pk)
$id[$pk] = $this->input->post($pk);
if (!is_array($this->TargetModel->getPk()))
$id = current($id);
$result = $this->udflib->getFieldArray($this->TargetModel, $id);
$fields = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($fields);
}
/**
* Saves UDFs to a dataset
*
* @return void
*/
public function save()
{
$pks = $this->TargetModel->getPks();
foreach ($pks as $id)
$this->form_validation->set_rules($id, $id, 'required');
$result = $this->udflib->getCiValidations($this->TargetModel, $this->input->post());
$fieldValidations = $this->getDataOrTerminateWithError($result);
$this->form_validation->set_rules($fieldvalidations);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$id = [];
$fields = $this->input->post();
foreach ($pks as $pk) {
$id[$pk] = $fields[$pk];
unset($fields[$pk]);
}
if (!is_array($this->TargetModel->getPk()))
$id = current($id);
$result = $this->TargetModel->update($id, $fields);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(array_fill_keys(array_keys($fields), ''));
}
//------------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Get the path to the target model from the url
*
* @return string
*/
private function getTargetModelPath()
{
$ci_model_path = array_slice($this->uri->rsegments, 2);
if ($ci_model_path)
$ci_model_path[] = ucfirst(array_pop($ci_model_path)) . '_model';
return implode(DIRECTORY_SEPARATOR, $ci_model_path);
}
}
@@ -0,0 +1,387 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class BetriebsmittelP extends FHCAPI_Controller
{
private $person_id = null;
public function __construct()
{
parent::__construct([
'getAllBetriebsmittel' => ['admin:r', 'assistenz:r'],
'addNewBetriebsmittel' => self::PERM_LOGGED,
'updateBetriebsmittel' => self::PERM_LOGGED,
'loadBetriebsmittel' => ['admin:r', 'assistenz:r'],
'deleteBetriebsmittel' => self::PERM_LOGGED,
'getTypenBetriebsmittel' => ['admin:r', 'assistenz:r'],
'loadInventarliste' => ['admin:r', 'assistenz:r']
]);
//Load Models
$this->load->model('ressource/Betriebsmittel_model', 'BetriebsmittelModel');
$this->load->model('ressource/Betriebsmittelperson_model', 'BetriebsmittelpersonModel');
// Additional Permission Checks
if ($this->router->method == 'addNewBetriebsmittel') {
$this->person_id = current(array_slice($this->uri->rsegments, 2));
$this->checkPermissionsForPerson(
$this->person_id,
['admin:rw', 'mitarbeiter:rw', 'basis/betriebsmittel:rw'],
['admin:rw', 'assistenz:rw', 'basis/betriebsmittel:rw']
);
} elseif ($this->router->method == 'updateBetriebsmittel' || $this->router->method == 'deleteBetriebsmittel') {
$betriebsmittelperson_id = current(array_slice($this->uri->rsegments, 2));
$result = $this->BetriebsmittelpersonModel->load($betriebsmittelperson_id);
if (!hasData($result))
show_404();
$this->person_id = current(getData($result))->person_id;
$this->checkPermissionsForPerson(
$this->person_id,
['admin:rw', 'mitarbeiter:rw', 'basis/betriebsmittel:rw'],
['admin:rw', 'assistenz:rw', 'basis/betriebsmittel:rw']
);
}
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'wawi'
]);
}
public function getAllBetriebsmittel($type_id, $id)
{
$result = $this->BetriebsmittelpersonModel->getBetriebsmittelData($id, $type_id);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
protected function validateNewOrUpdate()
{
$this->form_validation->set_rules('betriebsmitteltyp', 'Typ', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired')
]);
$this->form_validation->set_rules('kaution', 'Kaution', 'numeric|less_than_equal_to[9999.99]', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric')
]);
$this->form_validation->set_rules('ausgegebenam', 'Ausgegeben am', 'required|is_valid_date', [
'required' => $this->p->t('ui', 'error_fieldRequired')
]);
if ($this->input->post('ausgegebenam') && $this->input->post('retouram')) {
$this->form_validation->set_rules('retouram', 'Retour am', [
'is_valid_date',
['is_not_before_ausgegebenam', function ($value) {
return (new DateTime($value) >= new DateTime($this->input->post('ausgegebenam')));
}]
], [
'is_not_before_ausgegebenam' => $this->p->t('wawi', 'error_retourdatumVorAusgabe')
]);
} else {
$this->form_validation->set_rules('retouram', 'Retour am', 'is_valid_date');
}
$this->form_validation->set_rules('anmerkung', 'Anmerkung', 'max_length[256]');
if ($this->input->post('betriebsmitteltyp') == 'Inventar') {
// Inventar
$this->form_validation->set_rules('betriebsmittel_id', 'Inventarnummer', 'required');
} elseif ($this->input->post('betriebsmitteltyp') == 'Zutrittskarte') {
// Zutrittskarte
if ($this->input->post('nummer') === null && $this->input->post('nummer') === null) {
$this->form_validation->set_rules('nummer', 'Nummer', 'required', [
'required' => $this->p->t('wawi', 'error_zutrittskarteOhneNummer')
]);
$this->form_validation->set_rules('nummer2', 'Nummer2', 'required', [
'required' => $this->p->t('wawi', 'error_zutrittskarteOhneNummer')
]);
} else {
if ($this->input->post('nummer') === null) {
$result = $this->BetriebsmittelpersonModel->loadViewWhere([
'betriebsmitteltyp' => $this->input->post('betriebsmitteltyp'),
'nummer2' => $this->input->post('nummer2'),
'person_id !=' => $this->person_id,
'retouram IS NULL' => null
]);
if (hasData($result))
$this->form_validation->set_rules('nummer2', 'Nummer2', 'is_array', [
'is_array' => $this->p->t('wawi', 'error_bmZutrittskarteOccupied', (array)current(getData($result)))
]);
} else {
$result = $this->BetriebsmittelpersonModel->loadViewWhere([
'betriebsmitteltyp' => $this->input->post('betriebsmitteltyp'),
'nummer' => $this->input->post('nummer'),
'person_id !=' => $this->person_id,
'retouram IS NULL' => null
]);
if (hasData($result))
$this->form_validation->set_rules('nummer', 'Nummer', 'is_array', [
'is_array' => $this->p->t('wawi', 'error_bmZutrittskarteOccupied', (array)current(getData($result)))
]);
}
}
}
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
public function addNewBetriebsmittel($person_id)
{
$this->form_validation->set_rules('uid', 'UID', [
['uid_in_person', function ($value) use ($person_id) {
if ($value === null)
return true;
$this->load->model('person/Benutzer_model', 'BenutzerModel');
$result = $this->BenutzerModel->loadWhere([
'uid' => $value,
'person_id' => $person_id
]);
return hasData($result);
}]
], [
'uid_in_person' => $this->p->t('person', 'error_uidNotInPerson')
]);
$this->validateNewOrUpdate();
$betriebsmitteltyp = $this->input->post('betriebsmitteltyp');
$nummer = $this->input->post('nummer');
$nummer2 = $this->input->post('nummer2');
$beschreibung = $this->input->post('beschreibung');
$betriebsmittel_id = $this->input->post('betriebsmittel_id');
$anmerkung = $this->input->post('anmerkung');
$kaution = $this->input->post('kaution');
$ausgegebenam = $this->input->post('ausgegebenam');
$retouram = $this->input->post('retouram');
$uid = $this->input->post('uid');
// NOTE(chris): transform_kartennummer
if ($betriebsmitteltyp == 'Zutrittskarte' && $nummer)
$nummer = is_numeric($nummer) ? ltrim($nummer, "0") : hexdec(implode("", array_reverse(str_split(trim($nummer)))));
$this->db->trans_start();
if ($betriebsmitteltyp != 'Inventar') {
$this->BetriebsmittelModel->addOrder('updateamum', 'DESC');
if ($betriebsmitteltyp == 'Zutrittskarte' && $nummer === null) {
$result = $this->BetriebsmittelModel->loadWhere([
'betriebsmitteltyp' => $betriebsmitteltyp,
'nummer2' => $nummer2
]);
} else {
$result = $this->BetriebsmittelModel->loadWhere([
'betriebsmitteltyp' => $betriebsmitteltyp,
'nummer' => $nummer
]);
}
$data = $this->getDataOrTerminateWithError($result);
if ($data) {
$data = current($data);
if ($data->nummer !== $nummer || $data->nummer2 !== $nummer2 || $data->beschreibung !== $beschreibung) {
$result = $this->BetriebsmittelModel->update($data->betriebsmittel_id, [
'nummer' => $nummer,
'nummer2' => $nummer2,
'beschreibung' => $beschreibung,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]);
$this->getDataOrTerminateWithError($result);
}
$betriebsmittel_id = $data->betriebsmittel_id;
} else {
$result = $this->BetriebsmittelModel->insert([
'betriebsmitteltyp' => $betriebsmitteltyp,
'nummer' => $nummer,
'nummer2' => $nummer2,
'beschreibung' => $beschreibung,
'reservieren' => false,
'ort_kurzbz' => null,
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
]);
$betriebsmittel_id = $this->getDataOrTerminateWithError($result);
}
}
$result = $this->BetriebsmittelpersonModel->insert([
'person_id' => $person_id,
'betriebsmittel_id' => $betriebsmittel_id,
'anmerkung' => $anmerkung,
'kaution' => $kaution,
'ausgegebenam' => $ausgegebenam,
'retouram' => $retouram,
'uid' => $uid,
'insertamum' => date('c'),
'insertvon' => getAuthUID()
]);
$data = $this->getDataOrTerminateWithError($result);
$this->db->trans_complete();
$this->terminateWithSuccess(true);
}
public function updateBetriebsmittel($betriebsmittelperson_id)
{
$this->validateNewOrUpdate();
$betriebsmitteltyp = $this->input->post('betriebsmitteltyp');
$nummer = $this->input->post('nummer');
$nummer2 = $this->input->post('nummer2');
$beschreibung = $this->input->post('beschreibung');
$betriebsmittel_id = $this->input->post('betriebsmittel_id');
$anmerkung = $this->input->post('anmerkung');
$kaution = $this->input->post('kaution');
$ausgegebenam = $this->input->post('ausgegebenam');
$retouram = $this->input->post('retouram');
// NOTE(chris): transform_kartennummer
if ($betriebsmitteltyp == 'Zutrittskarte' && $nummer)
$nummer = is_numeric($nummer) ? ltrim($nummer, "0") : hexdec(implode("", array_reverse(str_split(trim($nummer)))));
$this->db->trans_start();
if ($betriebsmitteltyp != 'Inventar') {
$found = false;
if ($nummer !== null && $betriebsmittel_id !== null) {
$result = $this->BetriebsmittelModel->load($betriebsmittel_id);
$data = $this->getDataOrTerminateWithError($result);
if ($data && current($data)->nummer == $nummer) {
$found = true;
}
}
if (!$found) {
$this->BetriebsmittelModel->addOrder('updateamum', 'DESC');
if ($betriebsmitteltyp == 'Zutrittskarte' && $nummer === null) {
$result = $this->BetriebsmittelModel->loadWhere([
'betriebsmitteltyp' => $betriebsmitteltyp,
'nummer2' => $nummer2
]);
} else {
$result = $this->BetriebsmittelModel->loadWhere([
'betriebsmitteltyp' => $betriebsmitteltyp,
'nummer' => $nummer
]);
}
$data = $this->getDataOrTerminateWithError($result);
}
if ($data) {
$data = current($data);
if ($data->nummer !== $nummer || $data->nummer2 !== $nummer2 || $data->beschreibung !== $beschreibung) {
$result = $this->BetriebsmittelModel->update($data->betriebsmittel_id, [
'nummer' => $nummer,
'nummer2' => $nummer2,
'beschreibung' => $beschreibung,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]);
$this->getDataOrTerminateWithError($result);
}
$betriebsmittel_id = $data->betriebsmittel_id;
} else {
$result = $this->BetriebsmittelModel->insert([
'betriebsmitteltyp' => $betriebsmitteltyp,
'nummer' => $nummer,
'nummer2' => $nummer2,
'beschreibung' => $beschreibung,
'reservieren' => false,
'ort_kurzbz' => null,
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
]);
$betriebsmittel_id = $this->getDataOrTerminateWithError($result);
}
}
$result = $this->BetriebsmittelpersonModel->update($betriebsmittelperson_id, [
'betriebsmittel_id' => $betriebsmittel_id,
'anmerkung' => $anmerkung,
'kaution' => $kaution,
'ausgegebenam' => $ausgegebenam,
'retouram' => $retouram,
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]);
$data = $this->getDataOrTerminateWithError($result);
$this->db->trans_complete();
$this->terminateWithSuccess(true);
}
public function loadBetriebsmittel($betriebsmittelperson_id)
{
$result = $this->BetriebsmittelpersonModel->getBetriebsmittelData($betriebsmittelperson_id, 'betriebsmittelperson_id');
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result)) {
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Betriebsmittelperson_id']), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(current(getData($result)));
}
public function deleteBetriebsmittel($betriebsmittelperson_id)
{
$result = $this->BetriebsmittelpersonModel->delete(
array('betriebsmittelperson_id' => $betriebsmittelperson_id,
)
);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result)) {
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id' => 'Betriebsmittelperson_id']), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(current(getData($result)));
}
public function getTypenBetriebsmittel()
{
$this->load->model('ressource/Betriebsmitteltyp_model', 'BetriebsmitteltypModel');
$this->BetriebsmitteltypModel->addOrder('beschreibung', 'ASC');
$result = $this->BetriebsmitteltypModel->load(); // load All
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function loadInventarliste($searchString)
{
$result = $this->BetriebsmittelModel->loadInventarliste($searchString);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,141 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
class CheckPerson extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'updatePersonUnrulyStatus' => array('basis/mitarbeiter:rw', 'student/antragfreigabe:rw', 'student/studierendenantrag:rw'),
'filterPerson' => array('basis/mitarbeiter:rw', 'student/antragfreigabe:rw', 'student/studierendenantrag:rw'),
'checkUnruly' => array('basis/mitarbeiter:r', 'student/antragfreigabe:r', 'student/studierendenantrag:r', 'infocenter:r'),
'checkDuplicate' => array('infocenter:r'),
]);
$this->_ci =& get_instance();
$this->_ci->load->model('person/Person_model', 'PersonModel');
}
public function updatePersonUnrulyStatus()
{
$data = json_decode($this->input->raw_input_stream, true);
$person_id = $data['person_id'];
$unruly = $data['unruly'];
$result = $this->_ci->PersonModel->updateUnruly($person_id, $unruly);
if(isError($result)) {
$this->terminateWithError($result);
} else if (isSuccess($result)) {
$this->terminateWithSuccess($result);
}
}
public function checkDuplicate() {
$person_id = $this->input->post('person_id');
$result = $this->_ci->PersonModel->checkDuplicate($person_id);
if (isSuccess($result))
$this->terminateWithSuccess($result);
else
$this->terminateWithError('Error when searching for person');
}
// performs strict check over vorname, nachname, gebdatum
public function checkUnruly() {
$vorname = $this->input->post('vorname');
$nachname = $this->input->post('nachname');
$gebdatum = $this->input->post('gebdatum');
$result = $this->_ci->PersonModel->checkUnruly($vorname, $nachname, $gebdatum);
if (isSuccess($result))
$this->terminateWithSuccess($result);
else
$this->terminateWithError('Error when searching for person');
}
// filters nachname on similarity and vorname/gebdatum are optional
public function filterPerson() {
$payload = json_decode($this->input->raw_input_stream, TRUE);
$nachnameString = '';
$vornameString = '';
$filterUnruly = true;
$birthdateString = '';
if(array_key_exists( 'nachname', $payload) ) {
$nachnameString = $payload['nachname'];
}
if(array_key_exists('vorname', $payload)) {
$vornameString = $payload['vorname'];
}
if(array_key_exists('unruly', $payload)){
$filterUnruly = $payload['unruly'];
}
if(array_key_exists('gebdatum', $payload)) {
// TODO: enable if gebdatum filter for unrulys is desired
// $birthdateString = $payload['gebdatum'];
}
$parametersArray = array($nachnameString);
$where ="p.nachname~* ? ";
if (mb_strlen($nachnameString) == 2)
{
$where = "p.nachname=? ";
}
if(isset($vornameString) && $vornameString != '')
{
$where.= " AND p.vorname~*?";
$parametersArray[] = $vornameString;
}
if(isset($birthdateString) && $birthdateString != '')
{
$where.=" AND p.gebdatum=?";
$parametersArray[] = $birthdateString;
}
if(isset($filterUnruly))
{
$where.=" AND p.unruly=?";
$parametersArray[] = $filterUnruly;
}
$result = $this->_ci->PersonModel->checkUnrulyWhere($where, $parametersArray);
if (isSuccess($result))
$this->terminateWithSuccess($result);
else
$this->terminateWithError('Error when searching for person');
}
}
@@ -0,0 +1,65 @@
<?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 Lehrveranstaltung extends FHCAPI_Controller
{
/**
* Lehrveranstaltung API constructor.
*/
public function __construct()
{
parent::__construct(array(
'getTemplateLvTree' => array(
'lehre/lehrveranstaltung:rw'
)
));
// Load model LehrveranstaltungModel
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
}
/**
* Get all Templates and union with all Lehrveranstaltungen of given Studiensemester and Oes of given Berechtigung,
* that are assigned to a template. This data structure can be used for nested tabulators' data tree.
*
* @param null|string $studiensemester_kurzbz
* @param null|string $berechtigung
* @return array|stdClass|null
*/
public function getTemplateLvTree()
{
$studiensemester_kurzbz = $this->input->get('studiensemester_kurzbz');
$berechtigung = $this->input->get('berechtigung');
if ($berechtigung)
{
$oe_permissions = $this->permissionlib->getOE_isEntitledFor($berechtigung);
if(!$oe_permissions) $oe_permissions = [];
$result = $this->LehrveranstaltungModel->getTemplateLvTree($studiensemester_kurzbz, $oe_permissions);
}
else
{
$result = $this->LehrveranstaltungModel->getTemplateLvTree($studiensemester_kurzbz);
}
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
}
@@ -0,0 +1,51 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class NotizPerson extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'getUid' => ['admin:r', 'assistenz:r'],
'getNotizen' => ['admin:r', 'assistenz:r'],
'loadNotiz' => ['admin:r', 'assistenz:r'],
'addNewNotiz' => ['admin:rw', 'assistenz:rw'],
'updateNotiz' => ['admin:rw', 'assistenz:rw'],
'deleteNotiz' => ['admin:rw', 'assistenz:rw'],
'loadDokumente' => ['admin:r', 'assistenz:r'],
'getMitarbeiter' => ['admin:r', 'assistenz:r'],
'isBerechtigt' => ['admin:r', 'assistenz:r'],
]);
}
public function isBerechtigt($id, $typeId)
{
if($typeId != "person_id")
{
return $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);
}
return $this->outputJsonSuccess(true);
}
public function loadDokumente()
{
$notiz_id = $this->input->post('notiz_id');
// 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();
}
}
@@ -0,0 +1,118 @@
<?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 Studiensemester extends FHCAPI_Controller
{
/**
* Studiensemester API constructor.
*/
public function __construct()
{
parent::__construct(
array(
'getAll' => self::PERM_LOGGED,
'getAktNext' => self::PERM_LOGGED
)
);
// Load model StudiensemesterModel
$this->load->model('organisation/studiensemester_model', 'StudiensemesterModel');
}
/**
* Get all Studiensemester.
*
* @param null|string $order Sorting order for the Studiensemester, 'asc' or 'desc'. Defaults to 'asc'.
* @param null|string $start Start date of the displayed Studiensemester in the format 'YYYY-MM-DD'.
* If provided, only Studiensemester starting from this date onwards will be returned.
* eg. '2020-09-01' will start with WS2020.
*/
public function getAll()
{
$order = $this->input->get('order');
$start = $this->input->get('start');
if (strcasecmp($order, 'DESC') == 0)
{
$this->StudiensemesterModel->addOrder('ende', 'DESC');
}
else
{
$this->StudiensemesterModel->addOrder('ende', 'ASC');
}
if ($start)
{
$result = $this->StudiensemesterModel->loadWhere([
'start >= ' => $start
]);
}
else
{
$result = $this->StudiensemesterModel->load();
}
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
/**
* @return void
*/
public function getAktNext()
{
$semester = $this->input->get('semester');
$result = null;
if (!is_numeric($semester))
{
$result = $this->StudiensemesterModel->loadWhere(array('start <=' => 'NOW()', 'ende >=' => 'NOW()'));
}
if (!hasData($result))
{
$this->StudiensemesterModel->addOrder('ende');
$this->StudiensemesterModel->addLimit(1);
$whereArray = array('ende >=' => 'NOW()');
if (is_numeric($semester))
{
if ($semester % 2 == 0)
{
$ss = 'SS';
}
else
{
$ss = 'WS';
}
$whereArray['SUBSTRING(studiensemester_kurzbz FROM 1 FOR 2) ='] = $ss;
}
$result = $this->StudiensemesterModel->loadWhere($whereArray);
}
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_DB);
}
$this->terminateWithSuccess((getData($result) ?: ''));
}
}
@@ -0,0 +1,187 @@
<?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 \REST_Controller as REST_Controller;
use \Studierendenantrag_model as Studierendenantrag_model;
/**
* This controller operates between (interface) the JS (GUI) and the AntragLib (back-end)
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Abmeldung extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and loads the AntragLib
*/
public function __construct()
{
parent::__construct([
'getDetailsForNewAntrag' => self::PERM_LOGGED,
'getDetailsForAntrag' => self::PERM_LOGGED,
'createAntrag' => self::PERM_LOGGED,
'cancelAntrag' => self::PERM_LOGGED
]);
// Libraries
$this->load->library('AntragLib');
// Load language phrases
$this->loadPhrases([
'studierendenantrag'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Retrieves data of the current studiengang for the current user
*/
public function getDetailsForNewAntrag($prestudent_id)
{
if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, true))
$this->terminateWithError('Forbidden', self::ERROR_TYPE_AUTH, REST_Controller::HTTP_FORBIDDEN);
$result = $this->antraglib->getPrestudentAbmeldeBerechtigt($prestudent_id);
$result = $this->getDataOrTerminateWithError($result);
if (!$result) {
$this->terminateWithError(
$this->p->t('studierendenantrag', 'error_no_student'),
self::ERROR_TYPE_AUTH,
REST_Controller::HTTP_FORBIDDEN
);
} elseif ($result == -3) {
$this->terminateWithError(
$this->p->t('studierendenantrag', 'error_stg_blacklist'),
self::ERROR_TYPE_AUTH,
REST_Controller::HTTP_FORBIDDEN
);
} elseif ($result == -1) {
$result = $this->antraglib->getDetailsForLastAntrag(
$prestudent_id,
[
Studierendenantrag_model::TYP_ABMELDUNG,
Studierendenantrag_model::TYP_ABMELDUNG_STGL
]
);
$data = $this->getDataOrTerminateWithError($result);
$data->canCancel = (
$data->status == Studierendenantragstatus_model::STATUS_CREATED &&
$this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id)
);
$this->terminateWithSuccess($data);
}
$result = $this->antraglib->getDetailsForNewAntrag($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getDetailsForAntrag($studierendenantrag_id)
{
if (!$this->antraglib->isEntitledToShowAntrag($studierendenantrag_id))
return show_404();
$result = $this->antraglib->getDetailsForAntrag($studierendenantrag_id);
$data = $this->getDataOrTerminateWithError($result);
if ($data->typ !== Studierendenantrag_model::TYP_ABMELDUNG_STGL && $data->typ !== Studierendenantrag_model::TYP_ABMELDUNG)
return show_404();
$data->canCancel = (
$data->status == Studierendenantragstatus_model::STATUS_CREATED &&
$this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id)
);
$this->terminateWithSuccess($data);
}
public function createAntrag()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required');
$this->form_validation->set_rules('prestudent_id', 'Prestudent ID', 'required');
$this->form_validation->set_rules('grund', 'Grund', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$grund = $this->input->post('grund');
$studiensemester = $this->input->post('studiensemester');
$prestudent_id = $this->input->post('prestudent_id');
$result = $this->antraglib->getPrestudentAbmeldeBerechtigt($prestudent_id);
$result = $this->getDataOrTerminateWithError($result);
if (!$result)
$this->terminateWithError($this->p->t('studierendenantrag', 'error_no_student'), self::ERROR_TYPE_GENERAL);
elseif ($result == -3)
$this->terminateWithError($this->p->t('studierendenantrag', 'error_stg_blacklist'), self::ERROR_TYPE_GENERAL);
elseif ($result < 0)
$this->terminateWithError($this->p->t('studierendenantrag', 'error_antrag_exists'), self::ERROR_TYPE_GENERAL);
$result = $this->antraglib->createAbmeldung($prestudent_id, $studiensemester, getAuthUID(), $grund);
$data = $this->getDataOrTerminateWithError($result);
$result = $this->antraglib->getDetailsForAntrag($data);
if (!hasData($result))
return $this->terminateWithSuccess(true);
$data = getData($result);
$data->canCancel = (boolean)$this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id);
$this->terminateWithSuccess($data);
}
public function cancelAntrag()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('antrag_id', 'Antrag ID', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$antrag_id = $this->input->post('antrag_id');
if (!$this->antraglib->isEntitledToCancelAntrag($antrag_id))
$this->terminateWithError('Forbidden', self::ERROR_TYPE_AUTH, REST_Controller::HTTP_FORBIDDEN);
$result = $this->antraglib->cancelAntrag($antrag_id, getAuthUID());
$this->getDataOrTerminateWithError($result);
$result = $this->antraglib->getDetailsForAntrag($antrag_id);
if (!hasData($result))
$this->terminateWithSuccess($antrag_id);
$data = getData($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,429 @@
<?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 \stdClass as stdClass;
use \Studierendenantrag_model as Studierendenantrag_model;
/**
* This controller operates between (interface) the JS (GUI) and the AntragLib (back-end)
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Leitung extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and loads the AntragLib
*/
public function __construct()
{
parent::__construct([
'getActiveStgs' => ['student/antragfreigabe:r', 'student/studierendenantrag:r'],
'getAntraege' => ['student/antragfreigabe:r', 'student/studierendenantrag:r'],
'getHistory' => ['student/antragfreigabe:r', 'student/studierendenantrag:r'],
'getPrestudents' => 'student/studierendenantrag:w',
'approveAntrag' => 'student/antragfreigabe:w',
'rejectAntrag' => 'student/antragfreigabe:w',
'reopenAntrag' => 'student/studierendenantrag:w',
'pauseAntrag' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'],
'unpauseAntrag' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'],
'objectAntrag' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'],
'approveObjection' => ['student/antragfreigabe:w', 'student/studierendenantrag:w'],
'denyObjection' => ['student/antragfreigabe:w', 'student/studierendenantrag:w']
]);
// Libraries
$this->load->library('AntragLib');
// Load language phrases
$this->loadPhrases([
'studierendenantrag',
'lehre'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getActiveStgs()
{
$studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe') ?: [];
$studiengaenge = array_merge($studiengaenge, $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []);
$result = $this->StudierendenantragModel->loadStgsWithAntraege($studiengaenge);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAntraege($studiengang = null, $extra = null)
{
if ($studiengang && $studiengang == 'todo') {
$studiengang = $extra;
$extra = true;
} else {
$extra = false;
}
$studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe');
if(!is_array($studiengaenge))
$studiengaenge = [];
$stgsNeuanlage = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag');
if(!is_array($stgsNeuanlage))
$stgsNeuanlage = [];
$studiengaenge = array_unique(array_merge($studiengaenge, $stgsNeuanlage));
if ($studiengang) {
if (!in_array($studiengang, $studiengaenge))
$this->terminateWithError(
'Forbidden',
self::ERROR_TYPE_AUTH,
REST_Controller::HTTP_FORBIDDEN
);
$studiengaenge = [$studiengang];
}
$antraege = [];
if ($studiengaenge) {
$result = $extra
? $this->StudierendenantragModel->loadActiveForStudiengaenge($studiengaenge)
: $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge);
$antraege = $this->getDataOrTerminateWithError($result);
}
$this->terminateWithSuccess($antraege ?: []);
}
public function getHistory($studierendenantrag_id)
{
if (!$this->antraglib->isEntitledToSeeHistoryForAntrag($studierendenantrag_id))
$this->terminateWithError(
'Forbidden',
self::ERROR_TYPE_AUTH,
REST_Controller::HTTP_FORBIDDEN
);
$result = $this->antraglib->getAntragHistory($studierendenantrag_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data ?: []);
}
public function getPrestudents()
{
$query = $this->input->post('query');
$studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag');
$result = $this->antraglib->getAktivePrestudentenInStgs($studiengaenge, $query);
$result = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($result ?: []);
}
public function approveAntrag()
{
$this->load->library('form_validation');
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
['isEntitledToApproveAntrag', [$this->antraglib, 'isEntitledToApproveAntrag']],
],
[
'isEntitledToApproveAntrag' => $this->p->t('studierendenantrag', 'error_no_right')
]
);
$this->form_validation->set_rules(
'typ',
'Typ',
'required|in_list[' . implode(',', [
Studierendenantrag_model::TYP_ABMELDUNG,
Studierendenantrag_model::TYP_ABMELDUNG_STGL,
Studierendenantrag_model::TYP_UNTERBRECHUNG,
Studierendenantrag_model::TYP_WIEDERHOLUNG
]) . ']'
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
switch ($this->input->post('typ')) {
case Studierendenantrag_model::TYP_ABMELDUNG:
case Studierendenantrag_model::TYP_ABMELDUNG_STGL:
$result = $this->antraglib->approveAbmeldung([$studierendenantrag_id], getAuthUID());
break;
case Studierendenantrag_model::TYP_UNTERBRECHUNG:
$result = $this->antraglib->approveUnterbrechung([$studierendenantrag_id], getAuthUID());
break;
case Studierendenantrag_model::TYP_WIEDERHOLUNG:
$result = $this->antraglib->approveWiederholung($studierendenantrag_id, getAuthUID());
break;
}
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($studierendenantrag_id);
}
public function rejectAntrag()
{
$this->load->library('form_validation');
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
['isEntitledToRejectAntrag', [$this->antraglib, 'isEntitledToRejectAntrag']],
],
[
'isEntitledToRejectAntrag' => $this->p->t('studierendenantrag', 'error_no_right')
]
);
$this->form_validation->set_rules('grund', 'Grund', 'required');
$this->form_validation->set_rules(
'typ',
'Typ',
'required|in_list[' . implode(',', [
Studierendenantrag_model::TYP_UNTERBRECHUNG
]) . ']'
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$grund = $this->input->post('grund');
$result = $this->antraglib->rejectUnterbrechung([$studierendenantrag_id], getAuthUID(), $grund);
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($studierendenantrag_id);
}
public function reopenAntrag()
{
$this->load->library('form_validation');
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
['isEntitledToReopenAntrag', [$this->antraglib, 'isEntitledToReopenAntrag']],
],
[
'isEntitledToReopenAntrag' => $this->p->t('studierendenantrag', 'error_no_right')
]
);
$this->form_validation->set_rules(
'typ',
'Typ',
'required|in_list[' . implode(',', [
Studierendenantrag_model::TYP_WIEDERHOLUNG
]) . ']'
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->reopenWiederholung($studierendenantrag_id, getAuthUID());
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($studierendenantrag_id);
}
public function pauseAntrag()
{
$this->load->library('form_validation');
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
['isEntitledToPauseAntrag', [$this->antraglib, 'isEntitledToPauseAntrag']],
['antragCanBeManualPaused', [$this->antraglib, 'antragCanBeManualPaused']]
],
[
'isEntitledToPauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'antragCanBeManualPaused' => $this->p->t(
'studierendenantrag',
'error_not_pauseable',
['id' => $this->input->post('studierendenantrag_id')]
)
]
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->pauseAntrag($studierendenantrag_id, getAuthUID());
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($studierendenantrag_id);
}
public function unpauseAntrag()
{
$this->load->library('form_validation');
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
['isEntitledToUnpauseAntrag', [$this->antraglib, 'isEntitledToUnpauseAntrag']],
['antragCanBeManualUnpaused', [$this->antraglib, 'antragCanBeManualUnpaused']]
],
[
'isEntitledToUnpauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'antragCanBeManualUnpaused' => $this->p->t(
'studierendenantrag',
'error_not_paused',
['id' => $this->input->post('studierendenantrag_id')]
)
]
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->unpauseAntrag($studierendenantrag_id, getAuthUID());
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($studierendenantrag_id);
}
public function objectAntrag()
{
$this->load->library('form_validation');
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
['isEntitledToObjectAntrag', [$this->antraglib, 'isEntitledToObjectAntrag']],
['canBeObjected', function ($a) {
return $this->antraglib->hasType($a, Studierendenantrag_model::TYP_ABMELDUNG_STGL);
}]
],
[
'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'canBeObjected' => $this->p->t(
'studierendenantrag',
'error_no_objection'
)
]
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->objectAbmeldung($studierendenantrag_id, getAuthUID());
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($studierendenantrag_id);
}
public function approveObjection()
{
$this->load->library('form_validation');
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
['isEntitledToObjectAntrag', [$this->antraglib, 'isEntitledToObjectAntrag']],
['isObjected', function ($a) {
return $this->antraglib->hasStatus($a, Studierendenantragstatus_model::STATUS_OBJECTED);
}]
],
[
'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'isObjected' => $this->p->t(
'studierendenantrag',
'error_not_objected'
)
]
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->cancelAntrag($studierendenantrag_id, getAuthUID());
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($studierendenantrag_id);
}
public function denyObjection()
{
$this->load->library('form_validation');
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
['isEntitledToObjectAntrag', [$this->antraglib, 'isEntitledToObjectAntrag']],
['isObjected', function ($a) {
return $this->antraglib->hasStatus($a, Studierendenantragstatus_model::STATUS_OBJECTED);
}]
],
[
'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'isObjected' => $this->p->t(
'studierendenantrag',
'error_not_objected'
)
]
);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$grund = $this->input->post('grund');
$result = $this->antraglib->denyObjectionAbmeldung($studierendenantrag_id, getAuthUID(), $grund);
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($studierendenantrag_id);
}
}
@@ -1,4 +1,20 @@
<?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');
@@ -6,23 +22,28 @@ use \Studierendenantrag_model as Studierendenantrag_model;
use \DateTime as DateTime;
/**
*
* This controller operates between (interface) the JS (GUI) and the AntragLib (back-end)
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Unterbrechung extends FHC_Controller
class Unterbrechung extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and loads the FilterCmptLib
* Calls the parent's constructor and loads the AntragLib
*/
public function __construct()
{
parent::__construct();
parent::__construct([
'getDetailsForNewAntrag' => self::PERM_LOGGED,
'getDetailsForAntrag' => self::PERM_LOGGED,
'createAntrag' => self::PERM_LOGGED,
'cancelAntrag' => self::PERM_LOGGED
]);
// Configs
$this->load->config('studierendenantrag');
// Libraries
$this->load->library('AuthLib');
$this->load->library('AntragLib');
// Load language phrases
@@ -38,74 +59,62 @@ class Unterbrechung extends FHC_Controller
public function getDetailsForNewAntrag($prestudent_id)
{
if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, false)) {
$this->output->set_status_header(403);
return $this->outputJsonError('Forbidden');
}
if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, false))
$this->terminateWithError('Forbidden', self::ERROR_TYPE_AUTH, REST_Controller::HTTP_FORBIDDEN);
$result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id);
if (isError($result)) {
$this->output->set_status_header(500);
return $this->outputJsonError(getError($result));
}
$result = $result->retval;
$result = $this->getDataOrTerminateWithError($result);
if (!$result) {
$this->output->set_status_header(403);
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_student'));
}
elseif ($result == -1)
{
$this->terminateWithError(
$this->p->t('studierendenantrag', 'error_no_student'),
self::ERROR_TYPE_AUTH,
REST_Controller::HTTP_FORBIDDEN
);
} elseif ($result == -1) {
$result = $this->antraglib->getDetailsForLastAntrag($prestudent_id, Studierendenantrag_model::TYP_UNTERBRECHUNG);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$data = $this->getDataOrTerminateWithError($result);
return $this->outputJsonSuccess(getData($result));
}
elseif ($result == -2)
{
return $this->terminateWithSuccess($data);
} elseif ($result == -2) {
$result = $this->antraglib->getDetailsForLastAntrag($prestudent_id);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$result = getData($result);
$this->output->set_status_header(400);
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_pending', [
$data = $this->getDataOrTerminateWithError($result);
return $this->terminateWithError($this->p->t('studierendenantrag', 'error_antrag_pending', [
'typ' => $this->p->t('studierendenantrag', 'antrag_typ_' . $result->typ)
]));
}
elseif ($result == -3)
{
$this->output->set_status_header(403);
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_stg_blacklist'));
}
$result = $this->antraglib->getDetailsForNewAntrag($prestudent_id);
if (isError($result)) {
return $this->outputJsonError(getError($result));
} elseif ($result == -3) {
$this->terminateWithError(
$this->p->t('studierendenantrag', 'error_stg_blacklist'),
self::ERROR_TYPE_AUTH,
REST_Controller::HTTP_FORBIDDEN
);
}
$data = getData($result);
$result = $this->antraglib->getDetailsForNewAntrag($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($prestudent_id, null);
$this->outputJsonSuccess($data);
$this->terminateWithSuccess($data);
}
public function getDetailsForAntrag($studierendenantrag_id)
{
if (!$this->antraglib->isEntitledToShowAntrag($studierendenantrag_id)) return show_404();
if (!$this->antraglib->isEntitledToShowAntrag($studierendenantrag_id))
return show_404();
$result = $this->antraglib->getDetailsForAntrag($studierendenantrag_id);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$data = getData($result);
$data = $this->getDataOrTerminateWithError($result);
if ($data->typ !== Studierendenantrag_model::TYP_UNTERBRECHUNG)
return show_404();
$this->outputJsonSuccess($data);
$this->terminateWithSuccess($data);
}
public function createAntrag()
@@ -125,9 +134,8 @@ class Unterbrechung extends FHC_Controller
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
if (!$this->form_validation->run()) {
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$grund = $this->input->post('grund');
@@ -137,25 +145,17 @@ class Unterbrechung extends FHC_Controller
$dms_id = null;
$result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester, $datum_wiedereinstieg);
if (isError($result)) {
return $this->outputJsonError(['db' => getError($result)]);
}
$result = $result->retval;
if (!$result)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]);
}
elseif ($result == -3)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_stg_blacklist')]);
}
elseif ($result < 0)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_antrag_exists')]);
}
if(isset($_FILES['attachment']) && (!isset($_FILES['attachment']['error']) || $_FILES['attachment']['error'] != UPLOAD_ERR_NO_FILE))
{
$result = $this->getDataOrTerminateWithError($result);
if (!$result)
$this->terminateWithError($this->p->t('studierendenantrag', 'error_no_student'), self::ERROR_TYPE_GENERAL);
elseif ($result == -3)
$this->terminateWithError($this->p->t('studierendenantrag', 'error_stg_blacklist'), self::ERROR_TYPE_GENERAL);
elseif ($result < 0)
$this->terminateWithError($this->p->t('studierendenantrag', 'error_antrag_exists'), self::ERROR_TYPE_GENERAL);
if (isset($_FILES['attachment']) && (!isset($_FILES['attachment']['error']) || $_FILES['attachment']['error'] != UPLOAD_ERR_NO_FILE)) {
$this->load->library('DmsLib');
$dms = $this->config->item('unterbrechung_dms');
@@ -167,53 +167,46 @@ class Unterbrechung extends FHC_Controller
$allowed_filetypes = $this->config->item('unterbrechung_dms_filetypes') ?: ['*'];
$result = $this->dmslib->upload($dms, 'attachment', $allowed_filetypes);
if(isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
$dms_id = getData($result)['dms_id'];
$data = $this->getDataOrTerminateWithError($result);
$dms_id = $data['dms_id'];
}
$result = $this->antraglib->createUnterbrechung($prestudent_id, $studiensemester, getAuthUID(), $grund, $datum_wiedereinstieg, $dms_id);
if(isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
$antragId = getData($result);
$antragId = $this->getDataOrTerminateWithError($result);
$result = $this->antraglib->getDetailsForAntrag($antragId);
if(!hasData($result))
return $this->outputJsonSuccess($antragId);
$this->outputJsonSuccess(getData($result));
if (!hasData($result))
$this->terminateWithSuccess($antragId);
$this->terminateWithSuccess(getData($result));
}
public function cancelAntrag()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules('antrag_id', 'Antrag ID', 'required');
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
if (!$this->form_validation->run()) {
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$antrag_id = $this->input->post('antrag_id');
$result = $this->antraglib->cancelAntrag($antrag_id, getAuthUID());
if (isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
$this->getDataOrTerminateWithError($result);
$result = $this->antraglib->getDetailsForAntrag($antrag_id);
if (!hasData($result))
return $this->outputJsonSuccess($antrag_id);
$this->outputJsonSuccess(getData($result));
return $this->terminateWithSuccess($antrag_id);
$this->terminateWithSuccess(getData($result));
}
public function isValidDate($date)
@@ -0,0 +1,258 @@
<?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 \REST_Controller as REST_Controller;
use \Studierendenantragstatus_model as Studierendenantragstatus_model;
/**
* This controller operates between (interface) the JS (GUI) and the AntragLib (back-end)
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Wiederholung extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and loads the FilterCmptLib
*/
public function __construct()
{
parent::__construct([
'getDetailsForNewAntrag' => self::PERM_LOGGED,
'createAntrag' => self::PERM_LOGGED,
'cancelAntrag' => self::PERM_LOGGED,
'getLvs' => self::PERM_LOGGED,
'saveLvs' => ['student/studierendenantrag:w']
]);
// Libraries
$this->load->library('AntragLib');
// Load language phrases
$this->loadPhrases([
'global',
'studierendenantrag'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Retrieves data of the current studiengang for the current user
*/
public function getDetailsForNewAntrag($prestudent_id)
{
if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, false))
$this->terminateWithError('Forbidden', self::ERROR_TYPE_AUTH, REST_Controller::HTTP_FORBIDDEN);
$result = $this->antraglib->getPrestudentWiederholungsBerechtigt($prestudent_id);
$result = $this->getDataOrTerminateWithError($result);
if (!$result) {
$this->terminateWithError(
$this->p->t('studierendenantrag', 'error_no_student_no_failed_exam'),
self::ERROR_TYPE_AUTH,
REST_Controller::HTTP_FORBIDDEN
);
} elseif ($result == -1) {
$result = $this->antraglib->getDetailsForLastAntrag($prestudent_id, Studierendenantrag_model::TYP_WIEDERHOLUNG);
$data = $this->getDataOrTerminateWithError($result);
$result = $this->antraglib->getFailedExamForPrestudent($prestudent_id, $data->datum, $data->studiensemester_kurzbz);
// NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt()
$pruefungsdata = current(getData($result));
$data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz;
$data->lvbezeichnung = $pruefungsdata->lvbezeichnung;
$data->pruefungsdatum = $pruefungsdata->datum;
$this->terminateWithSuccess($data);
} elseif ($result == -2) {
$result = $this->antraglib->getDetailsForLastAntrag($prestudent_id);
$result = $this->getDataOrTerminateWithError($result);
$this->terminateWithError(
$this->p->t('studierendenantrag', 'error_antrag_pending', [
'typ' => $this->p->t('studierendenantrag', 'antrag_typ_' . $result->typ)
]),
self::ERROR_TYPE_GENERAL,
REST_Controller::HTTP_BAD_REQUEST
);
} elseif ($result == -3) {
$this->terminateWithError(
$this->p->t('studierendenantrag', 'error_stg_blacklist'),
self::ERROR_TYPE_GENERAL,
REST_Controller::HTTP_BAD_REQUEST
);
}
$result = $this->antraglib->getDetailsForNewAntrag($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
$result = $this->antraglib->getFailedExamForPrestudent($prestudent_id);
// NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt()
$pruefungsdata = current(getData($result));
$data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz;
$data->lvbezeichnung = $pruefungsdata->lvbezeichnung;
$data->pruefungsdatum = $pruefungsdata->datum;
$this->terminateWithSuccess($data);
}
public function createAntrag()
{
$this->createAntragWithStatus(true);
}
public function cancelAntrag()
{
$this->createAntragWithStatus(false);
}
protected function createAntragWithStatus($repeat)
{
$this->load->library('form_validation');
$this->form_validation->set_rules('prestudent_id', 'Prestudent ID', 'required');
$this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$prestudent_id = $this->input->post('prestudent_id');
$studiensemester = $this->input->post('studiensemester');
$result = $this->antraglib->getPrestudentWiederholungsBerechtigt($prestudent_id);
$result = $this->getDataOrTerminateWithError($result);
if (!$result) {
$this->terminateWithError($this->p->t('studierendenantrag', 'error_no_student'), self::ERROR_TYPE_GENERAL);
} elseif ($result == -1) {
$result = $this->PrestudentstatusModel->getLastStatus($prestudent_id);
$result = $this->getDataOrTerminateWithError($result);
if (!$result)
$this->terminateWithError($this->p->t('studierendenantrag', 'error_no_prestudentstatus', [
'prestudent_id' => $prestudent_id
]), self::ERROR_TYPE_GENERAL);
if (!in_array(current($result)->status_kurzbz, $this->config->item('antrag_prestudentstatus_whitelist')))
$this->terminateWithError($this->p->t('studierendenantrag', 'error_no_student'), self::ERROR_TYPE_GENERAL);
} elseif ($result == -2) {
$this->terminateWithError($this->p->t('studierendenantrag', 'error_antrag_exists'), self::ERROR_TYPE_GENERAL);
} elseif ($result == -3) {
$this->terminateWithError($this->p->t('studierendenantrag', 'error_stg_blacklist'), self::ERROR_TYPE_GENERAL);
}
$result = $this->antraglib->createWiederholung($prestudent_id, $studiensemester, getAuthUID(), $repeat);
$antragId = $this->getDataOrTerminateWithError($result);
$result = $this->antraglib->getDetailsForAntrag($antragId);
if (!hasData($result))
$this->terminateWithSuccess(true);
$data = getData($result);
$result = $this->antraglib->getFailedExamForPrestudent($prestudent_id);
// NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt()
$pruefungsdata = current(getData($result));
$data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz;
$data->lvbezeichnung = $pruefungsdata->lvbezeichnung;
$data->pruefungsdatum = $pruefungsdata->datum;
$this->terminateWithSuccess($data);
}
public function getLvs($antrag_id)
{
$result = $this->antraglib->getLvsForAntrag($antrag_id);
if (isError($result)) {
$error = getError($result);
if ($error == 'Forbidden')
$this->terminateWithError(
$error,
self::ERROR_TYPE_AUTH,
REST_Controller::HTTP_FORBIDDEN
);
$this->terminateWithError(
$error,
self::ERROR_TYPE_GENERAL
);
}
$lvs = getData($result);
$this->terminateWithSuccess($lvs);
}
public function saveLvs()
{
$forbiddenLvs = $this->input->post('forbiddenLvs');
$mandatoryLvs = $this->input->post('mandatoryLvs');
$antragsLvs = array_merge($forbiddenLvs, $mandatoryLvs);
if (!$antragsLvs)
$this->terminateWithError($this->p->t('studierendenantrag', 'error_no_lv'), self::ERROR_TYPE_GENERAL);
$insert = array_map(function ($lv) {
return [
'studierendenantrag_id' => $lv['studierendenantrag_id'],
'lehrveranstaltung_id' => $lv['lehrveranstaltung_id'],
'note' => $lv['zugelassen']
? ($lv['zugelassen'] == 1 ? 0 : $this->config->item('wiederholung_note_angerechnet'))
: $this->config->item('wiederholung_note_nicht_zugelassen'),
'anmerkung' => $lv['anmerkung'],
'insertvon' => getAuthUID(),
'studiensemester_kurzbz' => $lv['studiensemester_kurzbz']
];
}, $antragsLvs);
$antrag_ids = array_unique(array_map(function ($lv) {
return $lv['studierendenantrag_id'];
}, $insert));
foreach ($antrag_ids as $antrag_id) {
$result = $this->StudierendenantragModel->loadIdAndStatusWhere([
'studierendenantrag_id' => $antrag_id
]);
$antrag = $this->getDataOrTerminateWithError($result);
if (!$antrag)
$this->terminateWithError(
$this->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $antrag_id]),
self::ERROR_TYPE_GENERAL
);
$antrag = current($antrag);
if ($antrag->status != Studierendenantragstatus_model::STATUS_CREATED
&& $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED)
$this->terminateWithError(
$this->p->t('studierendenantrag', 'error_antrag_locked'),
self::ERROR_TYPE_GENERAL
);
}
$result = $this->antraglib->saveLvs($insert);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,66 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about addresses
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Address extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getNations' => self::PERM_LOGGED,
'getPlaces' => self::PERM_LOGGED
]);
}
public function getNations()
{
$this->load->model('codex/Nation_model', 'NationModel');
$this->NationModel->addOrder('kurztext');
$result = $this->NationModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getPlaces($plz)
{
$this->load->model('codex/Gemeinde_model', 'GemeindeModel');
$this->load->library('form_validation');
$this->form_validation->set_data(['address.plz' => $plz]);
$this->form_validation->set_rules('address.plz', 'PLZ', 'numeric|less_than[10000]');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$result = $this->GemeindeModel->getGemeindeByPlz($plz);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,233 @@
<?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 StV 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()
{
// TODO(chris): permissions
parent::__construct([
'student' => ['admin:r', 'assistenz:r'],
'students' => ['admin:r', 'assistenz:r']
]);
// Load Phrases
$this->loadPhrases([
'global',
'person',
'lehre',
'stv',
'konto'
]);
}
public function student()
{
$result = [];
$result['details'] = [
'title' => $this->p->t('stv', 'tab_details'),
'component' => './Stv/Studentenverwaltung/Details/Details.js'
];
$result['notes'] = [
'title' => $this->p->t('stv', 'tab_notes'),
'component' => './Stv/Studentenverwaltung/Details/Notizen.js'
];
$result['contact'] = [
'title' => $this->p->t('stv', 'tab_contact'),
'component' => './Stv/Studentenverwaltung/Details/Kontakt.js',
'config' => [
'showBankaccount' => $this->permissionlib->isBerechtigt('mitarbeiter/bankdaten')
|| $this->permissionlib->isBerechtigt('student/bankdaten')
]
];
$result['prestudent'] = [
'title' => $this->p->t('stv', 'tab_prestudent'),
'component' => './Stv/Studentenverwaltung/Details/Prestudent.js'
];
$result['status'] = [
'title' => 'Status',
'component' => './Stv/Studentenverwaltung/Details/MultiStatus.js'
];
$result['banking'] = [
'title' => $this->p->t('stv', 'tab_banking'),
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
'config' => [
'showZahlungsbestaetigung' => (defined('ZAHLUNGSBESTAETIGUNG_ANZEIGEN') && ZAHLUNGSBESTAETIGUNG_ANZEIGEN),
'showBuchungsnr' => $this->permissionlib->isBerechtigt('admin'),
'showMahnspanne' => (!defined('FAS_KONTO_SHOW_MAHNSPANNE') || FAS_KONTO_SHOW_MAHNSPANNE===true),
'showCreditpoints' => (defined('FAS_KONTO_SHOW_CREDIT_POINTS') && FAS_KONTO_SHOW_CREDIT_POINTS == 'true'),
'columns' => $this->kontoColumns(),
'additionalCols' => []
]
];
$result['resources'] = [
'title' => $this->p->t('stv', 'tab_resources'),
'component' => './Stv/Studentenverwaltung/Details/Betriebsmittel.js'
];
/* TODO(chris): Ausgeblendet für Testing
$result['grades'] = [
'title' => $this->p->t('stv', 'tab_grades'),
'component' => './Stv/Studentenverwaltung/Details/Noten.js'
];
*/
Events::trigger('stv_conf_student', function & () use (&$result) {
return $result;
});
$this->terminateWithSuccess($result);
}
public function students()
{
$result = [];
$result['banking'] = [
'title' => $this->p->t('stv', 'tab_banking'),
'component' => './Stv/Studentenverwaltung/Details/Konto.js',
'config' => [
'showZahlungsbestaetigung' => (defined('ZAHLUNGSBESTAETIGUNG_ANZEIGEN') && ZAHLUNGSBESTAETIGUNG_ANZEIGEN),
'showBuchungsnr' => $this->permissionlib->isBerechtigt('admin'),
'showMahnspanne' => (!defined('FAS_KONTO_SHOW_MAHNSPANNE') || FAS_KONTO_SHOW_MAHNSPANNE===true),
'showCreditpoints' => (defined('FAS_KONTO_SHOW_CREDIT_POINTS') && FAS_KONTO_SHOW_CREDIT_POINTS == 'true'),
'columns' => $this->kontoColumnsMultiPerson(),
'additionalCols' => []
]
];
$result['status'] = [
'title' => 'Status',
'component' => './Stv/Studentenverwaltung/Details/MultiStatus.js',
'config' => [
'changeStatusToAbbrecherStgl' => $this->permissionlib->isBerechtigt('admin'),
'changeStatusToAbbrecherStud' => $this->permissionlib->isBerechtigt('admin'),
'changeStatusToUnterbrecher' => $this->permissionlib->isBerechtigt('admin'),
'changeStatusToDiplomand' => $this->permissionlib->isBerechtigt('admin'),
'changeStatusToAbsolvent' => $this->permissionlib->isBerechtigt('admin')
]
];
Events::trigger('stv_conf_students', function & () use (&$result) {
return $result;
});
$this->terminateWithSuccess($result);
}
protected function kontoColumns()
{
return [
'buchungsdatum' => [
'field' => "buchungsdatum",
'title' => $this->p->t('konto', 'buchungsdatum')
],
'buchungstext' => [
'field' => "buchungstext",
'title' => $this->p->t('konto', 'buchungstext')
],
'betrag' => [
'field' => "betrag",
'title' => $this->p->t('konto', 'betrag')
],
'studiensemester_kurzbz' => [
'field' => "studiensemester_kurzbz",
'title' => $this->p->t('lehre', 'studiensemester')
],
'buchungstyp_kurzbz' => [
'field' => "buchungstyp_kurzbz",
'title' => $this->p->t('konto', 'buchungstyp'),
'visible' => false
],
'buchungsnr' => [
'field' => "buchungsnr",
'title' => $this->p->t('konto', 'buchungsnr'),
'visible' => false
],
'insertvon' => [
'field' => "insertvon",
'title' => $this->p->t('global', 'insertvon'),
'visible' => false
],
'insertamum' => [
'field' => "insertamum",
'title' => $this->p->t('global', 'insertamum'),
'visible' => false
],
'kuerzel' => [
'field' => "kuerzel",
'title' => $this->p->t('lehre', 'studiengang'),
'visible' => false
],
'anmerkung' => [
'field' => "anmerkung",
'title' => $this->p->t('global', 'anmerkung')
],
'actions' => [
'title' => $this->p->t('global', 'actions'),
'frozen' => true
]
];
}
protected function kontoColumnsMultiPerson()
{
return [
'person_id' => [
'field' => "person_id",
'title' => $this->p->t('person', 'person_id')
],
'anrede' => [
'field' => "anrede",
'title' => $this->p->t('person', 'anrede'),
'visible' => false
],
'titelpost' => [
'field' => "titelpost",
'title' => $this->p->t('person', 'titelpost'),
'visible' => false
],
'titelpre' => [
'field' => "titelpre",
'title' => $this->p->t('person', 'titelpre'),
'visible' => false
],
'vorname' => [
'field' => "vorname",
'title' => $this->p->t('person', 'vorname')
],
'vornamen' => [
'field' => "vornamen",
'title' => $this->p->t('person', 'vornamen'),
'visible' => false
],
'nachname' => [
'field' => "nachname",
'title' => $this->p->t('person', 'nachname')
]
] + $this->kontoColumns();
}
}
@@ -0,0 +1,71 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about favorite verbände
* Listens to ajax post calls to change the favorite verbände data
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Favorites extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'index' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED
]);
// Load models
$this->load->model('system/Variable_model', 'VariableModel');
// TODO(chris): variable table might be to small to store favorites!
}
public function index()
{
$result = $this->VariableModel->getVariables(getAuthUID(), ['stv_favorites']);
$data = $this->getDataOrTerminateWithError($result);
if (!$data)
$this->terminateWithSuccess(null);
else
$this->terminateWithSuccess($data['stv_favorites']);
}
public function set()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('favorites', 'Favorites', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$favorites = $this->input->post('favorites');
$result = $this->VariableModel->setVariable(getAuthUID(), 'stv_favorites', $favorites);
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
}
}
@@ -0,0 +1,84 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about the Studiengang filter
* Listens to ajax post calls to change the Studiengang filter data
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Filter extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and prepares libraries and phrases
*/
public function __construct()
{
parent::__construct([
'getStg' => self::PERM_LOGGED,
'setStg' => self::PERM_LOGGED
]);
// Load models
$this->load->model('system/Variable_model', 'VariableModel');
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Get current setting
*
* @return void
*/
public function getStg()
{
$result = $this->VariableModel->getVariables(getAuthUID(), ['kontofilterstg']);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data['kontofilterstg'] == 'true');
}
/**
* Set current setting
*
* @return void
*/
public function setStg()
{
$this->load->library('form_validation');
$studiengang_kz = $this->input->post('studiengang_kz');
if ($studiengang_kz === null) {
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$result = $this->VariableModel->setVariable(getAuthUID(), 'kontofilterstg', $studiengang_kz ? 'true' : 'false');
$this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(true);
}
}
@@ -0,0 +1,754 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Kontakt extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getAdressen' => ['admin:r', 'assistenz:r'],
'addNewAddress' => ['admin:rw', 'assistenz:rw'],
'addNewContact' => ['admin:rw', 'assistenz:rw'],
'addNewBankverbindung' => ['mitarbeiter/bankdaten:rw', 'student/bankdaten:rw'],
'updateAddress' => ['admin:rw', 'assistenz:rw'],
'updateContact' => ['admin:rw', 'assistenz:rw'],
'updateBankverbindung' => ['mitarbeiter/bankdaten:rw', 'student/bankdaten:rw'],
'loadAddress' => ['admin:r', 'assistenz:r'],
'loadContact' => ['admin:r', 'assistenz:r'],
'loadBankverbindung' => ['mitarbeiter/bankdaten:r', 'student/bankdaten:r'],
'deleteAddress' => ['admin:rw', 'assistenz:rw'],
'deleteContact' => ['admin:rw','assistenz:rw'],
'deleteBankverbindung' => ['mitarbeiter/bankdaten:rw','astudent/bankdaten:rw'],
'getAdressentypen' => ['admin:r', 'assistenz:r'],
'getKontakttypen' => ['admin:r', 'assistenz:r'],
'getFirmen' => ['admin:r', 'assistenz:r'],
'getStandorte' => ['admin:r', 'assistenz:r'],
'getStandorteByFirma' => ['admin:r', 'assistenz:r'],
'getKontakte' => ['admin:r', 'assistenz:r'],
'getBankverbindung' => ['mitarbeiter/bankdaten:r', 'student/bankdaten:r']
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$this->load->library('form_validation');
// Load language phrases
$this->loadPhrases([
'ui',
'person'
]);
// Load models
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->load->model('organisation/standort_model', 'StandortModel');
$this->load->model('ressource/firma_model', 'FirmaModel');
$this->load->model('person/Kontakt_model', 'KontaktModel');
// Extra Permissionchecks
$permsMa = [];
$permsStud = [];
switch ($this->router->method) {
case 'getBankverbindung':
case 'loadBankverbindung':
$permsMa = ['mitarbeiter/bankdaten:r'];
$permsStud = ['student/bankdaten:r'];
break;
case 'addNewBankverbindung':
case 'updateBankverbindung':
case 'deleteBankverbindung':
$permsMa = ['mitarbeiter/bankdaten:rw'];
$permsStud = ['student/bankdaten:rw'];
break;
case 'getAdressen':
case 'getKontakte':
case 'loadAddress':
case 'loadContact':
$permsMa = $permsStud = ['admin:r', 'assistenz:r'];
break;
case 'addNewAddress':
case 'addNewContact':
case 'updateAddress':
case 'updateContact':
case 'deleteAddress':
case 'deleteContact':
$permsMa = $permsStud = ['admin:rw', 'assistenz:rw'];
break;
}
if ($this->router->method == 'getAdressen'
|| $this->router->method == 'getKontakte'
|| $this->router->method == 'getBankverbindung'
|| $this->router->method == 'addNewAddress'
|| $this->router->method == 'addNewContact'
|| $this->router->method == 'addNewBankverbindung'
) {
$person_id = current(array_slice($this->uri->rsegments, 2));
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud);
} elseif ($this->router->method == 'loadAddress'
|| $this->router->method == 'loadContact'
|| $this->router->method == 'loadBankverbindung'
|| $this->router->method == 'updateAddress'
|| $this->router->method == 'updateContact'
|| $this->router->method == 'updateBankverbindung'
|| $this->router->method == 'deleteAddress'
|| $this->router->method == 'deleteContact'
|| $this->router->method == 'deleteBankverbindung'
) {
$id = current(array_slice($this->uri->rsegments, 2));
$model = 'person/Adresse_model';
if ($this->router->method == 'loadContact'
|| $this->router->method == 'updateContact'
|| $this->router->method == 'deleteContact'
) {
$model = 'person/Kontakt_model';
} elseif ($this->router->method == 'loadBankverbindung'
|| $this->router->method == 'updateBankverbindung'
|| $this->router->method == 'deleteBankverbindung'
) {
$model = 'person/Bankverbindung_model';
}
$this->load->model($model, 'TempModel');
$result = $this->TempModel->load($id);
$data = $this->getDataOrTerminateWithError($result);
if (!$result)
show_404();
$person_id = current($data)->person_id;
$this->checkPermissionsForPerson($person_id, $permsMa, $permsStud);
}
}
public function getAdressen($person_id)
{
$this->AdresseModel->addSelect('public.tbl_adresse.*');
$this->AdresseModel->addSelect('t.*');
$this->AdresseModel->addSelect('f.firma_id');
$this->AdresseModel->addSelect('f.name as firmenname');
$this->AdresseModel->addJoin('public.tbl_adressentyp t', 'ON (t.adressentyp_kurzbz = public.tbl_adresse.typ)');
$this->AdresseModel->addJoin('public.tbl_firma f', 'ON (f.firma_id = public.tbl_adresse.firma_id)', 'LEFT');
$result = $this->AdresseModel->loadWhere(
array('person_id' => $person_id)
);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function addNewAddress($person_id)
{
$this->form_validation->set_rules('plz', 'PLZ', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ'])
]);
if(isset($_POST['gemeinde']) && isset($_POST['ort']))
$this->form_validation->set_rules('plz', 'Postleitzahl', 'callback_validateLocationCombination', [
'validateLocationCombination' => $this->p->t('ui', 'error_location_combination')
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$uid = getAuthUID();
$co_name = isset($_POST['co_name']) ? $_POST['co_name'] : null;
$strasse = isset($_POST['strasse']) ? $_POST['strasse'] : null;
$ort = isset($_POST['ort']) ? $_POST['ort'] : null;
$gemeinde = isset($_POST['gemeinde']) ? $_POST['gemeinde'] : null;
$nation = isset($_POST['nation']) ? $_POST['nation'] : null;
$name = isset($_POST['name']) ? $_POST['name'] : null;
$typ = isset($_POST['typ']) ? $_POST['typ'] : null;
$anmerkung = isset($_POST['anmerkung']) ? $_POST['anmerkung'] : null;
if(isset($_POST['firma']))
{
$firma_id = $_POST['firma']['firma_id'];
}
else
$firma_id = null;
$result = $this->AdresseModel->insert(
[
'person_id' => $person_id,
'strasse' => $strasse,
'insertvon' => $uid,
'insertamum' => date('c'),
'plz' => $_POST['plz'],
'ort' => $ort,
'gemeinde' => $gemeinde,
'nation' => $nation,
'heimatadresse' => $_POST['heimatadresse'],
'zustelladresse' => $_POST['zustelladresse'],
'co_name' => $co_name,
'typ' => $typ,
'firma_id' => $firma_id,
'name' => $name,
'rechnungsadresse' => $_POST['rechnungsadresse'],
'anmerkung' => $anmerkung
]
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
}
public function updateAddress($address_id)
{
$uid = getAuthUID();
$this->form_validation->set_rules('plz', 'PLZ', 'required|numeric', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'PLZ']),
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'PLZ'])
]);
if(isset($_POST['gemeinde']) && isset($_POST['ort']))
$this->form_validation->set_rules('plz', 'Postleitzahl', 'callback_validateLocationCombination', [
'validateLocationCombination' => $this->p->t('ui', 'error_location_combination')
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->load->model('person/Adresse_model', 'AdresseModel');
if(!$address_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Adresse_id']), self::ERROR_TYPE_GENERAL);
}
if(isset($_POST['firma']))
{
$firma_id = $_POST['firma']['firma_id'];
}
elseif(isset($_POST['firma_id']))
{
$firma_id = $_POST['firma_id'];
}
else
$firma_id = null;
$person_id = isset($_POST['person_id']) ? $_POST['person_id'] : null;
$co_name = isset($_POST['co_name']) ? $_POST['co_name'] : null;
$strasse = isset($_POST['strasse']) ? $_POST['strasse'] : null;
$ort = isset($_POST['ort']) ? $_POST['ort'] : null;
$gemeinde = isset($_POST['gemeinde']) ? $_POST['gemeinde'] : null;
$nation = isset($_POST['nation']) ? $_POST['nation'] : null;
$name = isset($_POST['name']) ? $_POST['name'] : null;
$typ = isset($_POST['typ']) ? $_POST['typ'] : null;
$anmerkung = isset($_POST['anmerkung']) ? $_POST['anmerkung'] : null;
$result = $this->AdresseModel->update(
[
'adresse_id' => $address_id
],
[ 'person_id' => $person_id,
'strasse' => $strasse,
'updatevon' => $uid,
'updateamum' => date('c'),
'plz' => $_POST['plz'],
'ort' => $ort,
'gemeinde' => $gemeinde,
'nation' => $nation,
'heimatadresse' => $_POST['heimatadresse'],
'zustelladresse' => $_POST['zustelladresse'],
'co_name' => $co_name,
'typ' => $typ,
'firma_id' => $firma_id,
'name' => $name,
'rechnungsadresse' => $_POST['rechnungsadresse'],
'anmerkung' => $anmerkung
]
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
}
public function loadAddress($adresse_id)
{
$this->load->model('person/Adresse_model', 'AdresseModel');
$this->AdresseModel->addSelect('public.tbl_adresse.*');
$this->AdresseModel->addSelect('t.*');
$this->AdresseModel->addSelect('f.firma_id');
$this->AdresseModel->addSelect('f.name as firmenname');
$this->AdresseModel->addJoin('public.tbl_adressentyp t', 'ON (t.adressentyp_kurzbz = public.tbl_adresse.typ)');
$this->AdresseModel->addJoin('public.tbl_firma f', 'ON (f.firma_id = public.tbl_adresse.firma_id)', 'LEFT');
$this->AdresseModel->addLimit(1);
$result = $this->AdresseModel->loadWhere(
array('adresse_id' => $adresse_id)
);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Adresse_id']), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(current(getData($result)) ? : null);
}
public function deleteAddress($adresse_id)
{
$this->load->model('person/Adresse_model', 'AdresseModel');
$result = $this->AdresseModel->load([
'adresse_id'=> $adresse_id,
]);
if(isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$result = current(getData($result));
if($result->heimatadresse)
$this->terminateWithError($this->p->t('person', 'error_deleteHomeAdress'), self::ERROR_TYPE_GENERAL);
$result = $this->AdresseModel->delete(
array('adresse_id' => $adresse_id)
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Adresse_id']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)) ? : null);
}
public function getAdressentypen()
{
$this->load->model('person/Adressentyp_model', 'AdressentypModel');
$result = $this->AdressentypModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(getData($result) ?: []);
}
public function getFirmen($searchString)
{
$this->load->model('ressource/firma_model', 'FirmaModel');
$result = $this->FirmaModel->searchFirmen($searchString);
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess($result ?: []);
}
public function getStandorte($searchString)
{
$this->load->model('organisation/standort_model', 'StandortModel');
$result = $this->StandortModel->searchStandorte($searchString);
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess($result ?: []);
}
public function getStandorteByFirma($firma_id)
{
$this->load->model('organisation/standort_model', 'StandortModel');
$result = $this->StandortModel->getStandorteByFirma($firma_id);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getKontakte($person_id)
{
$this->KontaktModel->addSelect("public.tbl_kontakt.*,
TO_CHAR (CASE
WHEN public.tbl_kontakt.updateamum >= public.tbl_kontakt.insertamum
THEN public.tbl_kontakt.updateamum
ELSE public.tbl_kontakt.insertamum
END::timestamp, 'DD.MM.YYYY HH24:MI:SS') AS lastUpdate, st.bezeichnung, f.name");
$this->StandortModel->addJoin('public.tbl_standort st', 'ON (public.tbl_kontakt.standort_id = st.standort_id)', 'LEFT');
$this->FirmaModel->addJoin('public.tbl_firma f', 'ON (f.firma_id = st.firma_id)', 'LEFT');
$result = $this->KontaktModel->loadWhere(
array('person_id' => $person_id)
);
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function getKontakttypen()
{
$this->load->model('person/Kontakttyp_model', 'KontakttypModel');
$result = $this->KontakttypModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
else
{
$this->terminateWithSuccess(getData($result) ?: []);
}
}
public function loadContact($kontakt_id)
{
$this->load->model('person/Kontakt_model', 'KontaktModel');
$this->KontaktModel->addSelect('*, public.tbl_kontakt.*');
$this->KontaktModel->addSelect('st.kurzbz');
$this->KontaktModel->addJoin('public.tbl_standort st', 'ON (public.tbl_kontakt.standort_id = st.standort_id)', 'LEFT');
$this->FirmaModel->addJoin('public.tbl_firma f', 'ON (f.firma_id = st.firma_id)', 'LEFT');
$this->KontaktModel->addLimit(1);
$result = $this->KontaktModel->loadWhere(
array('kontakt_id' => $kontakt_id)
);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Kontakt_id']), self::ERROR_TYPE_GENERAL);
}
// $this->outputJsonSuccess(current(getData($result)));
$this->terminateWithSuccess(current(getData($result)));
}
public function addNewContact($person_id)
{
if(($_POST['kontakttyp'] == 'email' && isset($_POST['kontakt'])))
{
$this->form_validation->set_rules('kontakt', 'Kontakt', 'required|valid_email', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Kontakt']),
'valid_email' => $this->p->t('ui', 'error_fieldNoValidEmail', ['field' => 'Kontakt'])
]);
}
else
{
$this->form_validation->set_rules('kontakt', 'Kontakt', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Kontakt'])
]);
}
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->load->model('person/Kontakt_model', 'KontaktModel');
$uid = getAuthUID();
$kontakttyp = $this->input->post('kontakttyp');
$anmerkung = $this->input->post('anmerkung');
$kontakt = $this->input->post('kontakt');
$ext_id = $this->input->post('ext_id');
$standort_id = $this->input->post('standort_id');
$result = $this->KontaktModel->insert(
[
'person_id' => $person_id,
'kontakttyp' => $kontakttyp,
'anmerkung' => $anmerkung,
'kontakt' => $kontakt,
'zustellung' => $_POST['zustellung'],
'insertvon' => $uid,
'insertamum' => date('c'),
'standort_id' => $standort_id,
'ext_id' => $ext_id
]
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
}
public function updateContact($kontakt_id)
{
$this->load->model('person/Kontakt_model', 'KontaktModel');
if(!$kontakt_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Kontakt_id']), self::ERROR_TYPE_GENERAL);
}
if(($_POST['kontakttyp'] == 'email' && isset($_POST['kontakt'])))
{
$this->form_validation->set_rules('kontakt', 'Kontakt', 'required|valid_email', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Kontakt']),
'valid_email' => $this->p->t('ui', 'error_fieldNoValidEmail', ['field' => 'Kontakt'])
]);
}
else
{
$this->form_validation->set_rules('kontakt', 'Kontakt', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Kontakt'])
]);
}
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
/* if(isset($_POST['standort']))
{
$standort_id = $_POST['standort']['standort_id'];
}
else
$standort_id = null;*/
$uid = getAuthUID();
$kontakttyp = $this->input->post('kontakttyp');
$anmerkung = $this->input->post('anmerkung');
$kontakt = $this->input->post('kontakt');
$ext_id = $this->input->post('ext_id');
$person_id = $this->input->post('person_id');
$standort_id = $this->input->post('standort_id');
//return $this->terminateWithError("in update " . $standort_id, self::ERROR_TYPE_GENERAL);
$result = $this->KontaktModel->update(
[
'kontakt_id' => $kontakt_id
],
[
'person_id' => $person_id,
'kontakttyp' => $kontakttyp,
'anmerkung' => $anmerkung,
'kontakt' => $kontakt,
'zustellung' => $_POST['zustellung'],
'insertvon' => $uid,
'insertamum' => date('c'),
'standort_id' => $standort_id,
'ext_id' => $ext_id
]
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
}
public function deleteContact($kontakt_id)
{
$this->load->model('person/Kontakt_model', 'KontaktModel');
$result = $this->KontaktModel->delete(
array('kontakt_id' => $kontakt_id)
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
elseif (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Kontakt_id']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)) ? : null);
}
public function getBankverbindung($person_id)
{
$this->load->model('person/Bankverbindung_model', 'BankverbindungModel');
$this->BankverbindungModel->addSelect('*');
$result = $this->BankverbindungModel->loadWhere(
array('person_id' => $person_id)
);
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess((getData($result) ?: []));
}
public function addNewBankverbindung($person_id)
{
$this->form_validation->set_rules('iban', 'IBAN', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'IBAN'])
]);
$this->form_validation->set_rules('typ', 'TYP', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'TYP'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->load->model('person/Bankverbindung_model', 'BankverbindungModel');
$ext_id = $this->input->post('ext_id');
$oe_kurzbz = $this->input->post('oe_kurzbz');
$orgform_kurzbz = $this->input->post('orgform_kurzbz');
$name = $this->input->post('name');
$anschrift = $this->input->post('anschrift');
$bic = $this->input->post('bic');
$blz = $this->input->post('blz');
$kontonr = $this->input->post('kontonr');
$result = $this->BankverbindungModel->insert(
[
'person_id' => $person_id,
'name' => $name,
'anschrift' => $anschrift,
'bic' => $bic,
'iban' => $_POST['iban'],
'blz' => $blz,
'kontonr' => $kontonr,
'insertvon' => 'uid',
'insertamum' => date('c'),
'typ' => $_POST['typ'],
'verrechnung' => $_POST['verrechnung'],
'ext_id' => $ext_id,
'oe_kurzbz' => $oe_kurzbz,
'orgform_kurzbz' => $orgform_kurzbz
]
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
}
public function loadBankverbindung($bankverbindung_id)
{
$this->load->model('person/Bankverbindung_model', 'BankverbindungModel');
$this->BankverbindungModel->addSelect('*');
$this->BankverbindungModel->addLimit(1);
$result = $this->BankverbindungModel->loadWhere(
array('bankverbindung_id' => $bankverbindung_id)
);
if (isError($result))
{
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Bankverbindung_id']), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(current(getData($result)));
}
public function updateBankverbindung($bankverbindung_id)
{
$this->form_validation->set_rules('iban', 'IBAN', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'IBAN'])
]);
$this->form_validation->set_rules('typ', 'TYP', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'TYP'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$this->load->model('person/Bankverbindung_model', 'BankverbindungModel');
if(!$bankverbindung_id)
{
return $this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=> 'Bankverbindung_id']), self::ERROR_TYPE_GENERAL);
}
$uid = getAuthUID();
$result = $this->BankverbindungModel->update(
[
'bankverbindung_id' => $bankverbindung_id
],
[
'person_id' => $_POST['person_id'],
'name' => $_POST['name'],
'anschrift' => $_POST['anschrift'],
'bic' => $_POST['bic'],
'iban' => $_POST['iban'],
'blz' => $_POST['blz'],
'kontonr' => $_POST['kontonr'],
'updatevon' => $uid,
'updateamum' => date('c'),
'typ' => $_POST['typ'],
'verrechnung' => $_POST['verrechnung'],
'ext_id' => $_POST['ext_id'],
'oe_kurzbz' => $_POST['oe_kurzbz'],
'orgform_kurzbz' => $_POST['orgform_kurzbz']
]
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->outputJsonSuccess(true);
}
public function deleteBankverbindung($bankverbindung_id)
{
$this->load->model('person/Bankverbindung_model', 'BankverbindungModel');
$result = $this->BankverbindungModel->delete(
array('bankverbindung_id' => $bankverbindung_id)
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if (!hasData($result))
{
$this->outputJson($result);
}
return $this->terminateWithSuccess(current(getData($result)) ? : null);
}
public function validateLocationCombination()
{
$this->load->model('codex/Gemeinde_model', 'GemeindeModel');
return $this->GemeindeModel->checkLocation($_POST['plz'], $_POST['gemeinde'], $_POST['ort']);
}
}
@@ -0,0 +1,495 @@
<?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 a Konto
* Listens to ajax post calls to change the Konto data
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Konto extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and prepares libraries and phrases
*/
public function __construct()
{
parent::__construct([
'get' => 'student/stammdaten:r',
'getBuchungstypen' => self::PERM_LOGGED,
'checkDoubles' => ['admin:r', 'assistenz:r'],
'insert' => ['admin:w', 'assistenz:w'],
'counter' => ['admin:w', 'assistenz:w'],
'update' => ['admin:w', 'assistenz:w'],
'delete' => ['admin:w', 'assistenz:w']
]);
// Load models
$this->load->model('crm/Konto_model', 'KontoModel');
// Load language phrases
$this->loadPhrases([
'konto'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Get details for a prestudent
*
* @return void
*/
public function get()
{
$this->load->library('form_validation');
$person_id = $this->input->post('person_id');
if (!$person_id || !is_array($person_id)) {
$this->form_validation->set_rules('person_id', 'Person ID', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$studiengang_kz = $this->input->post('studiengang_kz');
if ($this->input->post('only_open')) {
$result = $this->KontoModel->getOffeneBuchungen($person_id, $studiengang_kz);
} else {
$result = $this->KontoModel->getAlleBuchungen($person_id, $studiengang_kz);
}
$result = $this->getDataOrTerminateWithError($result);
// sort into tree
$childs = [];
$data = [];
foreach ($result as $entry) {
if ($entry->buchungsnr_verweis) {
if (isset($data[$entry->buchungsnr_verweis])) {
if (!isset($data[$entry->buchungsnr_verweis]->_children))
$data[$entry->buchungsnr_verweis]->_children = [];
$data[$entry->buchungsnr_verweis]->_children[] = $entry;
} else {
if (!isset($childs[$entry->buchungsnr_verweis]))
$childs[$entry->buchungsnr_verweis] = [];
$childs[$entry->buchungsnr_verweis][] = $entry;
}
} else {
$data[$entry->buchungsnr] = $entry;
if (isset($childs[$entry->buchungsnr]))
$entry->_children = $childs[$entry->buchungsnr];
}
}
$this->terminateWithSuccess(array_values($data));
}
/**
* Get list of Buchungstypen
*
* @return void
*/
public function getBuchungstypen()
{
$this->load->model('crm/Buchungstyp_model', 'BuchungstypModel');
$result = $this->BuchungstypModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* Check double Buchungen
*
* @return void
*/
public function checkDoubles()
{
if (!defined('FAS_DOPPELTE_BUCHUNGSTYPEN_CHECK') || !FAS_DOPPELTE_BUCHUNGSTYPEN_CHECK)
$this->terminateWithSuccess(false);
$this->load->library('form_validation');
$person_ids = $this->input->post('person_id');
if (!$person_ids || !is_array($person_ids)) {
$person_ids = [$person_ids];
$this->form_validation->set_rules('person_id', 'Person ID', 'required');
}
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required');
$this->form_validation->set_rules('buchungstyp_kurzbz', 'Buchungstyp', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$buchungstypen = unserialize(FAS_DOPPELTE_BUCHUNGSTYPEN_CHECK);
$buchung = $this->input->post('buchungstyp_kurzbz');
if (!isset($buchungstypen[$buchung]))
$this->terminateWithSuccess(false);
$result = $this->KontoModel->checkDoubleBuchung($person_ids, $this->input->post('studiensemester_kurzbz'), $buchungstypen[$buchung]);
$result = $this->getDataOrTerminateWithError($result);
if (!$result)
$this->terminateWithSuccess(false);
$persons = array_map(function ($row) {
return $row->nachname . ' ' . $row->vorname;
}, $result);
$result = $this->p->t('konto', 'confirm_overwrite') . "\n";
if (count($persons) > 10) {
$result .= "-" . implode("\n-", array_slice($persons, 0, 10)) . "\n";
if (count($persons) == 11) {
$result .= "\n" . $this->p->t('konto', 'confirm_overwrite_1_add_pers');
} else {
$result .= "\n" . $this->p->t('konto', 'confirm_overwrite_x_add_pers', [
'x' => count($persons) - 10
]);
}
} else {
$result .= "-" . implode("\n-", $persons) . "\n";
}
$result .= $this->p->t('konto', 'confirm_overwrite_proceed');
$this->addError($result, 'confirm');
$this->terminateWithSuccess(true);
}
/**
* Save Buchung
*
* @return void
*/
public function insert()
{
$this->load->library('form_validation');
$person_ids = $this->input->post('person_id');
if (!$person_ids || !is_array($person_ids)) {
$person_ids = [$person_ids];
$this->form_validation->set_rules('person_id', 'Person ID', 'required');
}
$this->form_validation->set_rules('betrag', 'Betrag', 'numeric');
$this->form_validation->set_rules('buchungsdatum', 'Buchungsdatum', 'is_valid_date');
$this->form_validation->set_rules('buchungstext', 'Buchungstext', 'max_length[256]');
$this->form_validation->set_rules('mahnspanne', 'Mahnspanne', 'integer');
$this->form_validation->set_rules('buchungstyp_kurzbz', 'Buchungstyp', 'required|max_length[32]');
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required|max_length[16]');
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'required|has_permissions_for_stg[admin:rw,assistenz:rw]');
$this->form_validation->set_rules('credit_points', 'Credit Points', 'numeric');
Events::trigger('konto_insert_validation', $this->form_validation);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$allowed = [
'betrag',
'buchungsdatum',
'buchungstext',
'mahnspanne',
'buchungstyp_kurzbz',
'studiensemester_kurzbz',
'studiengang_kz',
'credit_points',
'anmerkung'
];
$data = [
'insertamum' => date('c'),
'insertvon' => getAuthUID()
];
foreach ($allowed as $field)
if ($this->input->post($field) !== null)
$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']];
}
$result = [];
foreach ($person_ids as $person_id) {
$id = $this->KontoModel->insert(array_merge($data, ['person_id' => $person_id]));
if (isError($id)) {
$this->addError(getError($id), self::ERROR_TYPE_DB);
} else {
$kontodata = $this->KontoModel->withAdditionalInfo()->load(getData($id));
if (isError($kontodata))
$this->addError(getError($kontodata), self::ERROR_TYPE_DB);
else
$result[] = current(getData($kontodata));
}
}
if ($result)
$this->terminateWithSuccess($result);
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
/**
* Save Counter Buchung
*
* @return void
*/
public function counter()
{
$this->load->library('form_validation');
$buchungsnrs = $this->input->post('buchungsnr');
if (!$buchungsnrs || !is_array($buchungsnrs)) {
$buchungsnrs = $buchungsnrs ? [$buchungsnrs] : [];
$this->form_validation->set_rules('buchungsnr', 'Buchungsnr', 'required');
}
$this->form_validation->set_rules('buchungsdatum', 'Buchungsdatum', 'is_valid_date');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$data = [];
$rules = [];
foreach ($buchungsnrs as $k => $buchungsnr) {
$result = $this->KontoModel->load($buchungsnr);
if (isError($result)) {
$rules[] = [
'field' => 'buchung[' . $k . ']',
'label' => 'Buchung #' . $buchungsnr,
'rules' => 'required',
'errors' => [
'required' => getError($result)
]
];
} elseif (!hasData($result)) {
$rules[] = [
'field' => 'buchung[' . $k . ']',
'label' => 'Buchung #' . $buchungsnr,
'rules' => 'required'
];
} else {
$data[$k] = get_object_vars(current(getData($result)));
$rules[] = [
'field' => 'buchung[' . $k . '][buchungsnr]',
'label' => 'Buchung # ' . $buchungsnr,
'rules' => 'required|numeric'
];
$rules[] = [
'field' => 'buchung[' . $k . '][studiengang_kz]',
'label' => 'Buchung # ' . $buchungsnr,
'rules' => 'required|has_permissions_for_stg[admin:rw,assistenz:rw]'
];
$rules[] = [
'field' => 'buchung[' . $k . '][buchungsnr_verweis]',
'label' => 'Buchung # ' . $buchungsnr,
'rules' => 'regex_match[/^$/]',
'errors' => [
'regex_match' => $this->p->t('konto', 'error_counter_level')
]
];
}
}
$this->form_validation->reset_validation();
$this->form_validation->set_data(['buchung' => $data]);
$this->form_validation->set_rules($rules);
Events::trigger('konto_counter_validation', $this->form_validation);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$buchungsdatum = $this->input->post('buchungsdatum');
$newItems = [];
foreach ($data as $buchung) {
$result = $this->KontoModel->getDifferenz($buchung['buchungsnr']);
if (isError($result)) {
$this->addError(getError($result), self::ERROR_TYPE_GENERAL);
continue;
}
$betrag = $result->retval;
if ($betrag === null) {
$this->addError($this->p->t(
'konto',
'error_missing',
$buchung
), self::ERROR_TYPE_GENERAL);
continue;
}
$result = $this->KontoModel->insert([
'person_id' => $buchung['person_id'],
'studiengang_kz' => $buchung['studiengang_kz'],
'studiensemester_kurzbz' => $buchung['studiensemester_kurzbz'],
'buchungstext' => $buchung['buchungstext'],
'buchungstyp_kurzbz' => $buchung['buchungstyp_kurzbz'],
'credit_points' => $buchung['credit_points'],
'zahlungsreferenz' => $buchung['zahlungsreferenz'],
'betrag' => $betrag,
'buchungsdatum' => $buchungsdatum,
'mahnspanne' => '0',
'buchungsnr_verweis' => $buchung['buchungsnr'],
'insertamum' => date('c'),
'insertvon' => getAuthUID(),
'anmerkung' => ''
]);
if (isError($result)) {
$this->addError(getError($result), self::ERROR_TYPE_GENERAL);
continue;
}
$newItems = null;
// TODO(chris): get as tree?
/*$result = $this->KontoModel->withAdditionalInfo()->load($result->retval);
if (!hasData($result))
$newItems = null;
elseif ($newItems !== null)
$newItems[] = current(getData($result));*/
}
$this->terminateWithSuccess($newItems);
}
/**
* Save Buchung
*
* @return void
*/
public function update()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('buchungsnr', 'Buchungsnr', 'required');
$this->form_validation->set_rules('betrag', 'Betrag', 'numeric');
$this->form_validation->set_rules('buchungsdatum', 'Buchungsdatum', 'is_valid_date');
$this->form_validation->set_rules('buchungstext', 'Buchungstext', 'max_length[256]');
$this->form_validation->set_rules('mahnspanne', 'Mahnspanne', 'integer');
$this->form_validation->set_rules('buchungstyp_kurzbz', 'Buchungstyp', 'required|max_length[32]');
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester', 'required|max_length[16]');
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'required|has_permissions_for_stg[admin:rw,assistenz:rw]');
$this->form_validation->set_rules('credit_points', 'Credit Points', 'numeric');
Events::trigger('konto_update_validation', $this->form_validation);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$id = $this->input->post('buchungsnr');
$allowed = [
'betrag',
'buchungsdatum',
'buchungstext',
'mahnspanne',
'buchungstyp_kurzbz',
'studiensemester_kurzbz',
'studiengang_kz',
'credit_points',
'anmerkung'
];
$data = [
'updateamum' => date('c'),
'updatevon' => getAuthUID()
];
foreach ($allowed as $field)
if ($this->input->post($field) !== null)
$data[$field] = $this->input->post($field);
$result = $this->KontoModel->update($id, $data);
$this->getDataOrTerminateWithError($result);
$result = null;
// TODO(chris): get as tree?
/*$result = $this->KontoModel->withAdditionalInfo()->load($id);
#$result = $this->getDataOrTerminateWithError($result);
if (isError($result))
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
$result = $result->retval;*/
$this->terminateWithSuccess($result);
}
/**
* Delete Buchung
*
* @return void
*/
public function delete()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('buchungsnr', 'Buchungsnr', 'required');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$buchungsnr = $this->input->post('buchungsnr');
$result = $this->KontoModel->load($buchungsnr);
$result = $this->getDataOrTerminateWithError($result);
if (!$result)
$this->terminateWithError($this->p->t('konto', 'error_missing', [
'buchungsnr' => $buchungsnr
]));
$_POST['studiengang_kz'] = current($result)->studiengang_kz;
$this->form_validation->set_rules('studiengang_kz', 'Studiengang', 'has_permissions_for_stg[admin:rw,assistenz:rw]');
Events::trigger('konto_delete_validation', $this->form_validation);
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
Events::trigger('konto_delete', $buchungsnr);
$result = $this->KontoModel->delete($buchungsnr);
if (isError($result)) {
if (getCode($result) != 42)
$this->terminateWithError(getError($result));
$this->terminateWithError($this->p->t('konto', 'error_delete_level'));
}
$this->terminateWithSuccess();
}
}
@@ -0,0 +1,147 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about generally used lists
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Lists extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'getStudiensemester' => self::PERM_LOGGED,
'getStgs' => self::PERM_LOGGED,
'getSprachen' => self::PERM_LOGGED,
'getGeschlechter' => self::PERM_LOGGED,
'getAusbildungen' => self::PERM_LOGGED,
'getOrgforms' => self::PERM_LOGGED,
'getStati' => self::PERM_LOGGED
]);
}
public function getStudiensemester()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addOrder('ende');
$result = $this->StudiensemesterModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStgs()
{
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->StudiengangModel->addSelect('*');
$this->StudiengangModel->addSelect('UPPER(typ || kurzbz) AS kuerzel');
$this->StudiengangModel->addOrder('typ');
$this->StudiengangModel->addOrder('kurzbz');
$result = $this->StudiengangModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getSprachen()
{
$this->load->model('system/Sprache_model', 'SpracheModel');
$this->SpracheModel->addOrder('sprache');
$result = $this->SpracheModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getGeschlechter()
{
$this->load->model('person/Geschlecht_model', 'GeschlechtModel');
$this->GeschlechtModel->addOrder('sort');
$this->GeschlechtModel->addOrder('geschlecht');
$this->GeschlechtModel->addSelect('*');
#$this->GeschlechtModel->addTranslatedSelect("bezeichnung_mehrsprachig", "bezeichnung");
$this->GeschlechtModel->addSelect("bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $this->GeschlechtModel->escape(DEFAULT_LANGUAGE) . " LIMIT 1)] AS bezeichnung");
$result = $this->GeschlechtModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getAusbildungen()
{
$this->load->model('codex/Ausbildung_model', 'AusbildungModel');
$this->AusbildungModel->addOrder('ausbildungcode');
$result = $this->AusbildungModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getOrgforms()
{
$this->load->model('codex/Orgform_model', 'OrgformModel');
$this->OrgformModel->addOrder('bezeichnung');
$result = $this->OrgformModel->loadWhere(['rolle' => true]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function getStati()
{
$lang = getUserLanguage();
$this->load->model('crm/Status_model', 'StatusModel');
$this->StatusModel->addSelect('*');
#$this->StatusModel->addTranslatedSelect('bezeichnung_mehrsprachig', 'bezeichnung');
$this->StatusModel->addSelect(
'bezeichnung_mehrsprachig[(
SELECT index
FROM public.tbl_sprache
WHERE sprache=' . $this->StatusModel->escape($lang) . '
LIMIT 1
)] AS bezeichnung',
false
);
#$this->StatusModel->addOrder('ext_id');
$result = $this->StatusModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
}
@@ -0,0 +1,384 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Notiz extends Notiz_Controller
{
public function __construct()
{
parent::__construct([
'getUid' => ['admin:r', 'assistenz:r'],
'getNotizen' => ['admin:r', 'assistenz:r'],
'loadNotiz' => ['admin:r', 'assistenz:r'], // TODO(manu): self::PERM_LOGGED
'addNewNotiz' => ['admin:rw', 'assistenz:rw'], // TODO(manu): self::PERM_LOGGED
'updateNotiz' => ['admin:rw', 'assistenz:rw'], // TODO(manu): self::PERM_LOGGED
'deleteNotiz' => ['admin:r', 'assistenz:r'],
'loadDokumente' => ['admin:r', 'assistenz:r'],
'getMitarbeiter' => ['admin:r', 'assistenz:r']
]);
//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 getUid()
{
$this->terminateWithSuccess(getAuthUID());
}*/
public function getNotizen($id, $type)
{
//check if valid type
$result = $this->NotizzuordnungModel->isValidType($type);
if(isError($result))
$this->terminateWithError($result->retval, self::ERROR_TYPE_GENERAL);
//$this->terminateWithError(" after check type not valid", self::ERROR_TYPE_GENERAL);
$result = $this->NotizModel->getNotizWithDocEntries($id, $type);
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
// return $this->terminateWithError("type not valid", self::ERROR_TYPE_GENERAL);
}
/* public function loadNotiz()
{
$_POST = json_decode(utf8_encode($this->input->raw_input_stream), true);
$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
THEN public.tbl_notiz.updateamum ELSE public.tbl_notiz.insertamum END::timestamp, 'DD.MM.YYYY HH24:MI:SS') AS lastUpdate");
$this->NotizModel->addLimit(1);
$result = $this->NotizModel->loadWhere(
array('notiz_id' => $notiz_id)
);
if (isError($result))
{
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
elseif (!hasData($result))
{
$this->terminateWithError($this->p->t('ui', 'error_missingId', ['id'=>'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
else
{
$this->terminateWithSuccess(current(getData($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;
}
}
$notiz_id = $this->input->post('notiz_id');
if(!$notiz_id)
{
$this->terminateWithError($this->p->t('ui','error_missingId',['id'=>'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
//Form Validation
$this->form_validation->set_rules('titel', 'Titel', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Titel'])
]);
$this->form_validation->set_rules('text', 'Text', 'required', [
'required' => $this->p->t('ui', 'error_fieldRequired', ['field' => 'Text'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
//update Notiz
$uid = getAuthUID();
$titel = $this->input->post('titel');
$text = $this->input->post('text');
$verfasser_uid = $this->input->post('verfasser');
$bearbeiter_uid = isset($_POST['bearbeiter']) ? $_POST['bearbeiter'] : $uid;
$erledigt = $this->input->post('erledigt');
$start = $this->input->post('start');
$ende = $this->input->post('ende');
$result = $this->NotizModel->update(
[
'notiz_id' => $notiz_id
],
[
'titel' => $titel,
'updatevon' => $uid,
'updateamum' => date('c'),
'text' => $text,
'verfasser_uid' => $verfasser_uid,
'bearbeiter_uid' => $bearbeiter_uid,
'start' => $start,
'ende' => $ende,
'erledigt' => $erledigt
]
);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
//update(1) laden aller bereits mit dieser notiz_id verknüpften DMS-Einträge
$this->load->model('person/Notizdokument_model', 'NotizdokumentModel');
$this->NotizdokumentModel->addJoin('campus.tbl_dms_version', 'dms_id');
$dms_uploaded = null;
$result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $notiz_id));
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
elseif (!hasData($result))
{
$dms_id_arr = null;
}
else
{
$result = getData($result);
foreach($result as $doc) {
$dms_id_arr[] = array(
'name' => $doc->name,
'dms_id' => $doc->dms_id
);
}
}
foreach ($_FILES as $k => $file)
{
//update(2) alle neuen files (alle außer type application/x.fhc-dms+json) anhängen
if($file["type"] == 'application/x.fhc-dms+json')
{
$dms_uploaded[] = array(
'name' => $file["name"]
);
}
else
{
$dms = array(
'kategorie_kurzbz' => 'notiz',
'version' => 0,
'name' => $file["name"],
'mimetype' => $file["type"],
'insertamum' => date('c'),
'insertvon' => $uid
);
//Todo(manu) check if filetypes weiter eingeschränkt werden sollen
//Todo(manu)check name files: nicht gleiches file 2mal hochladen
$result = $this->dmslib->upload($dms, $k, array('*'));
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$dms_id = $result->retval['dms_id'];
$result = $this->NotizdokumentModel->insert(array('notiz_id' => $notiz_id, 'dms_id' => $dms_id));
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
}
}
//update(3) check if Dateien gelöscht wurden
if(count($dms_uploaded) != count($dms_id_arr))
{
if (count($dms_uploaded) == 0)
{
$filesDeleted = $dms_id_arr;
}
else
{
$upload_new_names = array_column($dms_uploaded, "name");
$filesDeleted = array_filter($dms_id_arr, function ($file) use ($upload_new_names) {
return !in_array($file["name"], $upload_new_names);
});
}
foreach ($filesDeleted as $file)
{
$result = $this->dmslib->removeAll($file['dms_id']);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
else
$this->outputJson($result);
}
}
return $this->terminateWithSuccess($result);
}*/
/* public function deleteNotiz()
{
$_POST = json_decode(utf8_encode($this->input->raw_input_stream), true);
$notiz_id = $this->input->post('notiz_id');
$type = $this->input->post('type_id');
$id = $this->input->post('id');
//dms_id auslesen aus notizdokument wenn vorhanden
$dms_id_arr = [];
$this->load->model('person/Notizdokument_model', 'NotizdokumentModel');
$result = $this->NotizdokumentModel->loadWhere(array('notiz_id' => $notiz_id));
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
if(hasData($result))
{
$result = getData($result);
foreach ($result as $doc) {
$dms_id_arr[] = $doc->dms_id;
}
}
if($dms_id_arr)
{
$this->load->library('DmsLib');
foreach($dms_id_arr as $dms_id)
{
$result = $this->dmslib->removeAll($dms_id);
if (isError($result))
{
return $this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->outputJson($result);
}
}
//delete Notizzuordnung
if($type == "software_id")
{
// Loads extension Model
$this->load->model('extensions/FHC-Core-Softwarebereitstellung/Softwarenotizzuordnung_model', 'ExtensionnotizzuordnungModel');
$result = $this->ExtensionnotizzuordnungModel->delete([
'notiz_id' => $notiz_id,
'id' => strval($id)
],
[
'type_id' => $type
]);
}
else
{
//notizzuordnungsid!
$result = $this->NotizzuordnungModel->delete(['notiz_id' => $notiz_id, $type => $id]);
}
$this->load->model('person/Notiz_model', 'NotizModel');
//$this->NotizModel->addJoin('public.tbl_notizzuordnung', 'notiz_id');
//TODO (erweitern um Type_id) für Extensions, damit auch Notizzuordnung gelöscht werden kann
//Löschen von Notiz
$result = $this->NotizModel->delete(
array('notiz_id' => $notiz_id)
);
if (isError($result))
{
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if(!hasData($result))
{
return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(current(getData($result)));
}*/
/* public function loadDokumente()
{
$_POST = json_decode(utf8_encode($this->input->raw_input_stream), true);
$notiz_id = $this->input->post('notiz_id');
$this->NotizModel->addSelect('campus.tbl_dms_version.*');
$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)');
$result = $this->NotizModel->loadWhere(
array('public.tbl_notiz.notiz_id' => $notiz_id)
);
if (isError($result)) {
return $this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
if(!hasData($result))
{
return $this->terminateWithError($this->p->t('ui','error_missingId', ['id'=> 'Notiz_id']), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result));
}*/
/* public function getMitarbeiter($searchString)
{
$this->load->model('ressource/Mitarbeiter_model', 'MitarbeiterModel');
$result = $this->MitarbeiterModel->searchMitarbeiter($searchString);
if (isError($result)) {
$this->terminateWithError($result, self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess($result);
}*/
public function isBerechtigt($id, $typeId)
{
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);
}
return success("berechtigt in überschreibender Funktion");
/* return $this->terminateWithError('keine Berechtigung bro', self::ERROR_TYPE_GENERAL);*/
}
}
@@ -0,0 +1,299 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \DateTime as DateTime;
class Prestudent extends FHCAPI_Controller
{
public function __construct()
{
parent::__construct([
'get' => ['admin:r', 'assistenz:r'],
'updatePrestudent' => ['admin:rw', 'assistenz:rw'],
'getHistoryPrestudents' => ['admin:r', 'assistenz:r'],
'getBezeichnungZGV' => ['admin:r', 'assistenz:r'],
'getBezeichnungDZgv' => ['admin:r', 'assistenz:r'],
'getBezeichnungMZgv' => ['admin:r', 'assistenz:r'],
'getAusbildung' => ['admin:r', 'assistenz:r'],
'getAufmerksamdurch' => ['admin:r', 'assistenz:r'],
'getBerufstaetigkeit' => ['admin:r', 'assistenz:r'],
'getTypenStg' => ['admin:r', 'assistenz:r'],
'getStudienplaene' => ['admin:r', 'assistenz:r'],
'getStudiengang' => ['admin:r', 'assistenz:r']
]);
if ($this->router->method == 'updatePrestudent') {
$prestudent_id = current(array_slice($this->uri->rsegments, 2));
$this->checkPermissionsForPrestudent($prestudent_id, ['admin:rw', 'assistenz:rw']);
} elseif ($this->router->method == 'get'
|| $this->router->method == 'getStudienplaene'
|| $this->router->method == 'getStudiengang'
) {
$prestudent_id = current(array_slice($this->uri->rsegments, 2));
$this->checkPermissionsForPrestudent($prestudent_id, ['admin:r', 'assistenz:r']);
} elseif ($this->router->method == 'getHistoryPrestudents') {
$person_id = current(array_slice($this->uri->rsegments, 2));
$this->checkPermissionsForPerson($person_id, ['admin:r', 'assistenz:r'], ['admin:r', 'assistenz:r']);
}
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
// Load language phrases
$this->loadPhrases([
'ui', 'studierendenantrag', 'lehre'
]);
}
public function get($prestudent_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addSelect('*');
$result = $this->PrestudentModel->loadWhere(['prestudent_id' => $prestudent_id]);
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
if(!hasData($result))
{
return show_404();
}
$this->terminateWithSuccess(current(getData($result)));
}
public function updatePrestudent($prestudent_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
// UDF
$this->load->library('UDFLib');
$result = $this->udflib->getCiValidations($this->PrestudentModel, $this->input->post());
$udf_field_validations = $this->getDataOrTerminateWithError($result);
//Form validation
$this->load->library('form_validation');
$this->form_validation->set_rules($udf_field_validations);
$this->form_validation->set_rules('priorisierung', 'Priorisierung', 'numeric', [
'numeric' => $this->p->t('ui', 'error_fieldNotNumeric', ['field' => 'Priorisierung'])
]);
if ($this->form_validation->run() == false)
{
$this->terminateWithValidationErrors($this->form_validation->error_array());
}
$uid = getAuthUID();
$array_allowed_props_prestudent = [
'aufmerksamdurch_kurzbz',
'studiengang_kz',
'gsstudientyp_kurzbz',
'person_id',
'berufstaetigkeit_code',
'ausbildungcode',
'zgv_code',
'zgvort',
'zgvdatum',
'zgvnation',
'zgvmas_code',
'zgvmaort',
'zgvmadatum',
'zgvmanation',
'facheinschlberuf',
'bismelden',
'anmerkung',
'dual',
'zgvdoktor_code',
'zgvdoktorort',
'zgvdoktordatum',
'zgvdoktornation',
'aufnahmegruppe_kurzbz',
'priorisierung',
'foerderrelevant',
'zgv_erfuellt',
'zgvmas_erfuellt',
'zgvdoktor_erfuellt',
'mentor',
'aufnahmeschluessel',
'standort_code'
];
// add UDFs
$result = $this->udflib->getDefinitionForModel($this->PrestudentModel);
$definitions = $this->getDataOrTerminateWithError($result);
foreach ($definitions as $def)
$array_allowed_props_prestudent[] = $def['name'];
$update_prestudent = array();
foreach ($array_allowed_props_prestudent as $prop)
{
$val = $this->input->post($prop);
if ($val !== null || $prop == 'foerderrelevant') {
$update_prestudent[$prop] = $val;
}
}
$update_prestudent['updateamum'] = date('c');
$update_prestudent['updatevon'] = $uid;
if (count($update_prestudent))
{
$result = $this->PrestudentModel->update(
$prestudent_id,
$update_prestudent
);
$this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess(true);
}
return $this->terminateWithSuccess(false);
}
public function getHistoryPrestudents($person_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->getHistoryPrestudents($person_id);
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
$this->terminateWithSuccess(getData($result) ?: []);
}
public function getBezeichnungZGV()
{
$this->load->model('codex/Zgv_model', 'ZgvModel');
$this->ZgvModel->addOrder('zgv_code');
$result = $this->ZgvModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getBezeichnungDZgv()
{
$this->load->model('codex/Zgvdoktor_model', 'ZgvdoktorModel');
$this->ZgvdoktorModel->addOrder('zgvdoktor_code');
$result = $this->ZgvdoktorModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getBezeichnungMZgv()
{
$this->load->model('codex/Zgvmaster_model', 'ZgvmasterModel');
$this->ZgvmasterModel->addOrder('zgvmas_code');
$result = $this->ZgvmasterModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getAusbildung()
{
$this->load->model('codex/Ausbildung_model', 'AusbildungModel');
$this->AusbildungModel->addOrder('ausbildungcode');
$result = $this->AusbildungModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getAufmerksamdurch()
{
$this->load->model('codex/Aufmerksamdurch_model', 'AufmerksamdurchModel');
$this->AufmerksamdurchModel->addOrder('aufmerksamdurch_kurzbz');
$result = $this->AufmerksamdurchModel->load();
if (isError($result))
{
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getBerufstaetigkeit()
{
$this->load->model('codex/Berufstaetigkeit_model', 'BerufstaetigkeitModel');
$this->BerufstaetigkeitModel->addOrder('berufstaetigkeit_code');
$result = $this->BerufstaetigkeitModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getTypenStg()
{
$this->load->model('education/Gsstudientyp_model', 'GsstudientypModel');
$this->GsstudientypModel->addOrder('gsstudientyp_kurzbz');
$result = $this->GsstudientypModel->load();
if (isError($result)) {
$this->terminateWithError(getError($result), self::ERROR_TYPE_GENERAL);
}
return $this->terminateWithSuccess(getData($result) ?: []);
}
public function getStudienplaene($prestudent_id)
{
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$result = $this->StudienplanModel->getStudienplaeneByPrestudents($prestudent_id);
$data = $this->getDataOrTerminateWithError($result);
return $this->terminateWithSuccess($data);
}
/**
* Gets details for the Studiengang of the Prestudent
*
* @param integer $prestudent_id
*
* @return stdClass
*/
public function getStudiengang($prestudent_id)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addSelect('stg.*');
$this->PrestudentModel->addJoin('public.tbl_studiengang stg', 'studiengang_kz');
$result = $this->PrestudentModel->load($prestudent_id);
$stg = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess(current($stg));
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,562 @@
<?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 \DateTime as DateTime;
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about a Student
* Listens to ajax post calls to change the Student data
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Student extends FHCAPI_Controller
{
/**
* Calls the parent's constructor and prepares libraries and phrases
*/
public function __construct()
{
parent::__construct([
'get' => ['admin:r', 'assistenz:r'],
'save' => ['admin:rw', 'assistenz:rw'],
'check' => ['admin:rw', 'assistenz:rw'],
'add' => ['admin:rw', 'assistenz:rw'] // TODO(chris): extra permissions
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
if ($this->router->method == 'get'
|| $this->router->method == 'save'
) {
$prestudent_id = current(array_slice($this->uri->rsegments, 2));
if ($this->router->method == 'get')
$this->checkPermissionsForPrestudent($prestudent_id, ['admin:r', 'assistenz:r']);
else
$this->checkPermissionsForPrestudent($prestudent_id, ['admin:rw', 'assistenz:rw']);
}
// Load language phrases
$this->loadPhrases([
'ui'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Get details for a prestudent
*
* @param string $prestudent_id
* @return void
*/
public function get($prestudent_id)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->PrestudentModel->addSelect('p.*');
$this->PrestudentModel->addSelect('s.student_uid');
$this->PrestudentModel->addSelect('matrikelnr');
$this->PrestudentModel->addSelect('b.aktiv');
$this->PrestudentModel->addSelect('v.semester');
$this->PrestudentModel->addSelect('v.verband');
$this->PrestudentModel->addSelect('v.gruppe');
$this->PrestudentModel->addSelect('b.alias');
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
LIMIT 1
) AS email_privat",
false
);
}
$this->PrestudentModel->addJoin('public.tbl_student s', 'prestudent_id', 'LEFT');
$this->PrestudentModel->addJoin('public.tbl_benutzer b', 'student_uid = uid', 'LEFT');
$this->PrestudentModel->addJoin(
'public.tbl_studentlehrverband v',
'b.uid = v.student_uid AND v.studiensemester_kurzbz = ' . $this->PrestudentModel->escape($studiensemester_kurzbz),
'LEFT'
);
$this->PrestudentModel->addJoin('public.tbl_person p', 'p.person_id = tbl_prestudent.person_id');
$result = $this->PrestudentModel->loadWhere(['prestudent_id' => $prestudent_id]);
$student = $this->getDataOrTerminateWithError($result);
if (!$student)
return show_404();
$this->terminateWithSuccess(current($student));
}
/**
* Saves data to a prestudent
*
* @param string $prestudent_id
* @return void
*/
public function save($prestudent_id)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->load->model('person/Person_model', 'PersonModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('education/Studentlehrverband_model', 'StudentlehrverbandModel');
$this->load->library('form_validation');
$this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'is_valid_date');
$this->form_validation->set_rules('semester', 'Semester', 'integer');
$this->load->library('UDFLib');
$result = $this->udflib->getCiValidations($this->PersonModel, $this->input->post());
//TODO(Manu) check with Chris: input number not allowed
$udf_field_validations = $this->getDataOrTerminateWithError($result);
$this->form_validation->set_rules($udf_field_validations);
if (!$this->form_validation->run())
$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;
$result = $this->PrestudentModel->loadWhere(['prestudent_id' => $prestudent_id]);
$person = $this->getDataOrTerminateWithError($result);
$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) {
$val = $this->input->post($prop);
if ($val !== null) {
$update_lehrverband[$prop] = $val;
}
}
$array_allowed_props_person = [
'anrede',
'bpk',
'titelpre',
'titelpost',
'nachname',
'vorname',
'vornamen',
'wahlname',
'gebdatum',
'gebort',
'geburtsnation',
'svnr',
'ersatzkennzeichen',
'staatsbuergerschaft',
'matr_nr',
'sprache',
'geschlecht',
'familienstand',
'foto',
'anmerkung',
'homepage'
];
// add UDFs
$result = $this->udflib->getDefinitionForModel($this->PersonModel);
$definitions = $this->getDataOrTerminateWithError($result);
foreach ($definitions as $def)
$array_allowed_props_person[] = $def['name'];
$update_person = array();
foreach ($array_allowed_props_person as $prop) {
$val = $this->input->post($prop);
if ($val !== null) {
$update_person[$prop] = $val;
}
}
$array_allowed_props_student = ['matrikelnr'];
$update_student = array();
foreach ($array_allowed_props_student as $prop) {
$val = $this->input->post($prop);
if ($val !== null) {
$update_student[$prop] = $val;
}
}
// Check PKs
if (count($update_lehrverband) + count($update_student) && $uid === null) {
// TODO(chris): phrase
$this->terminateWithValidationErrors(['' => "Kein/e StudentIn vorhanden!"]);
}
if (count($update_person) && $person_id === null) {
// TODO(chris): phrase
$this->terminateWithValidationErrors(['' => "Keine Person vorhanden!"]);
}
// Do Updates
if (count($update_lehrverband)) {
$result = $this->StudentlehrverbandModel->update([
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'student_uid' => $uid
], $update_lehrverband);
$this->getDataOrTerminateWithError($result);
}
if (count($update_person)) {
$result = $this->PersonModel->update(
$person_id,
$update_person
);
$this->getDataOrTerminateWithError($result);
}
if (count($update_student)) {
$result = $this->StudentModel->update(
[$uid],
$update_student
);
$this->getDataOrTerminateWithError($result);
}
$this->terminateWithSuccess(array_fill_keys(array_merge(
array_keys($update_lehrverband),
array_keys($update_person),
array_keys($update_student)
), ''));
}
public function check()
{
$this->load->library('form_validation');
$this->form_validation->set_rules('gebdatum', 'Geburtsdatum', 'is_valid_date');
if (!$this->form_validation->run())
$this->terminateWithValidationErrors($this->form_validation->error_array());
$vorname = $this->input->post('vorname');
$nachname = $this->input->post('nachname');
$gebdatum = $this->input->post('gebdatum');
if (!$vorname && !$nachname && !$gebdatum)
$this->terminateWithValidationErrors(['At least one of vorname, nachname or gebdatum must be set']);
$this->load->model('person/Person_model', 'PersonModel');
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->group_end();
} elseif ($nachname) {
$this->PersonModel->db->or_where('LOWER(nachname)', 'LOWER(' . $this->PersonModel->escape($nachname) . ')', false);
}
$result = $this->PersonModel->load();
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
public function add()
{
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());
// TODO(chris): This should be in a library
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$this->db->trans_start();
$result = $this->addInteressent();
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
$this->terminateWithError('TODO(chris): TEXT', self::ERROR_TYPE_GENERAL);
$this->terminateWithSuccess($result);
}
protected function addInteressent()
{
// 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'),
'insertvon' => getAuthUID(),
'zugangscode' => uniqid(),
'aktiv' => true
];
if ($this->input->post('anrede'))
$data['anrede'] = $this->input->post('anrede');
if ($this->input->post('titelpre'))
$data['titelpre'] = $this->input->post('titelpre');
if ($this->input->post('titelpost'))
$data['titelpost'] = $this->input->post('titelpost');
if ($this->input->post('vorname'))
$data['vorname'] = $this->input->post('vorname');
if ($this->input->post('vornamen'))
$data['vornamen'] = $this->input->post('vornamen');
if ($this->input->post('wahlname'))
$data['wahlname'] = $this->input->post('wahlname');
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');
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);
}
// Addresse anlegen
$anlegen = $this->input->post('address[func]');
if ($anlegen) {
$this->load->model('person/Adresse_model', 'AdresseModel');
$data = [
'nation' => $this->input->post('address[nation]'),
'strasse' => $this->input->post('address[address]'),
'plz' => $this->input->post('address[plz]'),
'ort' => $this->input->post('address[ort]'),
'gemeinde' => $this->input->post('address[gemeinde]'),
'typ' => 'h',
'zustelladresse' => true,
];
if ($anlegen < 0) { // Überschreiben
$this->AdresseModel->addOrder('zustelladresse', 'DESC');
$this->AdresseModel->addOrder('sort');
$result = $this->AdresseModel->loadWhere([
'person_id' => $person_id
]);
$address = $this->getDataOrTerminateWithError($result);
if ($address) {
$address = current($address);
$data['updateamum'] = date('c');
$data['updatevon'] = getAuthUID();
$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);
}
}
// Kontaktdaten
$kontaktdaten = [];
foreach (['email', 'telefon', 'mobil'] as $k) {
$v = $this->input->post($k);
if ($v)
$kontaktdaten[$k] = $v;
}
if (count($kontaktdaten)) {
$this->load->model('person/Kontakt_model', 'KontaktModel');
foreach ($kontaktdaten as $typ => $kontakt) {
$data = [
'person_id' => $person_id,
'kontakttyp' => $typ,
'kontakt' => $kontakt,
'zustellung' => true,
'insertamum' => date('c'),
'insertvon' => getAuthUID()
];
$result = $this->KontaktModel->insert($data);
$this->getDataOrTerminateWithError($result);
}
}
// 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
];
$ausbildungsart = $this->input->post('ausbildungsart');
if ($ausbildungsart)
$data['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;
$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);
// 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);
if ($incoming) {
// TODO(chris): IMPLEMENT!
//Matrikelnummer und UID generieren
//Benutzerdatensatz anlegen
//Studentendatensatz anlegen
//StudentLehrverband anlegen
}
// TODO(chris): DEBUG
/*$result = $this->PrestudentModel->loadWhere([
'pestudent_id' => 1
]);
if (isError($result)) {
return $result;
}*/
$this->terminateWithSuccess(true);
}
public function requiredIfNotPersonId($value)
{
if (isset($_POST['person_id']))
return true;
return !!$value;
}
public function requiredIfAddressFunc($value)
{
if (!$_POST['address']['func'])
return true;
return !!$value;
}
}
@@ -0,0 +1,743 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about listing students
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Students extends FHCAPI_Controller
{
private $allowedStgs = [];
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['admin:r', 'assistenz:r'];
parent::__construct($permissions);
$this->allowedStgs = $this->permissionlib->getSTG_isEntitledFor('admin') ?: [];
$this->allowedStgs = array_merge($this->allowedStgs, $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []);
if (!$this->allowedStgs) {
$this->_outputAuthError([$router->method => ['admin:r', 'assistenz:r']]);
exit;
}
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
/**
* Remap calls:
* / => return []
* /inout => return []
* /inout/incoming => getIncoming
* /inout/outgoing => getOutgoing
* /inout/gemeinsamestudien => getGemeinsamestudien
* /(studiengang_kz) => getStudents
* /(studiengang_kz)/prestudent => getPrestudents
* /(studiengang_kz)/prestudent/* => getPrestudents
* /(studiengang_kz)/(semester) => getStudents
* /(studiengang_kz)/(semester)/grp/(gruppe_kurzbz) => getStudents
* /(studiengang_kz)/(semester)/(verband) => getStudents
* /(studiengang_kz)/(semester)/(verband)/(gruppe) => getStudents
* /(studiengang_kz)/(org_form) => getStudents
* /(studiengang_kz)/(org_form)/prestudent => getPrestudents
* /(studiengang_kz)/(org_form)/prestudent/* => getPrestudents
* /(studiengang_kz)/(org_form)/(semester) => getStudents
* /(studiengang_kz)/(org_form)/(semester)/grp/(gruppe_kurzbz)
* => getStudents
* /(studiengang_kz)/(org_form)/(semester)/(verband) => getStudents
* /(studiengang_kz)/(org_form)/(semester)/(verband)/(gruppe)
* => getStudents
* /uid/(student_uid) => getStudent
* /prestudent/(prestudent_id) => getPrestudent
* /person/(person_id) => getPerson
*
* @param string $method
* @param array $params (optional)
*
* @return void
*/
public function _remap($method, $params = [])
{
if ($method == '' || $method == 'index')
return $this->terminateWithSuccess([]);
if ($method == 'inout') {
if (!count($params))
return $this->terminateWithSuccess([]);
switch ($params[0]) {
case 'incoming':
return $this->getIncoming();
case 'outgoing':
return $this->getOutgoing();
case 'gemeinsamestudien':
return $this->getGemeinsamestudien();
default:
return show_404();
}
}
$count = count($params);
if (!$count)
return $this->getStudents($method);
if ($method == 'uid' && $count == 1)
return $this->getStudent($params[0]);
if ($method == 'prestudent' && $count == 1)
return $this->getPrestudent($params[0]);
if ($method == 'person' && $count == 1)
return $this->getPerson($params[0]);
if (is_numeric($params[0])) {
$sem = $params[0];
if ($count == 3 && $params[1] == 'grp') {
$g = $params[2];
$ver = null;
$grp = null;
} else {
$g = null;
$ver = $count > 1 ? $params[1] : null;
$grp = $count > 2 ? $params[2] : null;
}
return $this->getStudents($method, $sem, $ver, $grp, $g);
} elseif ($params[0] == 'prestudent') {
if ($count == 1)
return $this->getPrestudents($method);
if ($count == 2)
return $this->getPrestudents($method, $params[1]);
return $this->getPrestudents($method, $params[1], $params[$count-1]);
} else {
$org = $params[0];
if ($count > 1 && $params[1] == 'prestudent') {
if ($count == 2)
return $this->getPrestudents($method, null, null, $org);
if ($count == 3)
return $this->getPrestudents($method, $params[2], null, $org);
return $this->getPrestudents($method, $params[2], $params[$count-1], $org);
}
$sem = $count > 1 ? $params[1] : null;
if ($count == 4 && $params[2] == 'grp') {
$g = $params[3];
$ver = null;
$grp = null;
} else {
$g = null;
$ver = $count > 2 ? $params[2] : null;
$grp = $count > 3 ? $params[3] : null;
}
return $this->getStudents($method, $sem, $ver, $grp, $g, $org);
}
show_404();
}
/**
* @return void
*/
protected function getIncoming()
{
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
}
/**
* @return void
*/
protected function getOutgoing()
{
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
}
/**
* @return void
*/
protected function getGemeinsamestudien()
{
// TODO(chris): IMPLEMENT!
$this->terminateWithSuccess([]);
}
/**
* @param integer $studiengang_kz
* @param string $studiensemester_kurzbz (optional)
* @param string $filter (optional)
* @param string $orgform_kurzbz (optional)
*
* @return void
*/
protected function getPrestudents($studiengang_kz, $studiensemester_kurzbz = null, $filter = null, $orgform_kurzbz = null)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
$selectRT = "
SELECT 1
FROM public.tbl_rt_person
JOIN public.tbl_reihungstest r ON (rt_id = reihungstest_id)
WHERE person_id=p.person_id
AND studienplan_id IN (
SELECT studienplan_id
FROM lehre.tbl_studienplan
JOIN lehre.tbl_studienordnung o USING(studienordnung_id)
WHERE o.studiengang_kz=tbl_prestudent.studiengang_kz
)
AND r.studiensemester_kurzbz=" . $stdsemEsc;
$where = ['tbl_prestudent.studiengang_kz' => $studiengang_kz];
if ($orgform_kurzbz) {
$where['ps.orgform_kurzbz'] = $orgform_kurzbz;
}
switch ($filter) {
case "interessenten":
$where['ps.status_kurzbz'] = 'Interessent';
break;
case "bewerbungnichtabgeschickt":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bewerbung_abgeschicktamum'] = null;
break;
case "bewerbungabgeschickt":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bewerbung_abgeschicktamum IS NOT NULL'] = null;
$where['bestaetigtam'] = null;
break;
case "statusbestaetigt":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bestaetigtam IS NOT NULL'] = null;
break;
case "statusbestaetigtrtnichtangemeldet":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bestaetigtam IS NOT NULL'] = null;
$this->PrestudentModel->db->where('NOT EXISTS(' . $selectRT . ')', null, false);
break;
case "statusbestaetigtrtangemeldet":
$where['ps.status_kurzbz'] = 'Interessent';
$where['bestaetigtam IS NOT NULL'] = null;
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
break;
case "zgv":
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$result = $this->StudiengangModel->load($studiengang_kz);
$stg = $this->getDataOrTerminateWithError($result);
if (!$stg)
$this->terminateWithValidationErrors(['' => 'Studiengang does not exist']); // TODO(chris): phrase
$stg = current($stg);
$where['ps.status_kurzbz'] = 'Interessent';
if ($stg->typ == 'm') {
$where['zgvmas_code IS NOT NULL'] = null;
if (defined('ZGV_ERFUELLT_ANZEIGEN') && ZGV_ERFUELLT_ANZEIGEN)
$where['zgvmas_erfuellt'] = true;
} elseif ($stg->typ == 'p') {
$where['zgvdoktor_code IS NOT NULL'] = null;
if (defined('ZGV_DOKTOR_ANZEIGEN') && ZGV_DOKTOR_ANZEIGEN)
$where['zgvdoktor_erfuellt'] = true;
} else {
$where['zgv_code IS NOT NULL'] = null;
if (defined('ZGV_ERFUELLT_ANZEIGEN') && ZGV_ERFUELLT_ANZEIGEN)
$where['zgv_erfuellt'] = true;
}
break;
case "reihungstestangemeldet":
$where['ps.status_kurzbz'] = 'Interessent';
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
break;
case "reihungstestnichtangemeldet":
$where['ps.status_kurzbz'] = 'Interessent';
$this->PrestudentModel->db->where('NOT EXISTS(' . $selectRT . ')', null, false);
break;
case "bewerber":
$where['ps.status_kurzbz'] = 'Bewerber';
break;
case "bewerberrtnichtangemeldet":
$where['ps.status_kurzbz'] = 'Bewerber';
$this->PrestudentModel->db->where('NOT EXISTS(' . $selectRT . ')', null, false);
break;
case "bewerberrtangemeldet":
$where['ps.status_kurzbz'] = 'Bewerber';
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
break;
case "bewerberrtangemeldetteilgenommen":
$where['ps.status_kurzbz'] = 'Bewerber';
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
$where['reihungstestangetreten'] = true;
break;
case "bewerberrtangemeldetnichtteilgenommen":
$where['ps.status_kurzbz'] = 'Bewerber';
$this->PrestudentModel->db->where('EXISTS(' . $selectRT . ')', null, false);
$where['reihungstestangetreten'] = false;
break;
case "aufgenommen":
$where['ps.status_kurzbz'] = 'Aufgenommener';
break;
case "warteliste":
$where['ps.status_kurzbz'] = 'Wartender';
break;
case "absage":
$where['ps.status_kurzbz'] = 'Abgewiesener';
break;
case "incoming":
// NOTE(chris): in FAS it was not filtered for studiengang_kz
$where['ps.status_kurzbz'] = 'Incoming';
break;
case "absolvent":
$where['ps.status_kurzbz'] = 'Absolvent';
break;
case "diplomand":
$where['ps.status_kurzbz'] = 'Diplomand';
break;
default:
if (!$studiensemester_kurzbz) {
// TODO(chris): this does not work with $orgform_kurzbz != null
$where['ps.status_kurzbz'] = null;
} else {
$this->PrestudentModel->db->where_in('ps.status_kurzbz', [
'Interessent',
'Bewerber',
'Aufgenommener',
'Wartender',
'Abgewiesener'
]);
}
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);
$this->PrestudentModel->addSelect("'' AS verband");
$this->PrestudentModel->addSelect("'' AS gruppe");
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->loadWhere($where);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* @param integer $studiengang_kz
* @param integer $semester (optional)
* @param string $verband (optional)
* @param integer $gruppe (optional)
* @param string $gruppe_kurzbz (optional)
* @param string $orgform_kurzbz (optional)
*
* @return void
*/
protected function getStudents($studiengang_kz, $semester = null, $verband = null, $gruppe = null, $gruppe_kurzbz = null, $orgform_kurzbz = null)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
/*
$this->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');
$this->PrestudentModel->addSelect('v.verband');
$this->PrestudentModel->addSelect('v.gruppe');
$this->PrestudentModel->addSelect("'' AS priorisierung_relativ");
$where = [];
if ($gruppe_kurzbz !== null) {
$this->PrestudentModel->addJoin('public.tbl_benutzergruppe g', 'uid');
$where['g.gruppe_kurzbz'] = $gruppe_kurzbz;
$where['g.studiensemester_kurzbz'] = $studiensemester_kurzbz;
} else {
$where['v.studiengang_kz'] = $studiengang_kz;
if ($semester !== null)
$where['v.semester'] = $semester;
if ($verband !== null)
$where['v.verband'] = $verband;
if ($gruppe !== null)
$where['v.gruppe'] = $gruppe;
if (!$verband && !$gruppe && $orgform_kurzbz !== null) {
$this->PrestudentModel->db->where(
"(
SELECT orgform_kurzbz
FROM public.tbl_prestudentstatus
WHERE prestudent_id=tbl_prestudent.prestudent_id
AND studiensemester_kurzbz=" . $this->PrestudentModel->escape($studiensemester_kurzbz) . "
ORDER BY datum DESC, insertamum DESC, ext_id DESC LIMIT 1
) =",
$this->PrestudentModel->escape($orgform_kurzbz),
false
);
}
}
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->loadWhere($where);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* @param string $prestudent_id
*
* @return void
*/
protected function getPrestudent($prestudent_id)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$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');
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->loadWhere([
'tbl_prestudent.prestudent_id' => $prestudent_id
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* @param string $student_uid
*
* @return void
*/
protected function getStudent($student_uid)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$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');
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->loadWhere([
's.student_uid' => $student_uid
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* @param integer $person_id
*
* @return void
*/
protected function getPerson($person_id)
{
$studiensemester_kurzbz = $this->variablelib->getVar('semester_aktuell');
$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');
$this->addSelectPrioRel();
$this->addFilter($studiensemester_kurzbz);
$result = $this->PrestudentModel->loadWhere([
'p.person_id' => $person_id
]);
$data = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($data);
}
/**
* @param string|null $studiensemester_kurzbz
* @param string $type
*
* @return void
*/
protected function prepareQuery($studiensemester_kurzbz, $type = 'LEFT')
{
$stdsemEsc = $studiensemester_kurzbz ? $this->PrestudentModel->escape($studiensemester_kurzbz) : 'NULL';
$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', $type);
$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' . ($studiensemester_kurzbz ? '=' . $stdsemEsc : ' IS NULL'),
$type
);
$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->PrestudentModel->addSelect("b.uid");
$this->PrestudentModel->addSelect('titelpre');
$this->PrestudentModel->addSelect('nachname');
$this->PrestudentModel->addSelect('vorname');
$this->PrestudentModel->addSelect('wahlname');
$this->PrestudentModel->addSelect('vornamen');
$this->PrestudentModel->addSelect('titelpost');
$this->PrestudentModel->addSelect('svnr');
$this->PrestudentModel->addSelect('ersatzkennzeichen');
$this->PrestudentModel->addSelect('gebdatum');
$this->PrestudentModel->addSelect('geschlecht');
// semester
// verband
// gruppe
$this->PrestudentModel->addSelect('UPPER(stg.typ || stg.kurzbz) AS studiengang');
$this->PrestudentModel->addSelect('tbl_prestudent.studiengang_kz');
$this->PrestudentModel->addSelect("s.matrikelnr");
$this->PrestudentModel->addSelect('p.person_id');
$this->PrestudentModel->addSelect('pls.status_kurzbz AS status');
$this->PrestudentModel->addSelect('pls.datum AS status_datum');
$this->PrestudentModel->addSelect('pls.bestaetigtam AS status_bestaetigung');
$this->PrestudentModel->addSelect(
"(SELECT kontakt FROM public.tbl_kontakt WHERE kontakttyp='email' AND person_id=p.person_id AND zustellung LIMIT 1) AS mail_privat",
false
);
$this->PrestudentModel->addSelect("
CASE WHEN b.uid IS NOT NULL AND b.uid<>''
THEN b.uid || " . $this->PrestudentModel->escape(DOMAIN) . "
ELSE '' END AS mail_intern", false);
$this->PrestudentModel->addSelect('p.anmerkung AS anmerkungen');
$this->PrestudentModel->addSelect('tbl_prestudent.anmerkung');
$this->PrestudentModel->addSelect('pls.orgform_kurzbz');
$this->PrestudentModel->addSelect('aufmerksamdurch_kurzbz');
$this->PrestudentModel->addSelect(
"(SELECT rt_gesamtpunkte AS punkte FROM public.tbl_prestudent WHERE prestudent_id=ps.prestudent_id) AS punkte",
false
);
$this->PrestudentModel->addSelect('tbl_prestudent.aufnahmegruppe_kurzbz');
$this->PrestudentModel->addSelect('tbl_prestudent.dual');
$this->PrestudentModel->addSelect('p.matr_nr');
$this->PrestudentModel->addSelect('sp.bezeichnung AS studienplan_bezeichnung');
$this->PrestudentModel->addSelect('tbl_prestudent.prestudent_id');
// priorisierung_relativ
$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->db->where_in('tbl_prestudent.studiengang_kz', $this->allowedStgs);
$this->PrestudentModel->addOrder('nachname');
$this->PrestudentModel->addOrder('vorname');
}
/**
* @return void
*/
protected function addSelectPrioRel()
{
$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)
WHERE person_id = p.person_id
AND studiensemester_kurzbz = (
SELECT studiensemester_kurzbz
FROM PUBLIC.tbl_prestudentstatus
WHERE prestudent_id = tbl_prestudent.prestudent_id
AND status_kurzbz = 'Interessent'
LIMIT 1
)
AND status_kurzbz = 'Interessent'
) prest
WHERE laststatus NOT IN ('Abbrecher', 'Abgewiesener', 'Absolvent')
AND priorisierung <= tbl_prestudent.priorisierung
) || ' (' || tbl_prestudent.priorisierung || ')' AS priorisierung_relativ", false);
}
/**
* Adds additional filters to the query
*
* @param string $studiensemester_kurzbz
*
* @return void
*/
protected function addFilter($studiensemester_kurzbz)
{
$filter = $this->input->get('filter');
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);
}
}
}
@@ -0,0 +1,493 @@
<?php
/**
* Copyright (C) 2024 fhcomplete.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* This controller operates between (interface) the JS (GUI) and the back-end
* Provides data to the ajax get calls about verbände
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
*/
class Verband extends FHCAPI_Controller
{
public function __construct()
{
$permissions = [];
$router = load_class('Router');
$permissions[$router->method] = ['admin:r', 'assistenz:r'];
parent::__construct($permissions);
// Load Models
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
}
/**
* Remap calls:
* /
* /(studiengang_kz) => getStudiengang
* /(studiengang_kz)/(semester) => getSemester
* /(studiengang_kz)/(semester)/(verband) => getVerband
* /(studiengang_kz)/(org_form) => getStudiengang
* /(studiengang_kz)/(org_form)/(semester) => getSemester
* /(studiengang_kz)/(org_form)/(semester)/(verband) => getVerband
*
* @param string $method
* @param array $params (optional)
*
* @return void
*/
public function _remap($method, $params = [])
{
if ($method == '' || $method == 'index')
return $this->getBase();
// NOTE(chris): Test if access is allowed ($method is the Studiengang)
if (!$this->permissionlib->isBerechtigt('assistenz', 's', $method)
&& !$this->permissionlib->isBerechtigt('admin', 's', $method)
) {
return $this->_outputAuthError([$method => ['admin:r', 'assistenz:r']]);
}
$count = count($params);
if (!$count)
return $this->getStudiengang($method);
if ($count == 1) {
if (is_numeric($params[0]))
return $this->getSemester($method, $params[0]);
elseif ($params[0] == 'prestudent')
return $this->terminateWithSuccess($this->getStdSem($method . '/prestudent/', $method));
else
return $this->getStudiengang($method, $params[0]);
}
if ($count == 2) {
if (is_numeric($params[0]))
return $this->getVerband($method, $params[0], $params[1]);
elseif ($params[1] == 'prestudent')
return $this->terminateWithSuccess($this->getStdSem($method . '/' . $params[0] . '/prestudent/', $method));
else
return $this->getSemester($method, $params[1], $params[0]);
}
if ($count == 3 && !is_numeric($params[0]) && is_numeric($params[1]) && !is_numeric($params[2]))
return $this->getVerband($method, $params[1], $params[2], $params[0]);
show_404();
}
/**
* @return void
*/
protected function getBase()
{
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("v.studiengang_kz AS link");
$this->StudiengangModel->addSelect(
"CONCAT(kurzbzlang, ' (', UPPER(CONCAT(typ, kurzbz)), ') - ', tbl_studiengang.bezeichnung) AS name",
false
);
$this->StudiengangModel->addSelect('erhalter_kz');
$this->StudiengangModel->addSelect('typ');
$this->StudiengangModel->addSelect('kurzbz');
$this->StudiengangModel->addSelect('studiengang_kz');
$this->StudiengangModel->addSelect('studiengang_kz AS stg_kz');
$this->StudiengangModel->addOrder('erhalter_kz');
$this->StudiengangModel->addOrder('typ');
$this->StudiengangModel->addOrder('kurzbz');
$stgs = $this->permissionlib->getSTG_isEntitledFor('admin') ?: [];
$stgs = array_merge($stgs, $this->permissionlib->getSTG_isEntitledFor('assistenz') ?: []);
if (!$stgs)
$this->terminateWithSuccess([]);
$this->StudiengangModel->db->where_in('studiengang_kz', $stgs);
$result = $this->StudiengangModel->loadWhere(['v.aktiv' => true]);
$list = $this->getDataOrTerminateWithError($result);
if ($this->permissionlib->isBerechtigt('inout/uebersicht'))
$list[] = [
'name' => 'International',
'link' => 'inout',
'children' => [
[
'name' => 'Incoming',
'link' => 'inout/incoming',
'leaf' => true
],
[
'name' => 'Outgoing',
'link' => 'inout/outgoing',
'leaf' => true
],
[
'name' => 'Gemeinsame Studien',
'link' => 'inout/gemeinsamestudien',
'leaf' => true
]
]
];
$this->terminateWithSuccess($list);
}
/**
* @param integer $studiengang_kz
* @param string $orgform (optional)
*
* @return void
*/
protected function getStudiengang($studiengang_kz, $org_form = null)
{
$link = $studiengang_kz . '/';
if ($org_form !== null)
$link .= $org_form . '/';
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", semester) AS link", false);
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester ORDER BY verband, gruppe LIMIT 1)) AS name", false);
$this->StudiengangModel->addSelect('semester');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->StudiengangModel->addOrder('semester');
if ($org_form !== null) {
$this->StudiengangModel->db->group_start();
$this->StudiengangModel->db->where('v.semester', 0);
$this->StudiengangModel->db->or_where('v.orgform_kurzbz', $org_form);
$this->StudiengangModel->db->group_end();
}
$result = $this->StudiengangModel->loadWhere([
'v.studiengang_kz' => $studiengang_kz,
'v.aktiv' => true
]);
$list = $this->getDataOrTerminateWithError($result);
array_unshift($list, [
'name' => 'PreStudent',
'link' => $link . 'prestudent',
'children' => $this->getStdSem($link . 'prestudent/', $studiengang_kz)
]);
if ($org_form === null) {
// NOTE(chris): if mischform show orgforms
$result = $this->StudiengangModel->load($studiengang_kz);
$result = $this->getDataOrTerminateWithError($result);
if ($result) {
if (current($result)->mischform) {
$this->load->model('organisation/Studienordnung_model', 'StudienordnungModel');
$this->StudienordnungModel->addDistinct();
$this->StudienordnungModel->addSelect("CONCAT(studiengang_kz, '/', p.orgform_kurzbz) AS link");
$this->StudienordnungModel->addSelect("p.orgform_kurzbz AS name");
$this->StudienordnungModel->addJoin('lehre.tbl_studienplan p', 'studienordnung_id');
$result = $this->StudienordnungModel->loadWhere([
'aktiv' => true,
'studiengang_kz' => $studiengang_kz,
'p.orgform_kurzbz !=' => 'DDP'
]);
$result = $this->getDataOrTerminateWithError($result);
$list = array_merge($list, $result);
}
}
}
$this->terminateWithSuccess($list);
}
/**
* @param integer $studiengang_kz
* @param integer $semester
* @param string $orgform
*
* @return void
*/
protected function getSemester($studiengang_kz, $semester, $org_form = null)
{
$link = $studiengang_kz . '/';
if ($org_form !== null)
$link .= $org_form . '/';
$link .= $semester . '/';
$this->load->model('organisation/Gruppe_model', 'GruppeModel');
$this->GruppeModel->addDistinct();
$this->GruppeModel->addSelect("CONCAT(" . $this->GruppeModel->escape($link . 'grp/') . ", gruppe_kurzbz) AS link", false);
$this->GruppeModel->addSelect("CONCAT(gruppe_kurzbz, ' (', bezeichnung, ')') AS name", false);
$this->GruppeModel->addSelect("TRUE AS leaf", false);
$this->GruppeModel->addSelect('sort');
$this->GruppeModel->addSelect('gruppe_kurzbz');
$this->GruppeModel->addSelect($this->GruppeModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->GruppeModel->addOrder('sort');
$this->GruppeModel->addOrder('gruppe_kurzbz');
$where = [
'studiengang_kz' => $studiengang_kz,
'semester' => $semester,
'lehre' => true,
'sichtbar' => true,
'aktiv' => true,
'direktinskription' => false
];
if ($org_form !== null)
$where['orgform_kurzbz'] = $org_form;
$result = $this->GruppeModel->loadWhere($where);
$list = $this->getDataOrTerminateWithError($result);
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", verband) AS link", false);
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband ORDER BY gruppe LIMIT 1)) AS name", false);
$this->StudiengangModel->addSelect("CASE WHEN MAX(gruppe)='' OR MAX(gruppe)=' ' THEN TRUE ELSE FALSE END AS leaf");
$this->StudiengangModel->addSelect('verband');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->StudiengangModel->addOrder('verband');
$this->StudiengangModel->addGroupBy('link, name, verband');
$where = [
'v.studiengang_kz' => $studiengang_kz,
'v.semester' => $semester,
'v.verband !=' => '',
'v.aktiv' => true
];
if ($org_form !== null && $semester) // NOTE(chris): on semester 0 show all?
$where['v.orgform_kurzbz'] = $org_form;
$result = $this->StudiengangModel->loadWhere($where);
$result = $this->getDataOrTerminateWithError($result);
$list = array_merge($list, $result);
$this->terminateWithSuccess($list);
}
/**
* @param integer $studiengang_kz
* @param integer $semester
* @param integer $verband
* @param string $orgform
*
* @return void
*/
protected function getVerband($studiengang_kz, $semester, $verband, $org_form = null)
{
$link = $studiengang_kz . '/';
if ($org_form !== null)
$link .= $org_form . '/';
$link .= $semester . '/'. $verband . '/';
$this->StudiengangModel->addJoin('public.tbl_lehrverband v', 'studiengang_kz');
$this->StudiengangModel->addDistinct();
$this->StudiengangModel->addSelect("CONCAT(" . $this->StudiengangModel->escape($link) . ", gruppe) AS link", false);
$this->StudiengangModel->addSelect("CONCAT(UPPER(CONCAT(typ, kurzbz)), '-', semester, verband, gruppe, (SELECT CASE WHEN bezeichnung IS NULL OR bezeichnung='' THEN ''::TEXT ELSE CONCAT(' (', bezeichnung, ')') END FROM public.tbl_lehrverband WHERE studiengang_kz=v.studiengang_kz AND semester=v.semester AND verband=v.verband AND gruppe=v.gruppe ORDER BY gruppe LIMIT 1)) AS name", false);
$this->StudiengangModel->addSelect("TRUE AS leaf", false);
$this->StudiengangModel->addSelect('gruppe');
$this->StudiengangModel->addSelect($this->StudiengangModel->escape($studiengang_kz) . '::integer AS stg_kz', false);
$this->StudiengangModel->addOrder('gruppe');
$where = [
'v.studiengang_kz' => $studiengang_kz,
'v.semester' => $semester,
'v.verband' => $verband,
'v.gruppe !=' => '',
'v.aktiv' => true
];
if ($org_form !== null && $semester) // NOTE(chris): on semester 0 show all?
$where['v.orgform_kurzbz'] = $org_form;
$result = $this->StudiengangModel->loadWhere($where);
$list = $this->getDataOrTerminateWithError($result);
$this->terminateWithSuccess($list);
}
/**
* @param string $link
* @param integer $studiengang_kz
*
* @return array
*/
protected function getStdSem($link, $studiengang_kz)
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->load->model('system/Variable_model', 'VariableModel');
$result = $this->VariableModel->getVariables(getAuthUID(), ['number_displayed_past_studiensemester']);
$data = $this->getDataOrTerminateWithError($result);
$number_displayed_past_studiensemester = $data['number_displayed_past_studiensemester'] ?? null;
$this->StudiensemesterModel->addPlusMinus(null, $number_displayed_past_studiensemester);
$this->StudiensemesterModel->addOrder('ende');
$result = $this->StudiensemesterModel->load();
$studiensemester = $this->getDataOrTerminateWithError($result);
$result = [];
$studiengang_kz = (int)$studiengang_kz;
foreach ($studiensemester as $sem) {
$semlink = $link . $sem->studiensemester_kurzbz;
$intlink = $semlink . '/interessenten';
$result[] = [
'name' => $sem->studiensemester_kurzbz,
'link' => $semlink,
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Interessenten',
'link' => $intlink,
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Bewerbung nicht abgeschickt',
'link' => $intlink . '/bewerbungnichtabgeschickt',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Bewerbung abgeschickt, Status unbestätigt',
'link' => $intlink . '/bewerbungabgeschickt',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'ZGV erfüllt',
'link' => $intlink . '/zgv',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Status bestätigt',
'link' => $intlink . '/statusbestaetigt',
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Nicht zum Reihungstest angemeldet',
'link' => $intlink . '/statusbestaetigtrtnichtangemeldet',
'leaf' => true
],
[
'name' => 'Reihungstest angemeldet',
'link' => $intlink . '/statusbestaetigtrtangemeldet',
'leaf' => true
]
]
],
[
'name' => 'Nicht zum Reihungstest angemeldet',
'link' => $intlink . '/reihungstestnichtangemeldet',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Reihungstest angemeldet',
'link' => $intlink . '/reihungstestangemeldet',
'stg_kz' => $studiengang_kz,
'leaf' => true
]
]
],
[
'name' => 'Bewerber',
'link' => $semlink . '/bewerber',
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Nicht zum Reihungstest angemeldet',
'link' => $intlink . '/bewerberrtnichtangemeldet',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Reihungstest angemeldet',
'link' => $intlink . '/bewerberrtangemeldet',
'stg_kz' => $studiengang_kz,
'children' => [
[
'name' => 'Teilgenommen',
'link' => $intlink . '/bewerberrtangemeldetteilgenommen',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Nicht teilgenommen',
'link' => $intlink . '/bewerberrtangemeldetnichtteilgenommen',
'stg_kz' => $studiengang_kz,
'leaf' => true
]
]
]
]
],
[
'name' => 'Aufgenommen',
'link' => $semlink . '/aufgenommen',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Warteliste',
'link' => $semlink . '/warteliste',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Absage',
'link' => $semlink . '/absage',
'stg_kz' => $studiengang_kz,
'leaf' => true
],
[
'name' => 'Incoming',
'link' => $semlink . '/incoming',
'stg_kz' => $studiengang_kz,
'leaf' => true
]
]
];
}
return $result;
}
}
@@ -264,4 +264,4 @@ class Person extends API_Controller
return success('Input data are valid');
}
}
}
+21 -5
View File
@@ -5,8 +5,12 @@ if (! defined("BASEPATH")) exit("No direct script access allowed");
class UHSTAT1 extends FHC_Controller
{
const BERECHTIGUNG_UHSTAT_VERWALTEN = 'student/uhstat1daten_verwalten';
const LOGIN_SESSION_INDEX = 'bewerbung/user';
const PERSON_ID_SESSION_INDEX = 'bewerbung/personId';
const CODEX_OESTERREICH = 'A';
const CODEX_UNKNOWN_YEAR = 9999;
const CODEX_UNKNOWN_NATION = 'XXX';
const CODEX_UNKNOWN_BILDUNGMAX = 999;
const LOWER_BOUNDARY_YEARS = 160;
const UPPER_BOUNDARY_YEARS = 20;
@@ -210,7 +214,9 @@ class UHSTAT1 extends FHC_Controller
else
return true;
if (!isset($bildungsstaat)) return true;
// if no Bildungsstaat or Bildungmax unknown - valid
if (!isset($bildungsstaat) || $bildungmax == self::CODEX_UNKNOWN_BILDUNGMAX) return true;
// find out if abschluss is in Austria
$this->AbschlussModel->addSelect("in_oesterreich");
@@ -219,8 +225,11 @@ class UHSTAT1 extends FHC_Controller
if (hasData($abschlussRes))
{
$in_oesterreich = getData($abschlussRes)[0]->in_oesterreich;
// invalid if abschluss in Austria, but not Bildungsstaat, or abschluss not in Austria, but Bildungsstaat in Austria
return ($in_oesterreich && $bildungsstaat == self::CODEX_OESTERREICH) || (!$in_oesterreich && $bildungsstaat != self::CODEX_OESTERREICH);
// valid if Bildungsstaat and Abschluss in Austria, or Bildungsstaat and Abschluss not in Austria
// (or Abschluss not in Austria and Bildungsstaat unknown)
return ($in_oesterreich && $bildungsstaat == self::CODEX_OESTERREICH)
|| (!$in_oesterreich && ($bildungsstaat != self::CODEX_OESTERREICH || $bildungsstaat == self::CODEX_UNKNOWN_NATION));
}
return false;
@@ -363,7 +372,11 @@ class UHSTAT1 extends FHC_Controller
// get realistic birth years, dated back from current year
$currYear = date("Y");
$formMetaData['jahre'] = range($currYear - self::UPPER_BOUNDARY_YEARS, $currYear - self::LOWER_BOUNDARY_YEARS);
$yearRange = range($currYear - self::UPPER_BOUNDARY_YEARS, $currYear - self::LOWER_BOUNDARY_YEARS);
$formMetaData['jahre'] = array_combine($yearRange, $yearRange);
// add "unknown" option
$formMetaData['jahre'][self::CODEX_UNKNOWN_YEAR] = 'unbekannt';
return success($formMetaData);
}
@@ -411,7 +424,10 @@ class UHSTAT1 extends FHC_Controller
private function _getValidPersonId($berechtigungsArt)
{
// if coming from bewerbungstool - person id is in session (person must be logged in bewerbungstool)
if (isset($_SESSION[self::PERSON_ID_SESSION_INDEX]) && is_numeric($_SESSION[self::PERSON_ID_SESSION_INDEX]))
if (isset($_SESSION[self::PERSON_ID_SESSION_INDEX])
&& is_numeric($_SESSION[self::PERSON_ID_SESSION_INDEX])
&& isset($_SESSION[self::LOGIN_SESSION_INDEX])
)
return $_SESSION[self::PERSON_ID_SESSION_INDEX];
// if person id passed directly...
@@ -1,218 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \Studierendenantrag_model as Studierendenantrag_model;
/**
*
*/
class Abmeldung extends FHC_Controller
{
/**
* Calls the parent's constructor and loads the FilterCmptLib
*/
public function __construct()
{
parent::__construct();
// Libraries
$this->load->library('AuthLib');
$this->load->library('AntragLib');
// Load language phrases
$this->loadPhrases([
'studierendenantrag'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Retrieves data of the current studiengang for the current user
*/
public function getDetailsForNewAntrag($prestudent_id)
{
if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, true)) {
$this->output->set_status_header(403);
return $this->outputJsonError('Forbidden');
}
$result = $this->antraglib->getPrestudentAbmeldeBerechtigt($prestudent_id);
if (isError($result)) {
$this->output->set_status_header(500);
return $this->outputJsonError(getError($result));
}
$result = $result->retval;
if (!$result) {
$this->output->set_status_header(403);
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_student'));
}
elseif ($result == -3)
{
$this->output->set_status_header(403);
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_stg_blacklist'));
}
elseif ($result == -1)
{
$result = $this->antraglib->getDetailsForLastAntrag(
$prestudent_id,
[
Studierendenantrag_model::TYP_ABMELDUNG,
Studierendenantrag_model::TYP_ABMELDUNG_STGL
]
);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$data = getData($result);
$data->canCancel = (
$data->status == Studierendenantragstatus_model::STATUS_CREATED &&
$this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id)
);
return $this->outputJsonSuccess($data);
}
$result = $this->antraglib->getDetailsForNewAntrag($prestudent_id);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$this->outputJsonSuccess(getData($result));
}
public function getDetailsForAntrag($studierendenantrag_id)
{
if (!$this->antraglib->isEntitledToShowAntrag($studierendenantrag_id)) return show_404();
$result = $this->antraglib->getDetailsForAntrag($studierendenantrag_id);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$data = getData($result);
if ($data->typ !== Studierendenantrag_model::TYP_ABMELDUNG_STGL && $data->typ !== Studierendenantrag_model::TYP_ABMELDUNG)
return show_404();
$data->canCancel = (
$data->status == Studierendenantragstatus_model::STATUS_CREATED &&
$this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id)
);
$this->outputJsonSuccess($data);
}
public function createAntrag()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required');
$this->form_validation->set_rules('prestudent_id', 'Prestudent ID', 'required');
$this->form_validation->set_rules('grund', 'Grund', 'required');
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$grund = $this->input->post('grund');
$studiensemester = $this->input->post('studiensemester');
$prestudent_id = $this->input->post('prestudent_id');
$result = $this->antraglib->getPrestudentAbmeldeBerechtigt($prestudent_id);
if (isError($result)) {
return $this->outputJsonError(['db' => getError($result)]);
}
$result = $result->retval;
if (!$result)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]);
}
elseif ($result == -3)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_stg_blacklist')]);
}
elseif ($result < 0)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_antrag_exists')]);
}
$result = $this->antraglib->createAbmeldung($prestudent_id, $studiensemester, getAuthUID(), $grund);
if (isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
$result = $this->antraglib->getDetailsForAntrag(getData($result));
if (!hasData($result))
return $this->outputJsonSuccess(true);
$data = getData($result);
$data->canCancel = (boolean)$this->antraglib->isEntitledToCancelAntrag($data->studierendenantrag_id);
$this->outputJsonSuccess($data);
}
public function cancelAntrag()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules('antrag_id', 'Antrag ID', 'required');
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$antrag_id = $this->input->post('antrag_id');
if(!$this->antraglib->isEntitledToCancelAntrag($antrag_id))
{
$this->output->set_status_header(403);
return $this->outputJsonError('Forbidden');
}
$result = $this->antraglib->cancelAntrag($antrag_id, getAuthUID());
if(isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
$result = $this->antraglib->getDetailsForAntrag($antrag_id);
if (!hasData($result))
return $this->outputJsonSuccess($antrag_id);
$this->outputJsonSuccess(getData($result));
}
public function getStudiengaengeAssistenz()
{
$this->load->library('PermissionLib');
$_POST = json_decode($this->input->raw_input_stream, true);
$query = $this->input->post('query');
$studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag');
$result = $this->antraglib->getAktivePrestudentenInStgs($studiengaenge, $query);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$result = getData($result);
if (!$result) {
return $this->outputJsonSuccess([]);
}
return $this->outputJsonSuccess($result);
}
}
@@ -1,479 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \stdClass as stdClass;
/**
*
*/
class Leitung extends FHC_Controller
{
/**
* Calls the parent's constructor and loads the FilterCmptLib
*/
public function __construct()
{
parent::__construct();
// Libraries
$this->load->library('AuthLib');
$this->load->library('AntragLib');
// Load language phrases
$this->loadPhrases([
'studierendenantrag'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
public function getActiveStgs()
{
$studiengaenge = $this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe') ?: [];
$studiengaenge = array_merge($studiengaenge, $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag') ?: []);
$result = $this->StudierendenantragModel->loadStgsWithAntraege($studiengaenge);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
$this->outputJson($result);
}
public function getAntraege($studiengang = null, $extra = null)
{
if ($studiengang && $studiengang == 'todo') {
$studiengang = $extra;
$extra = true;
} else {
$extra = false;
}
if ($studiengang) {
$studiengaenge = [$studiengang];
} else {
$studiengaenge =$this->permissionlib->getSTG_isEntitledFor('student/antragfreigabe');
if(!is_array($studiengaenge))
$studiengaenge = [];
$stgsNeuanlage = $this->permissionlib->getSTG_isEntitledFor('student/studierendenantrag');
if(!is_array($stgsNeuanlage))
$stgsNeuanlage = [];
$studiengaenge = array_unique(array_merge($studiengaenge, $stgsNeuanlage));
}
$antraege = [];
if ($studiengaenge) {
$result = $extra
? $this->StudierendenantragModel->loadActiveForStudiengaenge($studiengaenge)
: $this->StudierendenantragModel->loadForStudiengaenge($studiengaenge);
if (isError($result)) {
$this->output->set_status_header(500);
return $this->outputJson('Internal Server Error');
}
if(hasData($result))
{
$antraege = getData($result);
}
}
$this->outputJson($antraege);
}
public function reopenAntrag()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
'required|callback_isEntitledToReopenAntrag',
[
'isEntitledToReopenAntrag' => $this->p->t('studierendenantrag', 'error_no_right')
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->reopenWiederholung($studierendenantrag_id, getAuthUID());
if (isError($result))
return $this->outputJsonError(['studierendenantrag_id' => getError($result)]);
$this->outputJsonSuccess($studierendenantrag_id);
}
public function pauseAntrag()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
[
'isEntitledToPauseAntrag',
[$this->antraglib, 'isEntitledToPauseAntrag']
],
[
'antragCanBeManualPaused',
[$this->antraglib, 'antragCanBeManualPaused']
]
],
[
'isEntitledToPauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'antragCanBeManualPaused' => $this->p->t(
'studierendenantrag',
'error_not_pauseable',
['id' => $this->input->post('studierendenantrag_id')]
)
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->pauseAntrag($studierendenantrag_id, getAuthUID());
if (isError($result))
return $this->outputJsonError(['studierendenantrag_id' => getError($result)]);
$this->outputJsonSuccess($studierendenantrag_id);
}
public function unpauseAntrag()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
[
'required',
[
'isEntitledToUnpauseAntrag',
[$this->antraglib, 'isEntitledToUnpauseAntrag']
],
[
'antragCanBeManualUnpaused',
[$this->antraglib, 'antragCanBeManualUnpaused']
]
],
[
'isEntitledToUnpauseAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'antragCanBeManualUnpaused' => $this->p->t(
'studierendenantrag',
'error_not_paused',
['id' => $this->input->post('studierendenantrag_id')]
)
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->unpauseAntrag($studierendenantrag_id, getAuthUID());
if (isError($result))
return $this->outputJsonError(['studierendenantrag_id' => getError($result)]);
$this->outputJsonSuccess($studierendenantrag_id);
}
public function objectAntrag()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
'required|callback_isEntitledToObjectAntrag|callback_canBeObjected',
[
'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'canBeObjected' => $this->p->t('studierendenantrag', 'error_no_objection')
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->objectAbmeldung($studierendenantrag_id, getAuthUID());
if (isError($result))
return $this->outputJsonError(['studierendenantrag_id' => getError($result)]);
$this->outputJsonSuccess($studierendenantrag_id);
}
public function objectionDeny()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
'required|callback_isEntitledToObjectAntrag|callback_isObjected',
[
'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'isObjected' => $this->p->t('studierendenantrag', 'error_not_objected')
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$grund = $this->input->post('grund');
$result = $this->antraglib->denyObjectionAbmeldung($studierendenantrag_id, getAuthUID(), $grund);
if (isError($result))
return $this->outputJsonError(['studierendenantrag_id' => getError($result)]);
$this->outputJsonSuccess($studierendenantrag_id);
}
public function objectionApprove()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
'required|callback_isEntitledToObjectAntrag|callback_isObjected',
[
'isEntitledToObjectAntrag' => $this->p->t('studierendenantrag', 'error_no_right'),
'isObjected' => $this->p->t('studierendenantrag', 'error_not_objected')
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->cancelAntrag($studierendenantrag_id, getAuthUID());
if (isError($result))
return $this->outputJsonError(['studierendenantrag_id' => getError($result)]);
$this->outputJsonSuccess($studierendenantrag_id);
}
public function isEntitledToReopenAntrag($studierendenantrag_id)
{
return $this->antraglib->isEntitledToReopenAntrag($studierendenantrag_id);
}
public function isEntitledToObjectAntrag($studierendenantrag_id)
{
return $this->antraglib->isEntitledToObjectAntrag($studierendenantrag_id);
}
public function isEntitledToRejectAntrag($studierendenantrag_id)
{
return $this->antraglib->isEntitledToRejectAntrag($studierendenantrag_id);
}
public function canBeObjected($studierendenantrag_id)
{
return $this->antraglib->hasType($studierendenantrag_id, Studierendenantrag_model::TYP_ABMELDUNG_STGL);
}
public function isObjected($studierendenantrag_id)
{
return $this->antraglib->hasStatus($studierendenantrag_id, Studierendenantragstatus_model::STATUS_OBJECTED);
}
public function approveAbmeldung()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
'required|callback_isEntitledToApproveAntrag',
[
'isEntitledToApproveAntrag' => $this->p->t('studierendenantrag', 'error_no_right')
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->approveAbmeldung([$studierendenantrag_id], getAuthUID());
if (isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
return $this->outputJsonSuccess($studierendenantrag_id);
}
public function approveAbmeldungStgl()
{
return $this->approveAbmeldung();
}
public function approveUnterbrechung()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
'required|callback_isEntitledToApproveAntrag',
[
'isEntitledToApproveAntrag' => $this->p->t('studierendenantrag', 'error_no_right')
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->approveUnterbrechung([$studierendenantrag_id], getAuthUID());
if (isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
return $this->outputJsonSuccess($studierendenantrag_id);
}
public function rejectUnterbrechung()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
'required|callback_isEntitledToRejectAntrag',
[
'isEntitledToRejectAntrag' => $this->p->t('studierendenantrag', 'error_no_right')
]
);
$this->form_validation->set_rules('grund', 'Grund', 'required');
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$grund = $this->input->post('grund');
$result = $this->antraglib->rejectUnterbrechung([$studierendenantrag_id], getAuthUID(), $grund);
if (isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
return $this->outputJsonSuccess($studierendenantrag_id);
}
public function approveWiederholung()
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules(
'studierendenantrag_id',
'Studierenden Antrag',
'required|callback_isEntitledToApproveAntrag',
[
'isEntitledToApproveAntrag' => $this->p->t('studierendenantrag', 'error_no_right')
]
);
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$studierendenantrag_id = $this->input->post('studierendenantrag_id');
$result = $this->antraglib->approveWiederholung($studierendenantrag_id, getAuthUID());
if (isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
return $this->outputJsonSuccess($studierendenantrag_id);
}
public function isEntitledToApproveAntrag($studierendenantrag_id)
{
return $this->antraglib->isEntitledToApproveAntrag($studierendenantrag_id);
}
public function getHistory($studierendenantrag_id)
{
if (!$this->antraglib->isEntitledToSeeHistoryForAntrag($studierendenantrag_id)) {
$this->output->set_status_header(403);
return $this->outputJson('Forbidden');
}
$result = $this->antraglib->getAntragHistory($studierendenantrag_id);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$this->outputJsonSuccess(getData($result) ?: []);
}
}
@@ -1,384 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
use \REST_Controller as REST_Controller;
/**
*
*/
class Wiederholung extends FHC_Controller
{
/**
* Calls the parent's constructor and loads the FilterCmptLib
*/
public function __construct()
{
parent::__construct();
// Configs
$this->load->config('studierendenantrag');
// Libraries
$this->load->library('AuthLib');
$this->load->library('PermissionLib');
$this->load->library('AntragLib');
$requiredPermissions = [
'saveLvs' => ['student/studierendenantrag:w'],
'getLvsAsRdf' => ['student/studierendenantrag:r', 'student/noten:r'],
'moveLvsToZeugnis' => ['student/studierendenantrag:w', 'student/noten:w']
];
if (isset($requiredPermissions[$this->router->method])) {
if (!$this->permissionlib->isEntitled($requiredPermissions, $this->router->method)) {
$this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
$this->outputJson('Forbidden');
exit;
}
}
// Load language phrases
$this->loadPhrases([
'global',
'studierendenantrag'
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Retrieves data of the current studiengang for the current user
*/
public function getDetailsForNewAntrag($prestudent_id)
{
if (!$this->antraglib->isEntitledToCreateAntragFor($prestudent_id, false)) {
$this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
return $this->outputJsonError('Forbidden');
}
$result = $this->antraglib->getPrestudentWiederholungsBerechtigt($prestudent_id);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
return $this->outputJsonError(getError($result));
}
$result = $result->retval;
if (!$result) {
$this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_student_no_failed_exam'));
}
elseif ($result == -1)
{
$result = $this->antraglib->getDetailsForLastAntrag($prestudent_id, Studierendenantrag_model::TYP_WIEDERHOLUNG);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$data = getData($result);
$result = $this->antraglib->getFailedExamForPrestudent($prestudent_id, $data->datum, $data->studiensemester_kurzbz);
// NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt()
$pruefungsdata = current(getData($result));
$data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz;
$data->lvbezeichnung = $pruefungsdata->lvbezeichnung;
$data->pruefungsdatum = $pruefungsdata->datum;
return $this->outputJsonSuccess($data);
}
elseif ($result == -2)
{
$result = $this->antraglib->getDetailsForLastAntrag($prestudent_id);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$result = getData($result);
$this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_pending', [
'typ' => $this->p->t('studierendenantrag', 'antrag_typ_' . $result->typ)
]));
}
elseif ($result == -3)
{
$this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_stg_blacklist'));
}
$result = $this->antraglib->getDetailsForNewAntrag($prestudent_id);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$data = getData($result);
$result = $this->antraglib->getFailedExamForPrestudent($prestudent_id);
// NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt()
$pruefungsdata = current(getData($result));
$data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz;
$data->lvbezeichnung = $pruefungsdata->lvbezeichnung;
$data->pruefungsdatum = $pruefungsdata->datum;
$this->outputJsonSuccess($data);
}
public function createAntrag()
{
$this->createAntragWithStatus(true);
}
public function cancelAntrag()
{
$this->createAntragWithStatus(false);
}
protected function createAntragWithStatus($repeat)
{
$this->load->library('form_validation');
$_POST = json_decode($this->input->raw_input_stream, true);
$this->form_validation->set_rules('prestudent_id', 'Prestudent ID', 'required');
$this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required');
if ($this->form_validation->run() == false)
{
return $this->outputJsonError($this->form_validation->error_array());
}
$prestudent_id = $this->input->post('prestudent_id');
$studiensemester = $this->input->post('studiensemester');
$result = $this->antraglib->getPrestudentWiederholungsBerechtigt($prestudent_id);
if (isError($result)) {
return $this->outputJsonError(['db' => getError($result)]);
}
$result = $result->retval;
if (!$result)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]);
}
elseif ($result == -1)
{
$result = $this->PrestudentstatusModel->getLastStatus($prestudent_id);
if (isError($result))
return $this->outputJsonError(['db' => getError($result)]);
if (!hasData($result))
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_prestudentstatus', [
'prestudent_id' => $prestudent_id
])]);
if (!in_array(current(getData($result))->status_kurzbz, $this->config->item('antrag_prestudentstatus_whitelist')))
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_no_student')]);
}
elseif ($result == -2)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_antrag_exists')]);
}
elseif ($result == -3)
{
return $this->outputJsonError(['db' => $this->p->t('studierendenantrag', 'error_stg_blacklist')]);
}
$result = $this->antraglib->createWiederholung($prestudent_id, $studiensemester, getAuthUID(), $repeat);
if(isError($result))
{
return $this->outputJsonError(['db' => getError($result)]);
}
$antragId = getData($result);
$result = $this->antraglib->getDetailsForAntrag($antragId);
if(!hasData($result))
return $this->outputJsonSuccess(true);
$data = getData($result);
$result = $this->antraglib->getFailedExamForPrestudent($prestudent_id);
// NOTE(chris): error handling for this function should already happenden in antraglib->getPrestudentWiederholungsBerechtigt()
$pruefungsdata = current(getData($result));
$data->studiensemester_kurzbz = $pruefungsdata->studiensemester_kurzbz;
$data->lvbezeichnung = $pruefungsdata->lvbezeichnung;
$data->pruefungsdatum = $pruefungsdata->datum;
$this->outputJsonSuccess($data);
}
public function getLvs($antrag_id)
{
$result = $this->antraglib->getLvsForAntrag($antrag_id);
if (isError($result)) {
$error = getError($result);
if ($error == 'Forbidden')
$this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
return $this->outputJsonError(getError($result));
}
$lvs = getData($result);
$this->outputJsonSuccess($lvs);
}
public function saveLvs()
{
$result = $this->getPostJSON();
$antragsLvs = array_merge($result->forbiddenLvs, $result->mandatoryLvs);
$insert = array_map(function ($lv) {
return [
'studierendenantrag_id' => $lv->studierendenantrag_id,
'lehrveranstaltung_id' => $lv->lehrveranstaltung_id,
'note' => $lv->zugelassen
? ($lv->zugelassen == 1 ? 0 : $this->config->item('wiederholung_note_angerechnet'))
: $this->config->item('wiederholung_note_nicht_zugelassen'),
'anmerkung' => $lv->anmerkung,
'insertvon' => getAuthUID(),
'studiensemester_kurzbz' => $lv->studiensemester_kurzbz
];
}, $antragsLvs);
$antrag_ids = array_unique(array_map(function ($lv) {
return $lv['studierendenantrag_id'];
}, $insert));
foreach ($antrag_ids as $antrag_id) {
$result = $this->StudierendenantragModel->loadIdAndStatusWhere([
'studierendenantrag_id' => $antrag_id
]);
if (isError($result))
return $this->outputJsonError(getError($result));
if (!hasData($result))
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $antrag_id]));
$antrag = current(getData($result));
if ($antrag->status != Studierendenantragstatus_model::STATUS_CREATED
&& $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED)
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_locked'));
}
if(!$antragsLvs)
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_no_lv'));
$result = $this->antraglib->saveLvs($insert);
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
public function getLvsAsRdf($prestudent_id)
{
// header für no cache
$this->output->set_header("Cache-Control: no-cache");
$this->output->set_header("Cache-Control: post-check=0, pre-check=0", false);
$this->output->set_header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
$this->output->set_header("Pragma: no-cache");
$this->output->set_header("Content-type: application/xhtml+xml");
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
$sem_akt = $this->variablelib->getVar('semester_aktuell');
$result = $this->antraglib->getLvsForPrestudent($prestudent_id, $sem_akt);
if (isError($result)) {
return $this->outputJsonError(getError($result));
}
$lvs = getData($result) ?: [];
$rdf_url = 'http://www.technikum-wien.at/antragnote';
$this->load->view('lehre/Antrag/Wiederholung/getLvs.rdf.php', [
'url' => $rdf_url,
'lvs' => $lvs
]);
}
public function moveLvsToZeugnis()
{
$anzahl = $this->input->post('anzahl');
$student_uid = $this->input->post('student_uid');
$this->load->model('education/Studierendenantraglehrveranstaltung_model', 'StudierendenantraglehrveranstaltungModel');
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$errormsg = array();
for($i=0; $i<$anzahl; $i++)
{
$id = $this->input->post('studierendenantrag_lehrveranstaltung_id_' . $i);
$result =$this->StudierendenantraglehrveranstaltungModel->load($id);
if(isError($result))
{
$errormsg[] = getError($result);
}
elseif(!hasData($result))
{
$errormsg[] = $this->p->t('studierendenantrag', 'error_no_lv_in_application');
}
else
{
$antragLv = getData($result)[0];
$result= $this->ZeugnisnoteModel->load([
'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id,
'student_uid'=> $student_uid,
'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz
]);
if(isError($result))
{
$errormsg[] = getError($result);
}
else
{
if (hasData($result))
{
$result = $this->ZeugnisnoteModel->update(
[
'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id,
'student_uid'=> $student_uid,
'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz
],
[
'note'=> $antragLv->note,
'uebernahmedatum' => date('c'),
'benotungsdatum' => $antragLv->insertamum,
'updateamum' => date('c'),
'bemerkung'=>$antragLv->anmerkung,
'updatevon'=>getAuthUID()
]
);
}
else
{
$result = $this->ZeugnisnoteModel->insert([
'lehrveranstaltung_id'=> $antragLv->lehrveranstaltung_id,
'student_uid'=> $student_uid,
'studiensemester_kurzbz' => $antragLv->studiensemester_kurzbz,
'note'=> $antragLv->note,
'uebernahmedatum' => date('c'),
'benotungsdatum' => $antragLv->insertamum,
'insertamum' => date('c'),
'bemerkung'=>$antragLv->anmerkung,
'insertvon'=>getAuthUID()
]);
}
if(isError($result))
{
$errormsg[] = getError($result);
}
}
}
}
if($errormsg)
$return = false;
else
$return = true;
$this->load->view('lehre/Antrag/Wiederholung/moveLvs.rdf.php', [
'return' => $return,
'errormsg' => $errormsg
]);
}
}
@@ -0,0 +1,213 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Mylv extends Auth_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'Student' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Studiensemester' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Lvs' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Info' => ['student/anrechnung_beantragen:r','user:r'], // TODO(chris): permissions?
'Pruefungen' => ['student/anrechnung_beantragen:r','user:r'] // TODO(chris): permissions?
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
*/
public function Student()
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
/**
*/
public function Studiensemester()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudiensemesterModel->getWhereStudentHasLvs(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
/**
*/
public function Lvs($studiensemester_kurzbz)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->getLvsByStudentWithGrades(getAuthUID(), $studiensemester_kurzbz, getUserLanguage());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
/**
*/
public function Info($studiensemester_kurzbz, $lehrveranstaltung_id)
{
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$result = $this->LehrveranstaltungModel->load($lehrveranstaltung_id);
if (isError($result))
return $this->outputJsonError(getError($result));
$lv = current(getData($result) ?: []);
if (!$lv)
return $this->outputJsonError('Could\'t find Lehrveranstaltung with id: ' . $lehrveranstaltung_id);
$this->load->model('education/Lehreinheitmitarbeiter_model', 'LehreinheitmitarbeiterModel');
$result = $this->LehreinheitmitarbeiterModel->getForLv($lehrveranstaltung_id, $studiensemester_kurzbz);
if (isError($result))
return $this->outputJsonError(getError($result));
$lvinfo = [];
$lvinfo['lektoren'] = getData($result) ?: [];
$kollisionsfreie_user = unserialize(KOLLISIONSFREIE_USER);
$lvinfo['lektoren'] = array_values(array_filter($lvinfo['lektoren'], function ($v) use ($kollisionsfreie_user) {
return !in_array($v->uid, $kollisionsfreie_user);
}));
$lvinfo['lvLeitung'] = array_values(array_filter($lvinfo['lektoren'], function ($v) {
return $v->lehrfunktion_kurzbz == 'LV-Leitung';
}));
$this->load->model('organisation/Organisationseinheit_model', 'OrganisationseinheitModel');
$result = $this->OrganisationseinheitModel->getWithType($lv->oe_kurzbz);
if (isError($result))
return $this->outputJsonError(getError($result));
$lvinfo['oe'] = current(getData($result) ?: []);
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$result = $this->BenutzerfunktionModel->getBenutzerFunktionenDetailed('Leitung', $lv->oe_kurzbz);
if (isError($result))
return $this->outputJsonError(getError($result));
$lvinfo['oeLeitung'] = getData($result) ?: [];
$result = $this->LehrveranstaltungModel->getKoordinator($lehrveranstaltung_id, $studiensemester_kurzbz);
if (isError($result))
return $this->outputJsonError(getError($result));
$lvinfo['koordinator'] = getData($result) ?: [];
if (defined('ACTIVE_ADDONS') && in_array('lvinfo', explode(';', ACTIVE_ADDONS)) && file_exists(FHCPATH . 'addons/lvinfo/include/lvinfo.class.php'))
{
require_once(FHCPATH . 'addons/lvinfo/include/lvinfo.class.php');
$lvinfoObj = new lvinfo();
$lvinfoObj->loadLVinfo($lehrveranstaltung_id, $studiensemester_kurzbz, null, true);
if (is_array($lvinfoObj->result))
{
$oldP = property_exists($this, 'p') ? $this->p : null;
$result = [];
$lvinfos = $lvinfoObj->result;
$lvinfoSet = new lvinfo();
$lvinfoSet->load_lvinfo_set($studiensemester_kurzbz);
foreach ($lvinfos as $lvi)
{
$this->p = null;
$this->loadPhrases('ui', $lvi->sprache);
$result[$lvi->sprache] = [];
foreach ($lvinfoSet->result as $set)
{
$key = $set->lvinfo_set_kurzbz;
if (!isset($lvi->data[$key]))
continue;
$info = [
'header' => $set->lvinfo_set_bezeichnung[$lvi->sprache]
];
if (isset($set->einleitungstext[$lvi->sprache]))
$info['subheader'] = $set->einleitungstext[$lvi->sprache];
switch ($set->lvinfo_set_typ)
{
case 'boolean':
$info['body'] = $this->p->t('ui', $lvi->data[$key] === true ? 'ja' : 'nein');
break;
case 'array':
$info['body'] = array_map('htmlspecialchars', $lvi->data[$key]);
break;
case 'editor':
$info['body'] = $lvi->data[$key];
break;
default:
$info['body'] = htmlspecialchars($lvi->data[$key]);
}
if ($info['body'])
$result[$lvi->sprache][] = $info;
}
}
if ($result)
{
$lvinfo['lvinfo'] = $result;
$lvinfo['lvinfoDefaultLang'] = getUserLanguage();
$this->load->model('system/Sprache_model', 'SpracheModel');
$result = $this->SpracheModel->loadMultiple(array_keys($result));
if (!isError($result))
{
$result = getData($result);
$lvinfo['sprachen'] = [];
foreach ($result as $sprache) {
$lvinfo['sprachen'][$sprache->sprache] = $sprache;
}
}
}
$this->p = $oldP;
}
}
$this->outputJsonSuccess($lvinfo);
}
/**
*/
public function Pruefungen($lehrveranstaltung_id)
{
$this->load->model('education/Pruefung_model', 'PruefungModel');
$result = $this->PruefungModel->getByStudentAndLv(getAuthUID(), $lehrveranstaltung_id, getUserLanguage());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
}
@@ -0,0 +1,73 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
*/
class Stundenplan extends Auth_Controller
{
/**
* Object initialization
*/
public function __construct()
{
parent::__construct([
'index' => ['basis/cis'],
'Reservierungen' => ['basis/cis'],
'Stunden' => ['basis/cis'],
]);
}
//------------------------------------------------------------------------------------------------------------------
// Public methods
/**
*/
public function index()
{
$this->load->model('ressource/Stundenplan_model', 'StundenplanModel');
/* $result = $this->StundenplanModel->loadForUid(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
*/
$res = $this->StundenplanModel->stundenplanGruppierung($this->StundenplanModel->getStundenplanQuery(getAuthUID()));
$res = getData($res);
$this->outputJsonSuccess($res);
}
/**
*/
public function Reservierungen()
{
$this->load->model('ressource/Reservierung_model', 'ReservierungModel');
$result = $this->ReservierungModel->loadForUid(getAuthUID());
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
/**
*/
public function Stunden()
{
$this->load->model('ressource/Stunde_model', 'StundeModel');
$result = $this->StundeModel->load();
if (isError($result))
return $this->outputJsonError(getError($result));
$this->outputJsonSuccess(getData($result));
}
}
@@ -9,6 +9,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
* NOTE: extends the FHC_Controller instead of the Auth_Controller because the FilterCmpt has its
* own permissions check
* TODO(chris): deprecated
*/
class Filter extends FHC_Controller
{
@@ -3,7 +3,7 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
* TODO(chris): deprecated
*/
class Phrasen extends FHC_Controller
{
@@ -3,7 +3,7 @@
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
*
* TODO(chris): deprecated
*/
class SearchBar extends FHC_Controller
{
@@ -0,0 +1,168 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Noten extends Auth_Controller
{
public function __construct()
{
parent::__construct([
'get' => 'student/noten:r',
'getZeugnis' => 'student/noten:r',
'update' => ['admin:w', 'assistenz:w']
]);
// Load Libraries
$this->load->library('VariableLib', ['uid' => getAuthUID()]);
}
public function get()
{
$this->load->model('codex/Note_model', 'NoteModel');
$result = $this->NoteModel->addOrder('note');
$result = $this->NoteModel->load();
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
return $this->outputJson($result);
}
public function getZeugnis($prestudent_id, $all = null)
{
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$result = $this->StudentModel->loadWhere([
'prestudent_id' => $prestudent_id
]);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
return $this->outputJson($result);
}
if (!hasData($result))
return $this->outputJsonSuccess(null);
$student_uid = current(getData($result))->student_uid;
$studiensemester_kurzbz = ($all === null) ? $this->variablelib->getVar('semester_aktuell') : null;
$result = $this->ZeugnisnoteModel->getZeugnisnoten($student_uid, $studiensemester_kurzbz);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
return $this->outputJson($result);
}
public function update()
{
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
$this->load->model('education/Zeugnisnote_model', 'ZeugnisnoteModel');
$this->load->library('form_validation');
$_POST = json_decode(utf8_encode($this->input->raw_input_stream), true);
if (empty($_POST) || !is_array(current($_POST))) {
$result = $this->hasPermissionUpdate($this->input->post('lehrveranstaltung_id'), $this->input->post('student_uid'));
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
return $this->outputJson($result);
}
$this->form_validation->set_rules('lehrveranstaltung_id', 'Lehrverantaltung ID', 'required|numeric');
$this->form_validation->set_rules('student_uid', 'Student UID', 'required');
$this->form_validation->set_rules('studiensemester_kurzbz', 'Studiensemester Kurzbezeichnung', 'required');
$this->form_validation->set_rules('note', 'Note', 'required|numeric');
$post = [$_POST];
} else {
foreach ($_POST as $i => $data) {
$lvid = isset($data['lehrveranstaltung_id']) ? $data['lehrveranstaltung_id'] : null;
$uid = isset($data['student_uid']) ? $data['student_uid'] : null;
$result = $this->hasPermissionUpdate($lvid, $uid);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_FORBIDDEN);
return $this->outputJson($result);
}
$this->form_validation->set_rules($i . '[lehrveranstaltung_id]', '#' . $i . ' Lehrverantaltung ID', 'required|numeric');
$this->form_validation->set_rules($i . '[student_uid]', '#' . $i . ' Student UID', 'required');
$this->form_validation->set_rules($i . '[studiensemester_kurzbz]', '#' . $i . ' Studiensemester Kurzbezeichnung', 'required');
$this->form_validation->set_rules($i . '[note]', '#' . $i . ' Note', 'required|numeric');
}
$post = $_POST;
}
if ($this->form_validation->run() == false) {
$this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
return $this->outputJsonError($this->form_validation->error_array());
}
$final_result = success();
$this->ZeugnisnoteModel->db->trans_start();
foreach ($post as $i => $data) {
$note = $data['note'];
unset($data['note']);
$result = $this->ZeugnisnoteModel->update($data, [
'note' => $note,
'benotungsdatum' => date('c'),
'updateamum' => date('c'),
'updatevon' => getAuthUID()
]);
if (isError($result)) {
$final_result = $result;
break;
}
}
$this->ZeugnisnoteModel->db->trans_complete();
if (isError($final_result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
$this->outputJson($final_result);
}
protected function hasPermissionUpdate($lehrveranstaltung_id, $student_uid)
{
// TODO(chris): error phrases!
if ($lehrveranstaltung_id === null || $student_uid === null)
return success();
$result = $this->StudentModel->load([$student_uid]);
if (isError($result))
return $result;
if (!hasData($result))
return error('Fehler beim Ermitteln des Studenten');
$student = current(getData($result));
if ($this->permissionlib->isBerechtigt('admin', 'suid', $student->studiengang_kz))
return success();
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $student->studiengang_kz))
return success();
$result = $this->StudienplanModel->getAllOesForLv($lehrveranstaltung_id);
if (isError($result))
return $result;
$oes = getData($result) ?: [];
$result = $this->LehrveranstaltungModel->getStg($lehrveranstaltung_id);
if (isError($result))
return $result;
if (hasData($result))
$oes[] = current(getData($result));
foreach ($oes as $oe) {
if ($this->permissionlib->isBerechtigt('admin', 'suid', $oe->oe_kurzbz))
return success();
if ($this->permissionlib->isBerechtigt('assistenz', 'suid', $oe->oe_kurzbz))
return success();
}
return error('Forbidden');
}
}
@@ -0,0 +1,43 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Studienplan extends Auth_Controller
{
public function __construct()
{
// TODO(chris): access!
parent::__construct([
'get' => self::PERM_LOGGED
]);
}
public function get()
{
$this->load->model('organisation/Studienplan_model', 'StudienplanModel');
$_POST = json_decode($this->input->raw_input_stream, true);
$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() == false) {
$this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
return $this->outputJsonError($this->form_validation->error_array());
}
$studiengang_kz = $this->input->post('studiengang_kz');
$studiensemester_kurzbz = $this->input->post('studiensemester_kurzbz');
$ausbildungssemester = $this->input->post('ausbildungssemester') ?: null;
$orgform_kurzbz = $this->input->post('orgform_kurzbz') ?: null;
$result = $this->StudienplanModel->getStudienplaeneBySemester($studiengang_kz, $studiensemester_kurzbz, $ausbildungssemester, $orgform_kurzbz);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
$this->outputJson($result);
}
}
@@ -0,0 +1,78 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class Studiensemester extends Auth_Controller
{
public function __construct()
{
// TODO(chris): access!
parent::__construct([
'index' => self::PERM_LOGGED,
'now' => self::PERM_LOGGED,
'set' => self::PERM_LOGGED
]);
}
public function index()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->StudiensemesterModel->addOrder('start');
$result = $this->StudiensemesterModel->load();
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
}
$this->outputJson($result);
}
public function now()
{
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$result = $this->StudiensemesterModel->getNearest();
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
$this->outputJson(getError($result));
}
$result = getData($result) ?: [];
if (count($result) != 1) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
$this->outputJsonError(count($result) ? 'Mehrere Studiensemester aktiv' : 'Kein Studiensemester aktiv');
} else {
$this->outputJsonSuccess(current($result)->studiensemester_kurzbz);
}
}
public function set()
{
$this->load->library('AuthLib');
$this->load->library('form_validation');
$_POST = json_decode(utf8_encode($this->input->raw_input_stream), true);
$this->form_validation->set_rules('studiensemester', 'Studiensemester', 'required');
if ($this->form_validation->run() == false) {
$this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
return $this->outputJsonError($this->form_validation->error_array());
}
$stdsem = $this->input->post('studiensemester');
$this->load->model('system/Variable_model', 'VariableModel');
$result = $this->VariableModel->setVariable(getAuthUID(), 'semester_aktuell', $stdsem);
if (isError($result)) {
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
return $this->outputJson($result);
}
$this->outputJsonSuccess(true);
}
}
+76
View File
@@ -0,0 +1,76 @@
<?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');
}
}
@@ -0,0 +1,216 @@
<?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['widgets'], $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['widgets'], $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['widgets'], $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['widgets'], $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['widgets']) || !isset($preset['widgets'][$funktion]))
$result[$funktion] = [];
else
$result[$funktion] = $preset['widgets'][$funktion];
}
else
$result[$funktion] = [];
}
return $this->outputJsonSuccess($result);
}
}
@@ -0,0 +1,86 @@
<?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) ?: []);
}
}
@@ -0,0 +1,58 @@
<?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');
}
}
@@ -0,0 +1,109 @@
<?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));
}
}
@@ -195,10 +195,10 @@ class AnrechnungJob extends JOB_Controller
$studiengang_bezeichnung = $this->StudiengangModel->load($studiengang_kz)->retval[0]->stg_bezeichnung;
// Get STGL mail address
$stglMailReceiver_arr = self::_getSTGLMailAddress($studiengang_kz);
$stglMailReceiver_arr = $this->_getSTGLMailAddress($studiengang_kz);
// Get HTML table with new Anrechnungen of that STG plus amount of them
list ($anrechnungen_amount, $anrechnungen_table) = self::_getSTGLMailDataTable($studiengang_kz, $anrechnungen);
list ($anrechnungen_amount, $anrechnungen_table) = $this->_getSTGLMailDataTable($studiengang_kz, $anrechnungen);
// Link to Antrag genehmigen dashboard
$url =
@@ -514,8 +514,6 @@ html;
'vorname' => $stgl->vorname
);
}
return $stglMailAdress_arr;
}
// If not available, get assistance mail address
else
@@ -524,12 +522,13 @@ html;
if (hasData($result))
{
return array(
$result->retval[0]->email,
''
$stglMailAdress_arr[]= array(
'to' => $result->retval[0]->email,
'vorname' => ''
);
}
}
return $stglMailAdress_arr;
}
// Build HTML table with yesterdays new Anrechnungen of the given STG
+23 -5
View File
@@ -29,6 +29,10 @@ class AntragJob extends JOB_Controller
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('organisation/Studiengang_model', 'StudiengangModel');
$this->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$this->loadPhrases([
'lehre'
]);
}
/**
@@ -179,8 +183,8 @@ class AntragJob extends JOB_Controller
$data,
$to,
'Anträge - Aktion(en) erforderlich',
DEFAULT_SANCHO_HEADER_IMG,
DEFAULT_SANCHO_FOOTER_IMG,
'',
'',
'',
$cc
))
@@ -412,10 +416,12 @@ class AntragJob extends JOB_Controller
$this->StudierendenantragModel->addSelect('studiensemester_kurzbz');
$this->StudierendenantragModel->addSelect('s.insertamum');
$this->StudierendenantragModel->addSelect('s.insertvon');
$this->StudierendenantragModel->addJoin('public.tbl_student pts', 'prestudent_id');
$this->StudierendenantragModel->addSelect('pts.student_uid');
$this->StudierendenantragModel->db->where_in(
'public.get_rolle_prestudent(prestudent_id, studiensemester_kurzbz)',
$this->config->item('antrag_prestudentstatus_whitelist')
$this->config->item('antrag_prestudentstatus_whitelist_abmeldung')
);
$result = $this->StudierendenantragModel->getWithLastStatusWhere([
@@ -449,11 +455,23 @@ class AntragJob extends JOB_Controller
if (isError($result))
$this->logError(getError($result));
$this->load->model('crm/Statusgrund_model', 'StatusgrundModel');
$result = $this->StatusgrundModel->loadWhere(['statusgrund_kurzbz' => 'abbrecherStgl']);
if (isError($result)) {
$this->logError(getError($result));
continue;
} elseif (!hasData($result)) {
$this->logError($this->p->t('lehre', 'error_noStatusgrund', ['statusgrund_kurzbz' => 'abbrecherStgl']));
continue;
}
$statusgrund = current(getData($result));
$result = $this->prestudentlib->setAbbrecher(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
'AntragJob',
'abbrecherStgl',
$statusgrund->statusgrund_id,
$antrag->insertamum,
null,
$antrag->insertvon ?: $insertvon
@@ -484,7 +502,7 @@ class AntragJob extends JOB_Controller
$person = current(getData($result));
$email = $studiengang->email;
$dataMail = array(
'prestudent' => $antrag->prestudent_id,
'prestudent' => 'UID: ' . $antrag->student_uid . ', PreStudentId: ' . $antrag->prestudent_id,
'studiensemester' => $antrag->studiensemester_kurzbz,
'name' => trim($person->vorname . ' '. $person->nachname),
);
@@ -9,8 +9,8 @@ class IssueResolver extends IssueResolver_Controller
{
parent::__construct();
// set fehler codes which can be resolved by the job
// structure: fehlercode => class (library) name for resolving
// set fehler codes which can be resolved by the job, with own resolver defined
// structure: fehlercode => class (library) name for resolving in "resolvers" folder
$this->_codeLibMappings = array(
'CORE_ZGV_0001' => 'CORE_ZGV_0001',
'CORE_ZGV_0002' => 'CORE_ZGV_0002',
@@ -30,7 +30,6 @@ class IssueResolver extends IssueResolver_Controller
'CORE_STG_0002' => 'CORE_STG_0002',
'CORE_STG_0003' => 'CORE_STG_0003',
'CORE_STG_0004' => 'CORE_STG_0004',
'CORE_STUDENTSTATUS_0001' => 'CORE_STUDENTSTATUS_0001',
'CORE_STUDENTSTATUS_0002' => 'CORE_STUDENTSTATUS_0002',
'CORE_STUDENTSTATUS_0003' => 'CORE_STUDENTSTATUS_0003',
'CORE_STUDENTSTATUS_0004' => 'CORE_STUDENTSTATUS_0004',
@@ -45,10 +44,17 @@ class IssueResolver extends IssueResolver_Controller
'CORE_STUDENTSTATUS_0013' => 'CORE_STUDENTSTATUS_0013',
'CORE_STUDENTSTATUS_0014' => 'CORE_STUDENTSTATUS_0014',
'CORE_STUDENTSTATUS_0015' => 'CORE_STUDENTSTATUS_0015',
'CORE_STUDENTSTATUS_0016' => 'CORE_STUDENTSTATUS_0016',
'CORE_PERSON_0001' => 'CORE_PERSON_0001',
'CORE_PERSON_0002' => 'CORE_PERSON_0002',
'CORE_PERSON_0003' => 'CORE_PERSON_0003',
'CORE_PERSON_0004' => 'CORE_PERSON_0004'
);
// fehler which are resolved by the job the same way as they are produced
// structure: fehlercode => class (library) name for resolving in "plausichecks" folder
$this->_codeProducerLibMappings = array(
'CORE_STUDENTSTATUS_0001' => 'AbbrecherAktiv',
);
}
}
@@ -51,7 +51,7 @@ class OneTimeMessages extends JOB_Controller
FROM public.tbl_prestudent p
JOIN public.tbl_prestudentstatus ps USING (prestudent_id)
JOIN public.tbl_studiengang s USING (studiengang_kz)
WHERE ps.status_kurzbz = \'Wartender\'
WHERE get_rolle_prestudent(ps.prestudent_id, NULL) = \'Wartender\'
AND ps.studiensemester_kurzbz = ?
AND ps.datum <= NOW() - \''.$days.' days\'::interval
AND s.typ = ?
@@ -431,8 +431,8 @@ class ReihungstestJob extends JOB_Controller
$mailcontent_data_arr,
$applicant->email,
'Ihre Anmeldung zum Reihungstest - Reminder / Your registration for the placement test - Reminder',
DEFAULT_SANCHO_HEADER_IMG,
DEFAULT_SANCHO_FOOTER_IMG,
'',
'',
$from,
'',
$bcc);
@@ -876,7 +876,7 @@ class ReihungstestJob extends JOB_Controller
JOIN PUBLIC.tbl_studiengang ON (tbl_prestudent.studiengang_kz = tbl_studiengang.studiengang_kz)
WHERE tbl_prestudent.person_id = ".$row_ps->person_id."
AND tbl_prestudent.prestudent_id != ".$row_ps->prestudent_id."
AND get_rolle_prestudent (tbl_prestudent.prestudent_id, '".$row_ps->studiensemester_kurzbz."') IN ('Aufgenommener','Bewerber','Wartender')
AND get_rolle_prestudent (tbl_prestudent.prestudent_id, '".$row_ps->studiensemester_kurzbz."') IN ('Aufgenommener','Bewerber','Wartender', 'Student')
AND studiensemester_kurzbz = '".$row_ps->studiensemester_kurzbz."'
AND tbl_studiengang.typ IN ('b', 'm')
AND priorisierung > ".$row_ps->priorisierung."
@@ -894,12 +894,22 @@ class ReihungstestJob extends JOB_Controller
{
foreach ($resultNiedrPrios->retval as $rowNiedrPrios)
{
// nur Info wenn aufgenommen oder master
if ($rowNiedrPrios->laststatus == 'Aufgenommener' || $rowNiedrPrios->studiengang_typ == 'm')
// nur Info wenn aufgenommen/student oder master
if ($rowNiedrPrios->laststatus == 'Aufgenommener' || $rowNiedrPrios->laststatus == 'Student' || $rowNiedrPrios->studiengang_typ == 'm')
{
// Mail zur Info an Assistenz schicken, dass in höherer Prio aufgenommen wurde
$mailArray[$rowNiedrPrios->studiengang_kz][$rowNiedrPrios->orgform_kurzbz]['AufnahmeHoeherePrio'][]
= $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')';
if ($rowNiedrPrios->laststatus == 'Aufgenommener')
{
// Mail zur Info an Assistenz schicken, dass in höherer Prio aufgenommen wurde
$mailArray[$rowNiedrPrios->studiengang_kz][$rowNiedrPrios->orgform_kurzbz]['AufnahmeHoeherePrio'][]
= $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')';
}
else if ($rowNiedrPrios->laststatus == 'Student')
{
$mailArray[$rowNiedrPrios->studiengang_kz][$rowNiedrPrios->orgform_kurzbz]['StudentHoeherePrio'][]
= $rowNiedrPrios->nachname.' '.$rowNiedrPrios->vorname.' ('.$rowNiedrPrios->prestudent_id.')';
}
}
elseif ($rowNiedrPrios->laststatus == 'Bewerber' && $row_ps->prestudenstatus_datum > $rowNiedrPrios->datum)
{
@@ -1023,7 +1033,7 @@ class ReihungstestJob extends JOB_Controller
{
$studiengang = $this->StudiengangModel->load($stg);
$mailcontent = '';
$content = false;
foreach ($orgform AS $art=>$value)
{
// Orgform nur dazu schreiben, wenn es mehr als Eine gibt
@@ -1044,6 +1054,7 @@ class ReihungstestJob extends JOB_Controller
$mailcontent .= '<tr><td style="font-family: verdana, sans-serif; border: 1px solid grey; padding: 3px">'.$bewerber.'</td></tr>';
}
$mailcontent .= '</tbody></table><br><br>';
$content = true;
}
if (isset($value['AufnahmeHoeherePrio']) && !isEmptyArray($value['AufnahmeHoeherePrio']))
{
@@ -1058,6 +1069,21 @@ class ReihungstestJob extends JOB_Controller
$mailcontent .= '<tr><td style="font-family: verdana, sans-serif; border: 1px solid grey; padding: 3px">'.$bewerber.'</td></tr>';
}
$mailcontent .= '</tbody></table>';
$content = true;
}
if (isset($value['StudentHoeherePrio']) && !isEmptyArray($value['StudentHoeherePrio']))
{
$mailcontent .= '<p style="font-family: verdana, sans-serif;">
Folgende Studenten wurden in einem höher priorisierten Studiengang aufgenommen:</p>';
$mailcontent .= '<table style="border-collapse: collapse; border: 1px solid grey;">';
$mailcontent .= ' <tbody>';
sort($value['StudentHoeherePrio']);
foreach ($value['StudentHoeherePrio'] AS $key=>$bewerber)
{
$mailcontent .= '<tr><td style="font-family: verdana, sans-serif; border: 1px solid grey; padding: 3px">'.$bewerber.'</td></tr>';
}
$mailcontent .= '</tbody></table>';
$content = true;
}
if (isset($value['AbgewiesenHoeherePrio']) && !isEmptyArray($value['AbgewiesenHoeherePrio']))
{
@@ -1071,6 +1097,7 @@ class ReihungstestJob extends JOB_Controller
$mailcontent .= '<tr><td style="font-family: verdana, sans-serif; border: 1px solid grey; padding: 3px">'.$bewerber.'</td></tr>';
}
$mailcontent .= '</tbody></table>';
$content = true;
}
if ($bcc != '' && isset($value['AbgewiesenWeilBewerber']) && !isEmptyArray($value['AbgewiesenWeilBewerber']))
{
@@ -1085,13 +1112,14 @@ class ReihungstestJob extends JOB_Controller
$mailcontent .= '<tr><td style="font-family: verdana, sans-serif; border: 1px solid grey; padding: 3px">'.$bewerber.'</td></tr>';
}
$mailcontent .= '</tbody></table>';
$content = true;
}
}
$mailcontent_data_arr['table'] = $mailcontent;
// Send email in Sancho design
if (!isEmptyString($mailcontent))
if (!isEmptyString($mailcontent) && $content === true)
{
sendSanchoMail(
'Sancho_ReihungstestteilnehmerJob',
@@ -1,114 +0,0 @@
<?php
if (!defined("BASEPATH")) exit("No direct script access allowed");
use vertragsbestandteil\VertragsbestandteilFactory;
/**
* Description of VertragsbestandteilTest
*
* @author bambi
*/
class VertragsbestandteilTest extends JOB_Controller
{
public function __construct()
{
parent::__construct();
$this->load->library('vertragsbestandteil/VertragsbestandteilLib',
null, 'VertragsbestandteilLib');
$this->load->library('vertragsbestandteil/GehaltsbestandteilLib',
null, 'GehaltsbestandteilLib');
}
public function testFetch()
{
$dienstverhaeltnis_id = 1;
$stichtag = null;
foreach($this->VertragsbestandteilLib->fetchVertragsbestandteile(
$dienstverhaeltnis_id, $stichtag) as $vertragsbestandteil)
{
//print_r($vertragsbestandteil);
echo $vertragsbestandteil . "\n";
}
}
public function testUpdate()
{
$now = new DateTime();
$data = new stdClass();
$data->vertragsbestandteil_id = 32;
$data->von = '2022-12-05';
$data->wochenstunden = 45.0;
$data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_STUNDEN;
$vb = VertragsbestandteilFactory::getVertragsbestandteil($data);
try
{
$this->VertragsbestandteilLib->storeVertragsbestandteil($vb);
echo "Update successful.\n";
}
catch( Exception $ex )
{
echo "Update failed.\n";
}
}
public function testInsert()
{
$now = new DateTime();
$data = new stdClass();
$data->dienstverhaeltnis_id = 1;
$data->von = '2022-12-01';
$data->insertamum = $now->format(DateTime::ATOM);
$data->insertvon = 'ma0080';
$data->vertragsbestandteiltyp_kurzbz = VertragsbestandteilFactory::VERTRAGSBESTANDTEIL_FUNKTION;
$data->benutzerfunktion_id = 112667;
$data->anmerkung = 'test funkton';
$data->kuendigungsrelevant = false;
$vb = VertragsbestandteilFactory::getVertragsbestandteil($data);
try
{
$this->VertragsbestandteilLib->storeVertragsbestandteil($vb);
echo "Insert successful.\n";
}
catch( Exception $ex )
{
echo "Insert failed.\n";
}
}
public function testGehaltsbestandteilInsert()
{
$data = new stdClass();
$data->gehaltsbestandteil_id = 2;
/*
$data->dienstverhaeltnis_id = 39;
$data->vertragsbestandteil_id = 123;
$data->gehaltstyp_kurzbz = 'zulage';
$data->von = '2023-04-01';
$data->bis = '2023-08-31';
$data->anmerkung = 'test anmerkung';
$data->grundbetrag = 100;
$data->betrag_valorisiert = 100;
$data->valorisierung = true;
*/
$data->auszahlungen = 12;
$gb = new \vertragsbestandteil\Gehaltsbestandteil();
$gb->hydrateByStdClass($data);
print_r($gb->toStdClass());
$this->GehaltsbestandteilLib->storeGehaltsbestandteil($gb);
}
}
@@ -6,58 +6,59 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
*/
class Pruefungsprotokoll extends Auth_Controller
{
private $_uid; // uid of the logged user
private $_uid; // uid of the logged user
/**
* Constructor
*/
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/pruefungsbeurteilung:r',
'Protokoll' => 'lehre/pruefungsbeurteilung:r',
'saveProtokoll' => 'lehre/pruefungsbeurteilung:rw',
)
);
/**
* Constructor
*/
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/pruefungsbeurteilung:r',
'Protokoll' => 'lehre/pruefungsbeurteilung:r',
'showProtokoll' => 'lehre/pruefungsbeurteilung:r',
'saveProtokoll' => 'lehre/pruefungsbeurteilung:rw',
)
);
// Load models
$this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel');
$this->load->model('education/Abschlussbeurteilung_model', 'AbschlussbeurteilungModel');
// Load models
$this->load->model('education/Abschlusspruefung_model', 'AbschlusspruefungModel');
$this->load->model('education/Abschlussbeurteilung_model', 'AbschlussbeurteilungModel');
$this->load->library('PermissionLib');
$this->load->library('AuthLib');
$this->load->library('PermissionLib');
$this->load->library('AuthLib');
// Load language phrases
$this->loadPhrases(
array(
'ui',
'global',
'person',
'abschlusspruefung',
// Load language phrases
$this->loadPhrases(
array(
'ui',
'global',
'person',
'abschlusspruefung',
'password',
'lehre'
)
);
)
);
$this->_setAuthUID(); // sets property uid
$this->_setAuthUID(); // sets property uid
$this->setControllerId(); // sets the controller id
}
$this->setControllerId(); // sets the controller id
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function index()
{
$this->load->library('WidgetLib');
// Protokolle anzeigen seit heute / letzte Woche / alle
$period = $this->input->post('period');
$period = (!is_null($period)) ? $period : 'today';
$data = array('period' => $period);
$this->load->view('lehre/pruefungsprotokollUebersicht.php', $data);
}
@@ -66,47 +67,15 @@ class Pruefungsprotokoll extends Auth_Controller
*/
public function Protokoll()
{
$abschlusspruefung_id = $this->input->get('abschlusspruefung_id');
$this->load->view('lehre/pruefungsprotokoll.php', $this->_getPruefungsprotokollData());
}
if (!is_numeric($abschlusspruefung_id))
show_error('invalid abschlusspruefung');
$abschlusspruefung_saved = false;
$abschlusspruefung = $this->_getAbschlusspruefungBerechtigt($abschlusspruefung_id);
if (isError($abschlusspruefung))
show_error(getError($abschlusspruefung));
else
{
$abschlusspruefung = getData($abschlusspruefung);
$abschlusspruefung_saved = isset($abschlusspruefung->protokoll) && isset($abschlusspruefung->abschlussbeurteilung_kurzbz);
}
$this->AbschlussbeurteilungModel->addOrder("sort", "ASC");
$this->AbschlussbeurteilungModel->addOrder("(CASE WHEN abschlussbeurteilung_kurzbz = 'ausgezeichnet' THEN 1
WHEN abschlussbeurteilung_kurzbz = 'gut' THEN 2
WHEN abschlussbeurteilung_kurzbz = 'bestanden' THEN 3
WHEN abschlussbeurteilung_kurzbz = 'angerechnet' THEN 4
ELSE 5
END
)");
$abschlussbeurteilung = $this->AbschlussbeurteilungModel->load();
if (isError($abschlussbeurteilung))
show_error(getError($abschlussbeurteilung));
else
$abschlussbeurteilung = getData($abschlussbeurteilung);
$language = getUserLanguage();
$data = array(
'abschlusspruefung' => $abschlusspruefung,
'abschlussbeurteilung' => $abschlussbeurteilung,
'abschlusspruefung_saved' => $abschlusspruefung_saved,
'language' => $language
);
$this->load->view('lehre/pruefungsprotokoll.php', $data);
/**
* Show Pruefungsprotokoll.
*/
public function showProtokoll()
{
$this->load->view('lehre/pruefungsprotokoll.php', array_merge($this->_getPruefungsprotokollData(), array('readonly' => true)));
}
/**
@@ -168,18 +137,66 @@ class Pruefungsprotokoll extends Auth_Controller
$this->outputJsonError($this->p->t('ui', 'ungueltigeParameter'));
}
// -----------------------------------------------------------------------------------------------------------------
// Private methods
// -----------------------------------------------------------------------------------------------------------------
// Private methods
/**
* Retrieve the UID of the logged user and checks if it is valid
*/
private function _setAuthUID()
{
$this->_uid = getAuthUID();
/**
* 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');
}
if (!$this->_uid) show_error('User authentification failed');
}
/**
*
* @param
* @return object success or error
*/
private function _getPruefungsprotokollData()
{
$abschlusspruefung_id = $this->input->get('abschlusspruefung_id');
if (!is_numeric($abschlusspruefung_id))
show_error('invalid abschlusspruefung');
$abschlusspruefung_saved = false;
$abschlusspruefung = $this->_getAbschlusspruefungBerechtigt($abschlusspruefung_id);
if (isError($abschlusspruefung))
show_error(getError($abschlusspruefung));
else
{
$abschlusspruefung = getData($abschlusspruefung);
$abschlusspruefung_saved = isset($abschlusspruefung->protokoll) && isset($abschlusspruefung->abschlussbeurteilung_kurzbz);
}
$this->AbschlussbeurteilungModel->addOrder("sort", "ASC");
$this->AbschlussbeurteilungModel->addOrder("(CASE WHEN abschlussbeurteilung_kurzbz = 'ausgezeichnet' THEN 1
WHEN abschlussbeurteilung_kurzbz = 'gut' THEN 2
WHEN abschlussbeurteilung_kurzbz = 'bestanden' THEN 3
WHEN abschlussbeurteilung_kurzbz = 'angerechnet' THEN 4
ELSE 5
END
)");
$abschlussbeurteilung = $this->AbschlussbeurteilungModel->load();
if (isError($abschlussbeurteilung))
show_error(getError($abschlussbeurteilung));
else
$abschlussbeurteilung = getData($abschlussbeurteilung);
$language = getUserLanguage();
return array(
'abschlusspruefung' => $abschlusspruefung,
'abschlussbeurteilung' => $abschlussbeurteilung,
'abschlusspruefung_saved' => $abschlusspruefung_saved,
'language' => $language
);
}
/**
* Retrieves an Abschlussprüfung, with permission check
@@ -187,7 +204,7 @@ class Pruefungsprotokoll extends Auth_Controller
* @param $abschlusspruefung_id
* @return object success or error
*/
private function _getAbschlusspruefungBerechtigt($abschlusspruefung_id)
private function _getAbschlusspruefungBerechtigt($abschlusspruefung_id)
{
$result = error('Error when getting Abschlusspruefung');
@@ -21,6 +21,7 @@ class Studierendenantrag extends FHC_Controller
// Load Models
$this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel');
$this->load->model('person/Person_model', 'PersonModel');
// Load language phrases
$this->loadPhrases([
@@ -102,6 +103,7 @@ class Studierendenantrag extends FHC_Controller
public function abmeldungstgl($prestudent_id, $studierendenantrag_id = null)
{
$this->load->view('lehre/Antrag/Create', [
'prestudent_id' => $prestudent_id,
'studierendenantrag_id' => $studierendenantrag_id,
@@ -185,4 +187,4 @@ class Studierendenantrag extends FHC_Controller
return $strRequiredPermissions;
}
}
}
@@ -22,14 +22,14 @@ class approveAnrechnungDetail extends Auth_Controller
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/anrechnung_genehmigen:r',
'download' => 'lehre/anrechnung_genehmigen:r',
'approve' => 'lehre/anrechnung_genehmigen:rw',
'reject' => 'lehre/anrechnung_genehmigen:rw',
'requestRecommendation' => 'lehre/anrechnung_genehmigen:rw',
'withdraw' => 'lehre/anrechnung_genehmigen:rw',
'withdrawRequestRecommendation' => 'lehre/anrechnung_genehmigen:rw',
'saveEmpfehlungsNotiz' => 'lehre/anrechnung_genehmigen:rw'
'index' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN .':r',
'download' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN .':r',
'approve' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN .':rw',
'reject' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN .':rw',
'requestRecommendation' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN .':rw',
'withdraw' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN .':rw',
'withdrawRequestRecommendation' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN .':rw',
'saveEmpfehlungsNotiz' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN .':rw'
)
);
@@ -140,6 +140,9 @@ class approveAnrechnungDetail extends Auth_Controller
// Approve Anrechnung
foreach ($data as $item)
{
if (!$this->_checkBerechtigung($item['anrechnung_id']))
continue;
if ($this->anrechnunglib->approveAnrechnung($item['anrechnung_id']))
{
$json[]= array(
@@ -185,6 +188,9 @@ class approveAnrechnungDetail extends Auth_Controller
// Reject Anrechnung
foreach ($data as $item)
{
if (!$this->_checkBerechtigung($item['anrechnung_id']))
continue;
if ($this->anrechnunglib->rejectAnrechnung($item['anrechnung_id'], $item['begruendung']))
{
$json[]= array(
@@ -220,6 +226,9 @@ class approveAnrechnungDetail extends Auth_Controller
return $this->outputJsonError('Fehler beim Übertragen der Daten.');
}
if (!$this->_checkBerechtigung($anrechnung_id))
$this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern'));
$retval = array();
// Check if Anrechnungs-LV has lector
@@ -285,6 +294,9 @@ class approveAnrechnungDetail extends Auth_Controller
$this->terminateWithJsonError($this->p->t('ui', 'errorFelderFehlen'));
}
if (!$this->_checkBerechtigung($anrechnung_id))
$this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern'));
// Delete last status approved / rejected.
// If last status is 'approved', Genehmigung is resetted.
$result = $this->AnrechnungModel->withdrawApprovement($anrechnung_id);
@@ -313,6 +325,9 @@ class approveAnrechnungDetail extends Auth_Controller
show_error('Wrong parameter.');
}
if (!$this->_checkBerechtigung($anrechnung_id))
$this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern'));
// Get boolean empfehlung of given Anrechnung
if (!$result = getData($this->AnrechnungModel->load($anrechnung_id))[0])
{
@@ -362,6 +377,9 @@ class approveAnrechnungDetail extends Auth_Controller
$this->terminateWithJsonError($this->p->t('ui', 'systemFehler'));
}
if (!$this->_checkBerechtigung($anrechnung_id))
$this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern'));
// Save Empfehlungstext
$result = self::_saveEmpfehlungsNotiz($anrechnung_id, $empfehlungstext, $notiz_id);
@@ -601,4 +619,17 @@ class approveAnrechnungDetail extends Auth_Controller
$this->_uid
);
}
private function _checkBerechtigung($anrechnung_id)
{
$this->AnrechnungModel->addJoin('tbl_prestudent', 'prestudent_id');
$result = $this->AnrechnungModel->loadWhere(array('anrechnung_id' => $anrechnung_id));
if (isError($result) || !hasData($result))
show_error('Failed retrieving anrechnung');
$antragData = getData($result)[0];
return $this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN, 'suid', $antragData->studiengang_kz);
}
}
@@ -20,11 +20,11 @@ class approveAnrechnungUebersicht extends Auth_Controller
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/anrechnung_genehmigen:r',
'download' => 'lehre/anrechnung_genehmigen:r',
'approve' => 'lehre/anrechnung_genehmigen:rw',
'reject' => 'lehre/anrechnung_genehmigen:rw',
'requestRecommendation' => 'lehre/anrechnung_genehmigen:rw'
'index' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN . ':r',
'download' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN . ':r',
'approve' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN . ':rw',
'reject' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN . ':rw',
'requestRecommendation' => self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN . ':rw'
)
);
@@ -135,6 +135,9 @@ class approveAnrechnungUebersicht extends Auth_Controller
// Approve Anrechnung
foreach ($data as $item)
{
if (!$this->_checkBerechtigung($item['anrechnung_id']))
continue;
// Get Prestudent
$this->AnrechnungModel->addSelect('prestudent_id');
$result = $this->AnrechnungModel->load($item['anrechnung_id']);
@@ -174,6 +177,9 @@ class approveAnrechnungUebersicht extends Auth_Controller
// Reject Anrechnung
foreach ($data as $item)
{
if (!$this->_checkBerechtigung($item['anrechnung_id']))
continue;
if ($this->anrechnunglib->rejectAnrechnung($item['anrechnung_id'], $item['begruendung']))
{
$json[]= array(
@@ -212,6 +218,9 @@ class approveAnrechnungUebersicht extends Auth_Controller
foreach ($data as $item)
{
if (!$this->_checkBerechtigung($item['anrechnung_id']))
continue;
// Check if Anrechnungs-LV has lector
if (!$this->anrechnunglib->LVhasLector($item['anrechnung_id']))
{
@@ -483,4 +492,17 @@ class approveAnrechnungUebersicht extends Auth_Controller
return $oeLeitung_arr;
}
private function _checkBerechtigung($anrechnung_id)
{
$this->AnrechnungModel->addJoin('tbl_prestudent', 'prestudent_id');
$result = $this->AnrechnungModel->loadWhere(array('anrechnung_id' => $anrechnung_id));
if (isError($result) || !hasData($result))
show_error('Failed retrieving anrechnung');
$antragData = getData($result)[0];
return $this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_GENEHMIGEN, 'suid', $antragData->studiengang_kz);
}
}
@@ -13,9 +13,9 @@ class CreateAnrechnung extends Auth_Controller
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/anrechnung_anlegen:r',
'getLVsByStudent' => 'lehre/anrechnung_anlegen:r',
'create' => 'lehre/anrechnung_anlegen:rw'
'index' => self::BERECHTIGUNG_ANRECHNUNG_ANLEGEN . ':r',
'getLVsByStudent' => self::BERECHTIGUNG_ANRECHNUNG_ANLEGEN . ':r',
'create' => self::BERECHTIGUNG_ANRECHNUNG_ANLEGEN . ':rw'
)
);
@@ -24,6 +24,7 @@ class CreateAnrechnung extends Auth_Controller
$this->load->model('education/Anrechnungstatus_model', 'AnrechnungstatusModel');
$this->load->model('content/DmsVersion_model', 'DmsVersionModel');
$this->load->model('crm/Student_model', 'StudentModel');
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$this->load->model('education/Lehrveranstaltung_model', 'LehrveranstaltungModel');
// Load libraries
@@ -67,13 +68,22 @@ class CreateAnrechnung extends Auth_Controller
$result = $this->StudiensemesterModel->getNearest();
$studiensemester_kurzbz = getData($result)[0]->studiensemester_kurzbz;
}
$studiengang_kz_arr = array();
// Get Studiengaenge the user is entitled for
if (!$studiengang_kz_arr = $this->permissionlib->getSTG_isEntitledFor(self::BERECHTIGUNG_ANRECHNUNG_ANLEGEN))
if ($studiengaenge = $this->permissionlib->getSTG_isEntitledFor(self::BERECHTIGUNG_ANRECHNUNG_ANLEGEN, 'suid'))
{
show_error('Failed retrieving Studiengaenge');
foreach($studiengaenge as $studiengang)
{
$berechtigt = $this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_ANLEGEN, 'suid', $studiengang);
if ($berechtigt)
$studiengang_kz_arr[]= $studiengang;
}
}
else
show_error('Failed retrieving Studiengaenge');
// Get Anrechnungsbegruendungen
$this->load->model('education/Anrechnungbegruendung_model', 'AnrechnungbegruendungModel');
$begruendung_arr = getData($this->AnrechnungbegruendungModel->load());
@@ -124,7 +134,17 @@ class CreateAnrechnung extends Auth_Controller
$lehrveranstaltung_id = $this->input->post('lehrveranstaltung_id');
$begruendung_id = $this->input->post('begruendung_id');
$herkunftKenntnisse = $this->input->post('herkunftKenntnisse');
$prestudent = $this->PrestudentModel->load(array('prestudent_id' => $prestudent_id));
if (!hasData($prestudent) || isError($prestudent))
$this->terminateWithJsonError($this->p->t('ui', 'keineBerechtigung'));
$studiengang = getData($prestudent)[0]->studiengang_kz;
if (!$this->permissionlib->isBerechtigt(self::BERECHTIGUNG_ANRECHNUNG_ANLEGEN, 'suid', $studiengang))
$this->terminateWithJsonError($this->p->t('ui', 'keineBerechtigung'));
// Validate upload file
if (empty($_FILES['uploadfile']['name']))
{
@@ -111,8 +111,13 @@ class requestAnrechnung extends Auth_Controller
$lehrveranstaltung_id = $this->input->post('lv_id');
$studiensemester_kurzbz = $this->input->post('studiensemester');
$bestaetigung = $this->input->post('bestaetigung');
$begruendung_ects = $this->input->post('begruendung_ects');
$begruendung_lvinhalt = $this->input->post('begruendung_lvinhalt');
$begruendung_ects = $this->config->item('explain_equivalence') === TRUE
? $this->input->post('begruendung_ects')
: NULL;
$begruendung_lvinhalt = $this->config->item('explain_equivalence') === TRUE
? $this->input->post('begruendung_lvinhalt')
: NULL;
// Validate data
if (empty($_FILES['uploadfile']['name']))
@@ -124,8 +129,8 @@ class requestAnrechnung extends Auth_Controller
isEmptyString($anmerkung) ||
isEmptyString($lehrveranstaltung_id) ||
isEmptyString($studiensemester_kurzbz) ||
isEmptyString($begruendung_ects) ||
isEmptyString($begruendung_lvinhalt))
($this->config->item('explain_equivalence') === TRUE && isEmptyString($begruendung_ects)) ||
($this->config->item('explain_equivalence') === TRUE && isEmptyString($begruendung_lvinhalt)))
{
return $this->outputJsonError($this->p->t('ui', 'errorFelderFehlen'));
}
@@ -168,7 +173,7 @@ class requestAnrechnung extends Auth_Controller
// Hold just inserted DMS ID
$lastInsert_dms_id = $result->retval['dms_id'];
// Save Anrechnung and Anrechnungstatus
$result = $this->AnrechnungModel->createAnrechnungsantrag(
$prestudent_id,
@@ -21,10 +21,10 @@ class reviewAnrechnungDetail extends Auth_Controller
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/anrechnung_empfehlen:rw',
'download' => 'lehre/anrechnung_empfehlen:rw',
'recommend' => 'lehre/anrechnung_empfehlen:rw',
'dontRecommend' => 'lehre/anrechnung_empfehlen:rw'
'index' => self::BERECHTIGUNG_ANRECHNUNG_EMPFEHLEN . ':rw',
'download' => self::BERECHTIGUNG_ANRECHNUNG_EMPFEHLEN . ':rw',
'recommend' => self::BERECHTIGUNG_ANRECHNUNG_EMPFEHLEN . ':rw',
'dontRecommend' => self::BERECHTIGUNG_ANRECHNUNG_EMPFEHLEN . ':rw'
)
);
@@ -127,17 +127,23 @@ class reviewAnrechnungDetail extends Auth_Controller
foreach ($data as $item)
{
// Approve Anrechnung
if($this->anrechnunglib->recommendAnrechnung($item['anrechnung_id']))
$empfehlungData = $this->anrechnunglib->getEmpfehlungData($item['anrechnung_id']);
$isEmpfehlungsberechtigt = $this->anrechnunglib->isEmpfehlungsberechtigt($item['anrechnung_id']);
if (is_null($empfehlungData) && $isEmpfehlungsberechtigt)
{
$json[]= array(
'anrechnung_id' => $item['anrechnung_id'],
'empfehlung_anrechnung' => 'true',
'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL),
'empfehlung_am' => (new DateTime())->format('d.m.Y'),
'empfehlung_von' => $person->vorname. ' '. $person->nachname
);
// Approve Anrechnung
if($this->anrechnunglib->recommendAnrechnung($item['anrechnung_id']))
{
$json[]= array(
'anrechnung_id' => $item['anrechnung_id'],
'empfehlung_anrechnung' => 'true',
'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL),
'empfehlung_am' => (new DateTime())->format('d.m.Y'),
'empfehlung_von' => $person->vorname. ' '. $person->nachname
);
}
}
}
@@ -184,18 +190,25 @@ class reviewAnrechnungDetail extends Auth_Controller
foreach ($data as $item)
{
// Approve Anrechnung
if($this->anrechnunglib->dontRecommendAnrechnung($item['anrechnung_id'], $item['begruendung']))
$empfehlungData = $this->anrechnunglib->getEmpfehlungData($item['anrechnung_id']);
$isEmpfehlungsberechtigt = $this->anrechnunglib->isEmpfehlungsberechtigt($item['anrechnung_id']);
if (is_null($empfehlungData) && $isEmpfehlungsberechtigt)
{
$json[]= array(
'anrechnung_id' => $item['anrechnung_id'],
'empfehlung_anrechnung' => 'false',
'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL),
'empfehlung_am' => (new DateTime())->format('d.m.Y'),
'empfehlung_von' => $person->vorname. ' '. $person->nachname
);
// Approve Anrechnung
if($this->anrechnunglib->dontRecommendAnrechnung($item['anrechnung_id'], $item['begruendung']))
{
$json[]= array(
'anrechnung_id' => $item['anrechnung_id'],
'empfehlung_anrechnung' => 'false',
'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL),
'empfehlung_am' => (new DateTime())->format('d.m.Y'),
'empfehlung_von' => $person->vorname. ' '. $person->nachname
);
}
}
}
// Output json to ajax
@@ -256,7 +269,7 @@ class reviewAnrechnungDetail extends Auth_Controller
/**
* Check if user is entitled to read dms doc
* @param $dms_id
* @param $anrechnung_id
*/
private function _checkIfEntitledToReadAnrechnung($anrechnung_id)
{
@@ -19,10 +19,10 @@ class reviewAnrechnungUebersicht extends Auth_Controller
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/anrechnung_empfehlen:rw',
'download' => 'lehre/anrechnung_empfehlen:rw',
'recommend' => 'lehre/anrechnung_empfehlen:rw',
'dontRecommend' => 'lehre/anrechnung_empfehlen:rw'
'index' => self::BERECHTIGUNG_ANRECHNUNG_EMPFEHLEN . ':rw',
'download' => self::BERECHTIGUNG_ANRECHNUNG_EMPFEHLEN . ':rw',
'recommend' => self::BERECHTIGUNG_ANRECHNUNG_EMPFEHLEN . ':rw',
'dontRecommend' => self::BERECHTIGUNG_ANRECHNUNG_EMPFEHLEN . ':rw'
)
);
@@ -96,15 +96,21 @@ class reviewAnrechnungUebersicht extends Auth_Controller
foreach ($data as $item)
{
// Approve Anrechnung
if($this->anrechnunglib->recommendAnrechnung($item['anrechnung_id']))
$empfehlungData = $this->anrechnunglib->getEmpfehlungData($item['anrechnung_id']);
$isEmpfehlungsberechtigt = $this->anrechnunglib->isEmpfehlungsberechtigt($item['anrechnung_id']);
if (is_null($empfehlungData) && $isEmpfehlungsberechtigt)
{
$json[]= array(
'anrechnung_id' => $item['anrechnung_id'],
'empfehlung_anrechnung' => 'true',
'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL)
);
// Approve Anrechnung
if($this->anrechnunglib->recommendAnrechnung($item['anrechnung_id']))
{
$json[]= array(
'anrechnung_id' => $item['anrechnung_id'],
'empfehlung_anrechnung' => 'true',
'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL)
);
}
}
}
@@ -145,15 +151,21 @@ class reviewAnrechnungUebersicht extends Auth_Controller
foreach ($data as $item)
{
// Approve Anrechnung
if($this->anrechnunglib->dontRecommendAnrechnung($item['anrechnung_id'], $item['begruendung']))
$empfehlungData = $this->anrechnunglib->getEmpfehlungData($item['anrechnung_id']);
$isEmpfehlungsberechtigt = $this->anrechnunglib->isEmpfehlungsberechtigt($item['anrechnung_id']);
if (is_null($empfehlungData) && $isEmpfehlungsberechtigt)
{
$json[]= array(
'anrechnung_id' => $item['anrechnung_id'],
'empfehlung_anrechnung' => 'false',
'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL)
);
// Approve Anrechnung
if($this->anrechnunglib->dontRecommendAnrechnung($item['anrechnung_id'], $item['begruendung']))
{
$json[]= array(
'anrechnung_id' => $item['anrechnung_id'],
'empfehlung_anrechnung' => 'false',
'status_kurzbz' => self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL,
'status_bezeichnung' => $this->anrechnunglib->getStatusbezeichnung(self::ANRECHNUNGSTATUS_PROGRESSED_BY_STGL)
);
}
}
}
@@ -0,0 +1,45 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
class LvTemplateUebersicht extends Auth_Controller
{
public function __construct()
{
// Set required permissions
parent::__construct(
array(
'index' => 'lehre/lehrveranstaltung:rw',
)
);
// Load libraries
$this->load->library('AuthLib');
// Load language phrases
$this->loadPhrases(
array(
'global',
'lehre'
)
);
$this->_setAuthUID();
}
public function index()
{
$this->load->view('lehre/lvplanung/lvTemplateUebersicht.php');
}
/**
* 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');
}
}
@@ -29,6 +29,7 @@ class Gruppenmanagement extends Auth_Controller
$this->load->model('person/benutzer_model', 'BenutzerModel');
$this->load->model('ressource/mitarbeiter_model', 'MitarbeiterModel');
$this->load->model('person/benutzergruppe_model', 'BenutzergruppeModel');
$this->load->model('person/gruppe_manager_model', 'GruppemanagerModel');
$this->load->model('system/Log_model', 'LogModel');
$this->load->library('WidgetLib');
@@ -117,6 +118,27 @@ class Gruppenmanagement extends Auth_Controller
$result = error('Uid missing');
else
{
$this->GruppemanagerModel->addSelect('1');
$isManagerRes = $this->GruppemanagerModel->loadWhere(
array(
'uid' => $this->_uid,
'gruppe_kurzbz' => $gruppe_kurzbz
)
);
if (isError($isManagerRes))
{
$this->outputJsonError(getError($isManagerRes));
return;
}
if (!hasData($isManagerRes))
{
$this->outputJsonError($this->p->t('gruppenmanagement', 'nichtZumEditierenDerGruppeBerechtigt'));
return;
}
$this->BenutzergruppeModel->addSelect('1');
$benutzerExistsRes = $this->BenutzergruppeModel->loadWhere(
array(
'uid' => $uid,
@@ -170,6 +192,26 @@ class Gruppenmanagement extends Auth_Controller
$result = error('Uid missing');
else
{
$this->GruppemanagerModel->addSelect('1');
$isManagerRes = $this->GruppemanagerModel->loadWhere(
array(
'uid' => $this->_uid,
'gruppe_kurzbz' => $gruppe_kurzbz
)
);
if (isError($isManagerRes))
{
$this->outputJsonError(getError($isManagerRes));
return;
}
if (!hasData($isManagerRes))
{
$this->outputJsonError($this->p->t('gruppenmanagement', 'nichtZumEditierenDerGruppeBerechtigt'));
return;
}
$result = $this->BenutzergruppeModel->delete(
array(
'uid' => $uid,
@@ -16,7 +16,9 @@ class MigrateContract extends CLI_Controller
{
private $matching_ba1_vertragsart;
private $OE_DEFAULT = 'gst';
private $OE_DEFAULT;
protected $configerrors;
/**
* Constructor
@@ -28,29 +30,70 @@ class MigrateContract extends CLI_Controller
$this->load->model('codex/bisverwendung_model', 'BisVerwendungModel');
$this->load->model('person/benutzerfunktion_model', 'BenutzerfunktionModel');
$this->matching_ba1_vertragsart = array(
'101'=>'externerlehrender',
'102'=>'DV anderen Gebietskörperschaft',
'103'=>'echterdv',
'104'=>'studentischehilfskr',
'105'=>'externerlehrender',
'106'=>'Andere Bildungseinrichtung',
'107'=>'werkvertrag',
'108'=>'studentischehilfskr',
'109'=>'ueberlassungsvertrag',
'110'=>'echterfreier',
'111'=>'echterdv', //All-In
);
$this->load->config('migratecontract');
$this->OE_DEFAULT = $this->config->item('migratecontract_oe_default');
$this->matching_ba1_vertragsart = $this->config->item('migratecontract_matching_ba1_vertragsart');
$this->configerrors = array();
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
public function checkConfig()
{
echo "OE_DEFAULT: " . $this->OE_DEFAULT . "\n";
echo "matching_ba1_vertragsart: " . print_r($this->matching_ba1_vertragsart, true);
$this->checkOE_DEFAULT();
$this->checkMatching_ba1_vertragsart();
if( count($this->configerrors) > 0 )
{
foreach($this->configerrors AS $configerror)
{
echo $configerror . "\n";
}
die("Fehler in der Konfiguration. Abbruch!\n");
}
else
{
echo "Konfiguration OK.\n";
}
}
protected function checkOE_DEFAULT()
{
$db = new DB_Model();
$oesql = 'SELECT * FROM public.tbl_organisationseinheit WHERE oe_kurzbz = ?';
$oeres = $db->execReadOnlyQuery($oesql, array($this->OE_DEFAULT));
if( !hasData($oeres) )
{
$this->configerrors[] = 'Default Organisationseinheit: "'
. $this->OE_DEFAULT . '" nicht gefunden.';
}
}
protected function checkMatching_ba1_vertragsart() {
$db = new DB_Model();
foreach( $this->matching_ba1_vertragsart AS $vertragsart_kurzbz )
{
$vasql = 'SELECT * FROM hr.tbl_vertragsart WHERE vertragsart_kurzbz = ?';
$vares = $db->execReadOnlyQuery($vasql, array($vertragsart_kurzbz));
if( !hasData($vares) )
{
$this->configerrors[] = 'Vertragsart "' . $vertragsart_kurzbz
. '" nicht gefunden.';
}
}
}
/**
* Everything has a beginning
*/
public function index($user = null)
{
$this->checkConfig();
if (!is_null($user))
{
$contracts = $this->_transformUser($user);
@@ -400,6 +443,11 @@ class MigrateContract extends CLI_Controller
*/
private function _addVertragsbestandteilZeitaufzeichnung(&$contracts, $dv, $row_verwendung)
{
if( is_null($row_verwendung->zeitaufzeichnungspflichtig) || is_null($row_verwendung->azgrelevant) )
{
return;
}
if (isset($contracts['dv'][$dv]['vbs']))
{
foreach ($contracts['dv'][$dv]['vbs'] as $index_vbs=>$row_vbs)
@@ -4,14 +4,15 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
class MigrateHourlyRate extends CLI_Controller
{
CONST DEFAULT_OE = 'gst';
CONST DEFAULT_DATE = '1970-01-01';
CONST STUNDENSTAZTYP_LEHRE = 'lehre';
CONST STUNDENSTAZTYP_KALKULATORISCH = 'kalkulatorisch';
private $OE_DEFAULT;
private $_ci;
protected $configerrors;
public function __construct()
{
parent::__construct();
@@ -21,10 +22,38 @@ class MigrateHourlyRate extends CLI_Controller
$this->load->model('codex/Bisverwendung_model', 'BisVerwendungModel');
$this->load->model('person/Benutzerfunktion_model', 'BenutzerfunktionModel');
$this->load->model('ressource/Stundensatz_model', 'StundensatzModel');
$this->load->config('migratecontract');
$this->OE_DEFAULT = $this->config->item('migratecontract_oe_default');
$this->configerrors = array();
}
public function checkConfig()
{
echo "OE_DEFAULT: " . $this->OE_DEFAULT . "\n";
$this->checkOE_DEFAULT();
if( count($this->configerrors) > 0 )
{
foreach($this->configerrors AS $configerror)
{
echo $configerror . "\n";
}
die("Fehler in der Konfiguration. Abbruch!\n");
}
else
{
echo "Konfiguration OK.\n";
}
}
public function index($user = null)
{
$this->checkConfig();
echo "Lehre Stundensaetze werden migriert.\n";
$mitarbeiterResult = $this->_getMitarbeiterStunden($user);
if (isError($mitarbeiterResult)) return $mitarbeiterResult;
if (!hasData($mitarbeiterResult)) return error('Keine Mitarbeiterstunden gefunden');
@@ -38,20 +67,71 @@ class MigrateHourlyRate extends CLI_Controller
if (isError($insertResult)) return $insertResult;
}
$sapResult = $this->_getSapStunden($user);
if (isError($sapResult)) return $sapResult;
if (!hasData($sapResult)) return error('Keinen kalkulatorischen Stundensaetze gefunden');
$mitarbeiterArray = getData($sapResult);
foreach ($mitarbeiterArray as $mitarbeiter)
if( $this->checkIfSAPSyncTableExists() )
{
$this->_getUnternehmen($mitarbeiter);
$insertResult = $this->_addStundensatz($mitarbeiter, self::STUNDENSTAZTYP_KALKULATORISCH, date_format(date_create($mitarbeiter->beginn), 'Y-m-d'));
if (isError($insertResult)) return $insertResult;
echo "SAP Sync Tabelle gefunden. SAP Stundensaetze werden migriert.\n";
$sapResult = $this->_getSapStunden($user);
if (isError($sapResult)) return $sapResult;
if (!hasData($sapResult)) return error('Keinen kalkulatorischen Stundensaetze gefunden');
$mitarbeiterArray = getData($sapResult);
foreach ($mitarbeiterArray as $mitarbeiter)
{
$this->_getUnternehmen($mitarbeiter);
$insertResult = $this->_addStundensatz($mitarbeiter, self::STUNDENSTAZTYP_KALKULATORISCH, date_format(date_create($mitarbeiter->beginn), 'Y-m-d'));
if (isError($insertResult)) return $insertResult;
}
}
else
{
echo "SAP Sync Tabelle nicht gefunden. Ignoriere SAP Stundensaetze.\n";
}
}
protected function checkOE_DEFAULT()
{
$db = new DB_Model();
$oesql = 'SELECT * FROM public.tbl_organisationseinheit WHERE oe_kurzbz = ?';
$oeres = $db->execReadOnlyQuery($oesql, array($this->OE_DEFAULT));
if( !hasData($oeres) )
{
$this->configerrors[] = 'Default Organisationseinheit: "'
. $this->OE_DEFAULT . '" nicht gefunden.';
}
}
protected function checkIfSAPSyncTableExists()
{
$dbModel = new DB_Model();
$params = array(
DB_NAME,
'sync',
'tbl_sap_stundensatz'
);
$sql = "SELECT
1 AS exists
FROM
information_schema.tables
WHERE
table_catalog = ? AND
table_schema = ? AND
table_name = ?";
$res = $dbModel->execReadOnlyQuery($sql, $params);
if( hasData($res) )
{
return true;
}
else
{
return false;
}
}
private function _getSapStunden($user = null)
{
$dbModel = new DB_Model();
@@ -127,7 +207,7 @@ class MigrateHourlyRate extends CLI_Controller
$unternehmenResult = $this->_findUnternehmen($mitarbeiter->uid, "'kstzuordnung', 'oezuordnung'");
}
$unternehmen = self::DEFAULT_OE;
$unternehmen = $this->OE_DEFAULT;
if (hasData($unternehmenResult))
$unternehmen = getData($unternehmenResult)[0]->oe_kurzbz;
@@ -22,6 +22,7 @@ if (! defined('BASEPATH')) exit('No direct script access allowed');
* This controller operates between (interface) the JS (GUI) and the NavigationLib (back-end)
* Provides data to the ajax get calls about the filter
* This controller works with JSON calls on the HTTP GET or POST and the output is always JSON
* TODO(chris): deprecated
*/
class Navigation extends FHC_Controller
{
@@ -1,44 +0,0 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
/**
* Test Search Vue Component
*/
class TestSearch extends Auth_Controller
{
/**
* Constructor
*/
public function __construct()
{
parent::__construct(
array(
'index' => 'system/developer:r'
)
);
// Loads WidgetLib
$this->load->library('WidgetLib');
// Loads phrases system
$this->loadPhrases(
array(
'global',
'ui',
'filter'
)
);
}
// -----------------------------------------------------------------------------------------------------------------
// Public methods
/**
* Everything has a beginning
*/
public function index()
{
$this->load->view('system/logs/testSearch.php');
}
}
@@ -337,10 +337,13 @@ class InfoCenter extends Auth_Controller
$persondata = $this->_loadPersonData($person_id);
$checkPerson = $this->PersonModel->checkDuplicate($person_id);
if (isError($checkPerson)) show_error(getError($checkPerson));
$duplicate = array('duplicated' => getData($checkPerson));
$checkUnruly = $this->PersonModel->checkUnruly($persondata['stammdaten']->vorname, $persondata['stammdaten']->nachname, $persondata['stammdaten']->gebdatum);
if (isError($checkUnruly)) show_error(getError($checkUnruly));
$duplicate = array('duplicate' => getData($checkPerson));
$unruly = array('unruly' => getData($checkUnruly));
$prestudentdata = $this->_loadPrestudentData($person_id);
@@ -351,7 +354,8 @@ class InfoCenter extends Auth_Controller
$persondata,
$prestudentdata,
$dokumentdata,
$duplicate
$duplicate,
$unruly
);
$data[self::FHC_CONTROLLER_ID] = $this->getControllerId();
@@ -1285,67 +1289,28 @@ class InfoCenter extends Auth_Controller
$this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern'));
$kontakte = $this->input->post('kontakt');
foreach ($kontakte as $kontakt)
{
$kontaktExists = $this->KontaktModel->loadWhere(array(
'kontakt_id' => $kontakt['id'],
'person_id' => $person_id,
));
if($kontakte) {
if (hasData($kontaktExists))
{
$kontaktExists = getData($kontaktExists)[0];
foreach ($kontakte as $kontakt) {
$kontaktExists = $this->KontaktModel->loadWhere(array(
'kontakt_id' => $kontakt['id'],
'person_id' => $person_id,
));
if ($kontaktExists->kontakt === $kontakt['value'])
continue;
if (hasData($kontaktExists)) {
$kontaktExists = getData($kontaktExists)[0];
$update = $this->KontaktModel->update(
array
(
'kontakt_id' => $kontakt['id']
),
array
(
'kontakt' => isEmptyString($kontakt['value']) ? null : $kontakt['value'],
'updateamum' => date('Y-m-d H:i:s'),
'updatevon' => $this->_uid
)
);
if ($kontaktExists->kontakt === $kontakt['value'])
continue;
if (isError($update))
$this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern'));
}
}
$adressen = $this->input->post('adresse');
foreach ($adressen as $adresse)
{
$adresseExists = $this->AdresseModel->loadWhere(array(
'adresse_id' => $adresse['id'],
'person_id' => $person_id,
));
if (hasData($adresseExists))
{
$adresse = $adresse['value'];
$adresseExists = getData($adresseExists)[0];
if ($adresseExists->strasse !== $adresse['strasse'] ||
$adresseExists->plz !== $adresse['plz'] ||
$adresseExists->ort !== $adresse['ort'] ||
$adresseExists->nation !== $adresse['nation'])
{
$update = $this->AdresseModel->update(
$update = $this->KontaktModel->update(
array
(
'adresse_id' => $adresseExists->adresse_id
'kontakt_id' => $kontakt['id']
),
array
(
'strasse' => isEmptyString($adresse['strasse']) ? null : $adresse['strasse'],
'plz' => isEmptyString($adresse['plz']) ? null : $adresse['plz'],
'ort' => isEmptyString($adresse['ort']) ? null : $adresse['ort'],
'nation' => isEmptyString($adresse['nation']) ? null : $adresse['nation'],
'kontakt' => isEmptyString($kontakt['value']) ? null : $kontakt['value'],
'updateamum' => date('Y-m-d H:i:s'),
'updatevon' => $this->_uid
)
@@ -1354,7 +1319,48 @@ class InfoCenter extends Auth_Controller
if (isError($update))
$this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern'));
}
}
}
$adressen = $this->input->post('adresse');
if($adressen) {
foreach ($adressen as $adresse) {
$adresseExists = $this->AdresseModel->loadWhere(array(
'adresse_id' => $adresse['id'],
'person_id' => $person_id,
));
if (hasData($adresseExists)) {
$adresse = $adresse['value'];
$adresseExists = getData($adresseExists)[0];
if ($adresseExists->strasse !== $adresse['strasse'] ||
$adresseExists->plz !== $adresse['plz'] ||
$adresseExists->ort !== $adresse['ort'] ||
$adresseExists->nation !== $adresse['nation']) {
$update = $this->AdresseModel->update(
array
(
'adresse_id' => $adresseExists->adresse_id
),
array
(
'strasse' => isEmptyString($adresse['strasse']) ? null : $adresse['strasse'],
'plz' => isEmptyString($adresse['plz']) ? null : $adresse['plz'],
'ort' => isEmptyString($adresse['ort']) ? null : $adresse['ort'],
'nation' => isEmptyString($adresse['nation']) ? null : $adresse['nation'],
'updateamum' => date('Y-m-d H:i:s'),
'updatevon' => $this->_uid
)
);
if (isError($update))
$this->terminateWithJsonError($this->p->t('ui', 'fehlerBeimSpeichern'));
}
}
}
}
@@ -2383,4 +2389,4 @@ class InfoCenter extends Auth_Controller
$this->outputJsonSuccess("Success");
}
}
}
+163 -18
View File
@@ -7,6 +7,10 @@ if (!defined('BASEPATH')) exit('No direct script access allowed');
*/
abstract class Auth_Controller extends FHC_Controller
{
// Special Permissions
const PERM_ANONYMOUS = 'anonymous'; // Everyone
const PERM_LOGGED = 'logged_in'; // Every registered user
/**
* Extends this controller if authentication is required
*/
@@ -14,17 +18,41 @@ abstract class Auth_Controller extends FHC_Controller
{
parent::__construct();
// Loads authentication library and starts authentication
$this->load->library('AuthLib');
if (!is_array($requiredPermissions) || isEmptyArray($requiredPermissions))
show_error('The given permissions is not a valid array or it is an empty one');
if (!isset($requiredPermissions[$this->router->method]))
show_error('The given permission array does not contain the given method or is not correctly set');
$anonAllowed = false;
if ($requiredPermissions[$this->router->method] == self::PERM_ANONYMOUS)
$anonAllowed = true;
elseif (is_array($requiredPermissions[$this->router->method])
&& in_array(self::PERM_ANONYMOUS, $requiredPermissions[$this->router->method]))
$anonAllowed = true;
// Checks if the caller is allowed to access to this content
$this->_isAllowed($requiredPermissions);
if ($anonAllowed) {
// Loads authentication library without authentication
$this->load->library('AuthLib', [false]);
// Loads helper since it would only be called on authentication
$this->load->helper('hlp_authentication');
} else {
// Loads authentication library and starts authentication
$this->load->library('AuthLib');
// Checks if the caller is allowed to access to this content
$this->_isAllowed($requiredPermissions);
}
}
/**
* Checks if the caller is allowed to access to this content with the given permissions
* If it is not allowed will set the HTTP header with code 401
* Wrapper for permissionlib->isEntitled
*
* @param array $requiredPermissions
* @return void
*/
private function _isAllowed($requiredPermissions)
{
@@ -34,28 +62,145 @@ abstract class Auth_Controller extends FHC_Controller
// Checks if this user is entitled to access to this content
if (!$this->permissionlib->isEntitled($requiredPermissions, $this->router->method))
{
$this->output->set_status_header(REST_Controller::HTTP_UNAUTHORIZED); // set the HTTP header as unauthorized
$this->load->library('EPrintfLib'); // loads the EPrintfLib to format the output
// Prints the main error message
$this->eprintflib->printError('You are not allowed to access to this content');
// Prints the called controller name
$this->eprintflib->printInfo('Controller name: '.$this->router->class);
// Prints the called controller method name
$this->eprintflib->printInfo('Method name: '.$this->router->method);
// Prints the required permissions needed to access to this method
$this->eprintflib->printInfo('Required permissions: '.$this->_rpsToString($requiredPermissions, $this->router->method));
$this->_outputAuthError($requiredPermissions);
exit; // immediately terminate the execution
}
}
/**
* Checks for Permissions depending if the given person is a
* Mitarbeiter and/or Student
* 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
*
* @return void
*/
protected function checkPermissionsForPerson($person_id, $permMa, $permStud)
{
$res = $this->hasPermissionsForPerson($person_id, $permMa, $permStud);
if ($res) {
$perm = array_keys(array_flip(array_merge($res|1 ? $permMa : [], $res|2 ? $permStud : [])));
$this->_outputAuthError([$this->router->method => $perm]);
}
}
/**
* Checks for Permissions depending on the Studiengang of a Prestudent
* and exits/outputs an error if they are not met.
*
* @param integer $prestudent_id
* @param array $permStud Perms if the person is a Student
*
* @return void
*/
protected function checkPermissionsForPrestudent($prestudent_id, $permStud)
{
if (!$this->hasPermissionsForPrestudent($prestudent_id, $permStud)) {
$this->_outputAuthError([$this->router->method => $permStud]);
}
}
/**
* Checks for Permissions depending if the given person is a
* Mitarbeiter and/or Student
* and returns the result.
*
* @param integer $person_id
* @param array $permMa Perms if the person is a Mitarbeiter
* @param array $permStud Perms if the person is a Student
*
* @return integer 0 if permission is granted
*/
protected function hasPermissionsForPerson($person_id, $permMa, $permStud)
{
$res = 3;
$this->load->model('person/Person_model', 'PersonModel');
$this->PersonModel->addJoin('public.tbl_benutzer', 'person_id');
$this->PersonModel->addJoin('public.tbl_mitarbeiter', 'uid = mitarbeiter_uid');
$result = $this->PersonModel->load($person_id);
if (hasData($result)) {
if ($this->permissionlib->isEntitled(['a' => $permMa], 'a'))
return 0;
$res = 1;
}
$this->PersonModel->addJoin('public.tbl_prestudent', 'person_id');
$result = $this->PersonModel->load($person_id);
if (hasData($result)) {
$permStudConverted = [];
foreach (getData($result) as $row) {
foreach ($permStud as $k => $v) {
if (!isset($permStudConverted[$k])) {
$permStudConverted[$k] = $this->permissionlib->convertAccessType($v);
}
if ($this->permissionlib->isBerechtigt($permStudConverted[$k][0], $permStudConverted[$k][1], $row->studiengang_kz))
return 0;
}
}
$res += 2;
}
return $res;
}
/**
* Checks for Permissions depending on the Studiengang of a Prestudent
* and returns the result.
*
* @param integer $prestudent_id
* @param array $permStud Perms if the person is a Student
*
* @return boolean
*/
protected function hasPermissionsForPrestudent($prestudent_id, $permStud)
{
$this->load->model('crm/Prestudent_model', 'PrestudentModel');
$result = $this->PrestudentModel->load($prestudent_id);
if (!hasData($result))
show_404();
$stg = current(getData($result))->studiengang_kz;
foreach ($permStud as $k => $v) {
$perm = $this->permissionlib->convertAccessType($v);
if ($this->permissionlib->isBerechtigt($perm[0], $perm[1], $stg))
return true;
}
return false;
}
/**
* Outputs an error message and sets the HTTP Header.
* This function is protected so that it can be overwritten.
*
* @param array $requiredPermissions
* @return void
*/
protected function _outputAuthError($requiredPermissions)
{
$this->output->set_status_header(REST_Controller::HTTP_UNAUTHORIZED); // set the HTTP header as unauthorized
$this->load->library('EPrintfLib'); // loads the EPrintfLib to format the output
// Prints the main error message
$this->eprintflib->printError('You are not allowed to access to this content');
// Prints the called controller name
$this->eprintflib->printInfo('Controller name: '.$this->router->class);
// Prints the called controller method name
$this->eprintflib->printInfo('Method name: '.$this->router->method);
// Prints the required permissions needed to access to this method
$this->eprintflib->printInfo('Required permissions: '.$this->_rpsToString($requiredPermissions, $this->router->method));
}
/**
* Converts an array of permissions to a string that contains them as a comma separated list
* Ex: "<permission 1>, <permission 2>, <permission 3>"
*
* @param array $requiredPermissions
* @param string $method
* @return void
*/
private function _rpsToString($requiredPermissions, $method)
final protected function _rpsToString($requiredPermissions, $method)
{
$strRequiredPermissions = ''; // string that contains all the required permissions needed to access to this method
+14
View File
@@ -46,6 +46,20 @@ class CI3_Events
* NOTE(chris): Autoload Events config
*/
require_once(APPPATH.'config/Events.php');
$active_addons_array = explode(";", ACTIVE_ADDONS);
foreach (scandir(APPPATH.'config/extensions') as $dir)
if ($dir[0] != '.' && file_exists(APPPATH.'config/extensions/'.$dir.'/Events.php'))
require_once APPPATH.'config/extensions/'.$dir.'/Events.php';
foreach (scandir(FHCPATH.'addons') as $dir)
if ($dir[0] != '.' && file_exists(FHCPATH.'addons/'.$dir.'/Events.php'))
{
// only includes the Events of the addon if the addon is one of the active addons in the cis config
if(in_array($dir,$active_addons_array))
{
require_once FHCPATH . 'addons/' . $dir . '/Events.php';
}
}
+89 -17
View File
@@ -60,6 +60,9 @@ class DB_Model extends CI_Model
protected $pk; // Name of the PrimaryKey for DB-Update, Load, ...
protected $hasSequence; // False if this table has a composite primary key that is not using a sequence
// True if this table has a primary key that uses a sequence
//protected $paginationOptions; // $page and $page_size together in an associative array
protected $page;
protected $page_size;
private $executedQueryMetaData;
private $executedQueryListFields;
@@ -531,7 +534,7 @@ class DB_Model extends CI_Model
if (!is_numeric($start) || (is_numeric($start) && $start <= 0))
return error('The start parameter is not valid', EXIT_MODEL);
if (is_numeric($end) && $end > $start)
if (is_numeric($end))
{
$this->db->limit($start, $end);
}
@@ -827,6 +830,23 @@ class DB_Model extends CI_Model
return $result;
}
public function getDbTable()
{
return $this->dbTable;
}
public function getPk()
{
return $this->pk;
}
public function getPks()
{
if (is_array($this->pk))
return $this->pk;
return [$this->pk];
}
// ------------------------------------------------------------------------------------------
// Protected methods
@@ -971,14 +991,17 @@ class DB_Model extends CI_Model
// Find and replace all the occurrences of the provided encrypted columns
// with the postgresql decryption function
$query = str_replace(
$encryptedColumn,
sprintf(
self::CRYPT_WHERE_TEMPLATE,
$encryptedColumn,
$decryptionPassword,
$definition[self::CRYPT_CAST]
),
$query = preg_replace_callback(
'/(?<! (as|AS) )\b(\w+\.)?(' . $encryptedColumn . ')\b/',
function($matches) use (&$decryptionPassword, &$definition) {
$aliased_column = $matches[2] . $matches[3];
return sprintf(
self::CRYPT_WHERE_TEMPLATE,
$aliased_column,
$decryptionPassword,
$definition[self::CRYPT_CAST]
);
},
$query
);
}
@@ -1086,14 +1109,17 @@ class DB_Model extends CI_Model
{
// Find and replace all the occurrences of the provided encrypted columns
// with the postgresql decryption function
$where = str_replace(
$encryptedColumn,
sprintf(
self::CRYPT_WHERE_TEMPLATE,
$encryptedColumn,
$decryptionPassword,
$definition[self::CRYPT_CAST]
),
$where = preg_replace_callback(
'/(?<! (as|AS) )\b(\w+\.)?(' . $encryptedColumn . ')\b/',
function($matches) use (&$decryptionPassword, &$definition) {
$aliased_column = $matches[2] . $matches[3];
return sprintf(
self::CRYPT_WHERE_TEMPLATE,
$aliased_column,
$decryptionPassword,
$definition[self::CRYPT_CAST]
);
},
$where
);
}
@@ -1342,5 +1368,51 @@ class DB_Model extends CI_Model
return $udfs;
}
/**
* addPagination
* adds a limit and an optional offset depending on the arguments passed to the function
* @param int $page page to be queried
* @param int $page_size page_size used to calculate the offset of the pagination
* @param int | null $num_rows used to calculate the total amout of pages that are available with the $page and $page_size arguments
*
* @return void
*/
function addPagination( $page, $page_size, $num_rows=null)
{
if (isset($page) && is_numeric($page) && isset($page_size) && is_numeric($page_size) && $page > 0 && $page_size > 0) {
if (isset($num_rows) && is_numeric($num_rows) && $num_rows > 0) {
$floatMaxPageCount = $num_rows / $page_size;
$maxPageCount = ceil($floatMaxPageCount);
if($page > $maxPageCount){
$page = $maxPageCount;
}
}
$offset = (($page-1) * $page_size);
$this->addLimit($page_size, $offset);
} else {
$this->addLimit($page_size);
}
}
/**
* getQueryNumRows
* returns the number of rows of the current build query of the codeigniter query builder instance
* @param bool $reset resets the select of the query
*
* @return Result_object $num_rows
*/
function getNumRows($reset=false)
{
// returns the number of rows when executing the current query without reseting the select statement of the query
$num_rows = $this->db->count_all_results($this->dbTable,$reset);
if($num_rows){
return success($num_rows);
}else{
return error($this->db->error(), EXIT_DATABASE);
}
}
}
+66 -72
View File
@@ -5,7 +5,7 @@ if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Controller using JSON
*/
class FHCAPI_Controller extends FHC_Controller
class FHCAPI_Controller extends Auth_Controller
{
/**
@@ -19,12 +19,13 @@ class FHCAPI_Controller extends FHC_Controller
/**
* Error types
*/
const ERROR_TYPE_PHP = 'php'; // TODO(chris): php types from severity?
const ERROR_TYPE_PHP = 'php';
const ERROR_TYPE_EXCEPTION = 'exception';
const ERROR_TYPE_GENERAL = 'general';
const ERROR_TYPE_404 = '404';
const ERROR_TYPE_DB = 'db';
const ERROR_TYPE_VALIDATION = 'validation';
const ERROR_TYPE_AUTH = 'auth';
/**
* Return Object
@@ -45,10 +46,6 @@ class FHCAPI_Controller extends FHC_Controller
if (is_cli())
show_404();
parent::__construct();
$this->config->set_item('error_views_path', VIEWPATH.'errors'.DIRECTORY_SEPARATOR.'json'.DIRECTORY_SEPARATOR);
global $g_result;
$g_result = $this;
@@ -74,18 +71,14 @@ class FHCAPI_Controller extends FHC_Controller
}
}
#$this->returnObj['test'] = implode('/n', headers_list());
return json_encode($this->returnObj);
});
// Load libraries
$this->load->library('AuthLib');
$this->load->library('PermissionLib');
// Checks if the caller is allowed to access to this content
$this->_isAllowed($requiredPermissions);
// NOTE(chris): overwrite error_views_path before constructor
load_class('Config')->set_item('error_views_path', VIEWPATH.'errors'.DIRECTORY_SEPARATOR.'json'.DIRECTORY_SEPARATOR);
parent::__construct($requiredPermissions);
// For JSON Requests (as opposed to multipart/form-data) get the $_POST variable from the input stream instead
if ($this->input->get_request_header('Content-Type', true) == 'application/json')
$_POST = json_decode($this->security->xss_clean($this->input->raw_input_stream), true);
@@ -101,7 +94,7 @@ class FHCAPI_Controller extends FHC_Controller
// ---------------------------------------------------------------
/**
* @param array $data
* @param string|array|object $data
* @param string $type (optional)
* @return void
*/
@@ -117,6 +110,8 @@ class FHCAPI_Controller extends FHC_Controller
$error['messages'] = $data;
else
$error = $data;
} elseif (is_object($data)) {
$error = (array)$data;
} else {
$error['message'] = $data;
}
@@ -124,6 +119,9 @@ class FHCAPI_Controller extends FHC_Controller
if ($type)
$error['type'] = $type;
if (!isset($error['type']))
$error['type'] = self::ERROR_TYPE_GENERAL;
$this->returnObj['errors'][] = $error;
}
@@ -136,15 +134,38 @@ class FHCAPI_Controller extends FHC_Controller
$this->returnObj['data'] = $data;
}
/**
* @param string $key
* @param mixed $value
* @return void
*/
public function addMeta($key, $value)
{
if (!isset($this->returnObj['meta']))
$this->returnObj['meta'] = [];
$this->returnObj['meta'][$key] = $value;
}
/**
* @param string $key
* @return mixed
*/
public function getMeta($key)
{
if (!isset($this->returnObj['meta']))
return null;
if (!isset($this->returnObj['meta'][$key]))
return null;
return $this->returnObj['meta'][$key];
}
/**
* @param string $status
* @return void
*/
public function setStatus($status)
{
if (!isset($this->returnObj['meta']))
$this->returnObj['meta'] = [];
$this->returnObj['meta']['status'] = $status;
$this->addMeta('status', $status);
}
@@ -152,6 +173,17 @@ class FHCAPI_Controller extends FHC_Controller
// Handle Output object - Shortcut functions
// ---------------------------------------------------------------
/**
* @param mixed $data (optional)
* @return void
*/
protected function terminateWithSuccess($data = null)
{
$this->setData($data);
$this->setStatus(self::STATUS_SUCCESS);
exit;
}
/**
* @param array $errors
* @return void
@@ -165,24 +197,14 @@ class FHCAPI_Controller extends FHC_Controller
}
/**
* @param mixed $data (optional)
* @return void
*/
protected function terminateWithSuccess($data = null)
{
$this->setData($data);
$this->setStatus(self::STATUS_SUCCESS);
exit;
}
/**
* @param array $error
* @param string|array|object $error
* @param string $type (optional)
* @param integer $status (optional)
* @return void
*/
protected function terminateWithError($error, $type = null)
protected function terminateWithError($error, $type = null, $status = REST_Controller::HTTP_INTERNAL_SERVER_ERROR)
{
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
$this->output->set_status_header($status);
$this->addError($error, $type);
$this->setStatus(self::STATUS_ERROR);
exit;
@@ -191,65 +213,37 @@ class FHCAPI_Controller extends FHC_Controller
/**
* @param stdclass $result
* @param string $errortype
* @return void
* @return mixed
*/
protected function checkForErrors($result, $errortype = self::ERROR_TYPE_GENERAL)
protected function getDataOrTerminateWithError($result, $errortype = self::ERROR_TYPE_GENERAL)
{
// TODO(chris): IMPLEMENT!
if (isError($result)) {
$this->terminateWithError(getError($result), $errortype);
}
return $result->retval;
}
// TODO(chris): complete list
// ---------------------------------------------------------------
// Security
// ---------------------------------------------------------------
/**
* Checks if the caller is allowed to access to this content with the given permissions
* If it is not allowed will set the HTTP header with code 401
* Wrapper for permissionlib->isEntitled
* Outputs an error message and sets the HTTP Header.
* This overwrites the default behaviour to output a json object.
*
* @param array $requiredPermissions
* @return void
*/
protected function _isAllowed($requiredPermissions)
protected function _outputAuthError($requiredPermissions)
{
// Checks if this user is entitled to access to this content
if (!$this->permissionlib->isEntitled($requiredPermissions, $this->router->method))
{
$this->output->set_status_header(isLogged() ? REST_Controller::HTTP_FORBIDDEN : REST_Controller::HTTP_UNAUTHORIZED);
$this->output->set_status_header(isLogged() ? REST_Controller::HTTP_FORBIDDEN : REST_Controller::HTTP_UNAUTHORIZED);
$this->addError([
'message' => 'You are not allowed to access to this content',
'controller' => $this->router->class,
'method' => $this->router->method,
'required_permissions' => $this->_rpsToString($requiredPermissions, $this->router->method)
]);
exit; // immediately terminate the execution
}
}
/**
* Converts an array of permissions to a string that contains them as a comma separated list
* Ex: "<permission 1>, <permission 2>, <permission 3>"
*
* @param array $requiredPermissions
* @param string $method
* @return void
*/
protected function _rpsToString($requiredPermissions, $method)
{
if (!isset($requiredPermissions[$method]))
return '';
if (!is_array($requiredPermissions[$method]))
return $requiredPermissions[$method];
return implode(', ', $requiredPermissions[$method]);
$this->addError([
'message' => 'You are not allowed to access to this content',
'controller' => $this->router->class,
'method' => $this->router->method,
'required_permissions' => $this->_rpsToString($requiredPermissions, $this->router->method)
], self::ERROR_TYPE_AUTH);
}
}

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