Compare commits

..

170 Commits

Author SHA1 Message Date
Harald Bamberger 3b1a752068 experimental: adapt for using rollupjs bundler 2024-04-08 16:30:18 +02:00
Harald Bamberger c04d51c1c0 use rollup.alt.config.js as new default rollup.config.js 2024-04-08 09:19:25 +02:00
Harald Bamberger 2c1e2ca010 mv rollup.config.js to rollup.chunks.config.js since rollup.alt.config.js seems to be the preferred way and will become rollup.config.js in next commit 2024-04-08 09:18:37 +02:00
Harald Bamberger 9268395215 bundle css, import tabulator in filter component, import vue in Phrases Plugin 2024-04-08 09:13:42 +02:00
Harald Bamberger d2f19350b4 add rollup README with useful commands, add alternative rollup config to build one bundle per app without shared chunks, add package-lock.json to repo 2024-04-05 16:26:41 +02:00
Harald Bamberger 42d3d86185 add json module to rollup config, add axios and tabulator to package json 2024-04-05 15:23:10 +02:00
Harald Bamberger da56ae63ae add rollup watch script to package.json 2024-04-04 11:30:54 +02:00
Harald Bamberger a2cae87f53 change path for chunks 2024-04-03 17:42:34 +02:00
Harald Bamberger 0bc5fd1900 fix import paths 2024-04-03 17:37:25 +02:00
Harald Bamberger 9367438539 first guess using rollup to bundle vuejs applications 2024-04-03 17:14:05 +02:00
kindlm 5d49516b77 Merge branch 'ReportingFilterParameter' 2024-03-28 13:56:07 +01:00
kindlm 538264e577 Merge branch 'master' into ReportingFilterParameter 2024-03-28 13:55:29 +01:00
kindlm 2f99457283 GET-Parameter auch für Text übernehmen 2024-03-28 13:54:45 +01:00
Andreas Österreicher 4ccf2aebcc Prüfungstyp Termin3 wird nicht automatisch angelegt 2024-03-27 12:57:17 +01:00
Manfred 21b05394c8 Merge branch 'master' into ReportingFilterParameter 2024-03-26 17:24:07 +01:00
kindlm 7240a97d6e Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-03-26 17:16:57 +01:00
kindlm e469f54901 Typ "Text" bei vordefinierten Filtern ergänzt 2024-03-26 17:16:44 +01:00
Andreas Österreicher 42ddea9f51 Fixed Typ in Variable Name 2024-03-26 16:37:13 +01:00
Andreas Österreicher 058ed94c2b Merge branch 'feature-36196/DVUH_Meldestatus_beruecksichtigen' 2024-03-26 11:34:26 +01:00
Harald Bamberger a95c2fe47e studstatus switch fullname to have surname first 2024-03-26 11:27:44 +01:00
Andreas Österreicher 1e9a681c9a Gegencheck für tbl_tmp_store und tbl_audit_log entfernt da dies Tabellen
aus der Personalveraltung Extension sind
Gegencheck für Habiliation hinzugefügt
2024-03-26 09:19:36 +01:00
Harald Bamberger aabc10d1fc Merge branch 'master' of github.com:FH-Complete/FHC-Core 2024-03-25 16:54:00 +01:00
Harald Bamberger d4bc5148a7 fix disappearing searchbar when session expires, add functions to fetch dvs at a certain duedate for valorisation 2024-03-25 16:53:03 +01:00
Andreas Österreicher fe1ea63496 Merge branch 'feature-33294/StudienerfolgsbestaetigungAbbrecher' 2024-03-25 15:59:12 +01:00
Harald Bamberger 2a26765ff6 Merge branch 'feature-25562/PV21_Datenbankstruktur_fuer_Vertraege_und_Gehaelter' 2024-03-25 15:05:46 +01:00
Harald Bamberger 5413292529 Merge branch 'master' into feature-25562/PV21_Datenbankstruktur_fuer_Vertraege_und_Gehaelter 2024-03-25 14:55:46 +01:00
Harald Bamberger 8a86bce567 Merge branch 'feature-33003/BIS_Meldung_Personal' into feature-25562/PV21_Datenbankstruktur_fuer_Vertraege_und_Gehaelter 2024-03-25 14:55:11 +01:00
Harald Bamberger ad415ad665 deactivateDienstverhaeltnis: only set user to inactive if no other dv is active 2024-03-25 14:04:21 +01:00
Andreas Österreicher 6a6db4292f Merge branch 'feature-18571/EntwicklungsteamBisMeldung' 2024-03-25 13:54:42 +01:00
Andreas Österreicher 5fd4ded184 Merge branch 'master' into feature-18571/EntwicklungsteamBisMeldung 2024-03-25 13:12:35 +01:00
Harald Bamberger 9f2dd82009 Merge branch 'master' into feature-25562/PV21_Datenbankstruktur_fuer_Vertraege_und_Gehaelter 2024-03-25 13:08:10 +01:00
Manfred e1b5a86390 Merge branch 'master' of https://github.com/FH-Complete/FHC-Core 2024-03-19 15:55:00 +01:00
Manfred be0d73cd22 Sortierung der Studiensemester absteigend; Ziel-Studiensemester passt sich automatisch an 2024-03-19 15:54:54 +01:00
Andreas Österreicher 2cce61ca6a Korrekturen für Gehaltsimport 2024-03-15 13:37:07 +01:00
kindlm 1d81a4c2e8 Buttonbeschriftung geändert um barrierefreier zu sein 2024-03-14 17:08:03 +01:00
kindlm 79a1e6a7fd Merge branch 'benutzerberechtigungGUIneu' 2024-03-14 16:41:53 +01:00
kindlm 7bec921018 Merge branch 'master' into benutzerberechtigungGUIneu 2024-03-14 16:40:07 +01:00
kindlm d9caf746a1 Rechte-GUI verbesserungen
- Inaktive und WaWi-Einträge ausgblenden
- Kopie-Anmerkung verkürzt
- Inaktive OE Kennzeichnen
- Link ins CIS-Profil
- Shortcut zum einfügen von Datum und Kürzel
- "Mitarbeiter" ist default bei Benutzersuche
- GUI-Verbesserungen bei Rollenvergleich
2024-03-14 16:39:01 +01:00
Harald Bamberger bacfbd33f3 Merge branch 'feature-36016/Studstatus_QMB' 2024-03-14 12:37:21 +01:00
Harald Bamberger 77221e507f set tabulator to fixed height, fix missing grund when editing unterbrechung 2024-03-14 11:42:39 +01:00
cgfhtw bc5d42b310 Studstatus: ausbildungssemester in getAllPrestudentsWhereCommitteeExamFailed 2024-03-14 08:52:55 +01:00
cgfhtw cba4c8e365 Studstatus: Fallback for antrag details 2024-03-13 16:46:10 +01:00
Harald Bamberger af79736d67 documents use ausbildungssemester from prestudentstatus in semester of antrag, fix missing grund when editing unterbrechung 2024-03-13 16:16:23 +01:00
cgfhtw f5bc8bdcb2 Studstatus: Unterbrechung: get semester for current status on new Antrag 2024-03-13 10:40:32 +01:00
cgfhtw 673fd889fe Studstatus: get details without whitelist 2024-03-13 10:39:51 +01:00
cgfhtw ab7a5bac68 Unterbrechung studienjahr und semester anzeige 2024-03-13 08:37:40 +01:00
Harald Bamberger 4c8486af22 use correct config property 2024-03-12 14:36:27 +01:00
Harald Bamberger d05df01178 move load lib from function handleAbmeldungenStglDeadline to constructor as its also used in handleWiederholerDeadline 2024-03-12 13:22:01 +01:00
Harald Bamberger 7bdf5b832b Merge branch 'master' into feature-36016/Studstatus_QMB 2024-03-12 11:32:25 +01:00
Harald Bamberger 9504b713fc add missing insertvon to phrases definition 2024-03-12 11:31:12 +01:00
Andreas Österreicher 8d2d1c049a Removed wrong Semicolon 2024-03-12 08:28:16 +01:00
cgfhtw ac39ce8e71 Studstatus create view: fallback for studierendenantrag_id 2024-03-11 15:27:34 +01:00
Harald Bamberger 664fe3830f Merge branch 'master' into feature-33003/BIS_Meldung_Personal 2024-03-08 11:39:02 +01:00
Harald Bamberger b17f253273 Tabs component: add flex-grow-1 class to use available space 2024-03-08 11:37:23 +01:00
Harald Bamberger d9e44c8c23 Merge branch 'master' into feature-33003/BIS_Meldung_Personal 2024-03-08 11:08:40 +01:00
Andreas Österreicher b753a05f0e Anpassungen am Import Script für Gemeinden von FHB übernommen 2024-03-07 08:10:17 +01:00
KarpAlex 1085b9243d Merge branch 'master' into feature-33003/BIS_Meldung_Personal 2024-03-05 17:07:17 +01:00
Harald Bamberger 3d6b2eb202 add app fhctemplate if it does not exist 2024-03-05 17:04:43 +01:00
Harald Bamberger 5ad3510af6 add use of phrasen plugin to apps 2024-03-05 16:47:29 +01:00
Harald Bamberger d5d190777a Merge branch 'feature-34543/UX_Template' 2024-03-05 16:46:48 +01:00
Andreas Österreicher 7524d054db Merge branch 'feature-36530/bis_internationalisierung_codextabelle_neuerungen' 2024-03-05 13:04:25 +01:00
Andreas Österreicher 6869c147ef Beim deaktivieren von Benutzern wird Updateaktivam und Updateaktivvon
gesetzt
2024-03-05 11:32:30 +01:00
Manfred e32d464b7f Merge branch 'master' into benutzerberechtigungGUIneu 2024-03-01 15:28:10 +01:00
Manfred 2e4f2709ed Merge branch 'RechteAnpassen' into benutzerberechtigungGUIneu 2024-03-01 15:27:11 +01:00
SimonGschnell 474c4ad34f removes file that belongs to CIS_Profil 2024-03-01 10:53:06 +01:00
cgfhtw 6500708f90 Code Quality 2024-02-29 09:02:20 +01:00
cgfhtw 2d2098984a Pause feature 2024-02-29 08:34:58 +01:00
Cris f94b1700e7 Renamed filter- and phrases app for Fhc-Core-Extension
Renamed from extension to fhctemplate
2024-02-28 13:38:59 +01:00
Andreas Österreicher e243980ae6 Merge branch 'master' into feature-18571/EntwicklungsteamBisMeldung 2024-02-26 15:58:49 +01:00
cgfhtw 4bbac35540 Status colors 2024-02-26 11:56:29 +01:00
Alexei Karpenko d9ec506c86 Codextabelle Mobilitaetsprogramm Neuerungen: changed name of some programs, set correct sichtbar and sichtbar_outgoing booleans 2024-02-23 16:54:51 +01:00
Cris 296741b584 Merge branch 'feature-34543/UX_Template' of https://github.com/FH-Complete/FHC-Core into feature-34543/UX_Template 2024-02-22 11:17:38 +01:00
Cris c232eddf89 Added filter and phrases for Fhc-Core-Extension 2024-02-22 11:17:27 +01:00
Werner Masik fff0e937cc added Method to end DV and deactivate Benutzer 2024-02-21 16:23:39 +01:00
SimonGschnell 2d1e8a829d userdata changes 2024-02-21 13:50:38 +01:00
cgfhtw c034efb8b0 Unterbrechung bei laufender Unterbrechung 2024-02-21 09:19:56 +01:00
Werner Masik cd64df28bb added phrase for habilitation 2024-02-20 15:02:14 +01:00
cgfhtw 72d166a050 FHCAPI Controller: multipart upload 2024-02-20 08:38:29 +01:00
KarpAlex dfe0434cce added new mobilitaetsprogramm codes 2024-02-19 17:59:20 +01:00
cgfhtw 013664db70 FhcApi Controller: new helper functions 2024-02-19 15:23:43 +01:00
cgfhtw 469b3e9833 Form Input: auto classes 2024-02-19 15:23:13 +01:00
cgfhtw 8ad2908ca9 UploadDms: Delete Button styles 2024-02-19 15:23:00 +01:00
cgfhtw 6aebbada06 Form Input: only setFeedback on last radio/checkbox in production mode 2024-02-19 10:39:18 +01:00
cgfhtw 658212a6eb Show Antrag to Student when finished 2024-02-16 13:28:26 +01:00
cgfhtw ab2fc11797 PDF Download Wiederholung Deadline 2024-02-16 11:44:27 +01:00
cgfhtw 75e05d6eed PDF Download korrektur 2024-02-16 09:27:42 +01:00
cgfhtw 70386a58f3 Tabs Component: removed TODOs 2024-02-16 08:53:34 +01:00
Cris caa7ad6cc4 Merge remote-tracking branch 'origin/feature-34543/UX_Template' into feature-34543/UX_Template 2024-02-15 09:54:51 +01:00
cgfhtw 3322f5115a FhcApi: Clean return value 2024-02-15 09:41:11 +01:00
cgfhtw f5b5f39689 FhcApi: return value 2024-02-14 16:00:48 +01:00
cgfhtw 091d8509f0 Send E-Mails after Wiederholer deadline 2024-02-13 14:53:58 +01:00
Cris 4d8dbb2e78 Created Core BaseLayout Component 2024-02-13 10:52:11 +01:00
Cris 565f89c884 Added phrases anrechnung, geloescht and aenderungGespeichert 2024-02-13 10:51:37 +01:00
Cris e6774024b9 Merge branch 'feature-34543/UX_Template' of https://github.com/FH-Complete/FHC-Core into feature-34543/UX_Template 2024-02-12 11:25:07 +01:00
cgfhtw ce9ebee57d CSS: fhc-header w/o bottom border 2024-02-09 11:10:03 +01:00
cgfhtw 8c6c2b7e11 FilterCmpt: defaults & Bugfix 2024-02-09 09:32:02 +01:00
cgfhtw 6e85b37b0f Tabs: optional border 2024-02-09 09:31:26 +01:00
cgfhtw c3ec909448 CSS improvements 2024-02-09 09:30:59 +01:00
Andreas Österreicher 1d300a604f Funktion zum Migrieren der Habiliation hinzugefügt 2024-02-08 08:03:34 +01:00
Andreas Österreicher 912f62dc01 Merge branch 'master' into feature-33003/BIS_Meldung_Personal 2024-02-08 08:03:00 +01:00
Cris bc0f7f7087 Merge branch 'feature-34543/UX_Template' of https://github.com/FH-Complete/FHC-Core into feature-34543/UX_Template 2024-02-07 15:50:50 +01:00
kindlm 72197bf993 Merge branch 'master' into RechteAnpassen 2024-02-07 12:58:43 +01:00
cgfhtw 2f79ae1ece Form/Validation bugfix: dismiss cache problem (correct solution) 2024-02-07 09:19:19 +01:00
cgfhtw a2c5ebb291 Fhc.css: fhc-header 2024-02-07 09:13:21 +01:00
cgfhtw 1f3e283d3c Code cleanup 2024-02-07 09:12:47 +01:00
cgfhtw eb69f77113 Form/Validation bugfix: dismiss cache problem 2024-02-07 09:12:06 +01:00
cgfhtw 6bc6c7c074 Form/Input: Injection defaults 2024-02-07 09:11:20 +01:00
kindlm 238208f252 Zeitwünsche mit mitarbeiter/zeitwuensche einsehen 2024-02-05 16:39:53 +01:00
KarpAlex 1c2c12f0a5 Bismeldestichtag Model: added getByStudiensemester method 2024-02-02 18:41:18 +01:00
cgfhtw dfbd67c52b Form/Input: Multiple radios/checkboxes 2024-02-01 15:43:36 +01:00
cgfhtw fe798506a6 raw_input_stream as array instead of stdobj & terminateWithSuccess 2024-02-01 08:59:35 +01:00
cgfhtw 51e556a731 Remove textarea+ & Form.send()
Add $clearValidationForName()
2024-02-01 08:58:32 +01:00
Andreas Österreicher a193a7a1c8 Naming Convention korrigiert fuer DBUpdate File 2024-02-01 08:50:06 +01:00
Andreas Österreicher 53fc8fc807 Berechtigungen für Entwicklungsteam ins Studiengangsverwaltungs Addon
verschoben
2024-02-01 08:38:55 +01:00
Andreas Österreicher ef64aa7da2 - Fehler behoben wodurch Entwicklugnsteam nicht gespeichert werden konnte
wenn das Endedatum leer ist.
- Entwicklungsteam update aus alten DB-Update entfernt
2024-02-01 08:20:10 +01:00
kindlm 1b3c509ee8 Rechte in Rollen kopieren 2024-01-31 16:02:29 +01:00
Andreas Österreicher fae185958b Merge branch 'master' into feature-18571/EntwicklungsteamBisMeldung 2024-01-31 13:27:58 +01:00
Cris 02f0c54f10 Adapted Filter.js to ensure displaying tabulator 'formatter' columns not provided by filtersupdate filter definition
...like rowSelection checkboxes or custom formatted action buttons
2024-01-31 13:25:44 +01:00
cgfhtw 2dbdf41086 FHC-Api: finetuning 2024-01-31 09:39:51 +01:00
Cris 6bd834c509 Added filter AnrechnungTable (for testing) 2024-01-30 17:05:03 +01:00
Cris aa06a97eb3 Corrected alertMultiple to display all messages
Before it stucked with only the first message. Now all messages are displayed.
2024-01-30 17:04:02 +01:00
Cris b868024175 Corrected wrong variable name in FhcAlert handleSystemMessage 2024-01-30 17:00:49 +01:00
cgfhtw ef3ee76fa1 Form Validation 2024-01-30 11:39:17 +01:00
cgfhtw 272c4d5ccc FhcApi cleanup 2024-01-30 11:39:08 +01:00
cgfhtw 30bd6ea6a4 FhcApi Plugin + Form updates 2024-01-30 10:42:48 +01:00
cgfhtw b010cbb35d FhcAlert: CSS 2024-01-30 10:42:12 +01:00
cgfhtw ea9e58a640 Bugfix: Typo 2024-01-30 10:41:45 +01:00
cgfhtw 1fec3543cd FHCAPI Controller 2024-01-25 16:41:05 +01:00
Harald Bamberger 72bcb919aa prevent returning html entities in sanitizeProblemChars helper 2024-01-25 12:41:32 +01:00
Cris 4706b16a99 Merge branch 'feature-34543/UX_Template' of https://github.com/FH-Complete/FHC-Core into feature-34543/UX_Template 2024-01-25 10:40:09 +01:00
cgfhtw afc995b4bd Form Input modelValue dummy 2024-01-25 10:29:19 +01:00
Cris 693d59e8bc Merge branch 'feature-34543/UX_Template' of https://github.com/FH-Complete/FHC-Core into feature-34543/UX_Template 2024-01-23 09:57:51 +01:00
cgfhtw e2a66d5143 Fragment Component 2024-01-23 09:43:41 +01:00
cgfhtw 41e5c52d2f Css updates 2024-01-23 09:42:33 +01:00
cgfhtw be82d9b6cb Tabs Component update 2024-01-23 09:32:26 +01:00
cgfhtw d66a6567b0 Form Components 2024-01-23 09:29:47 +01:00
kindlm 363ec9aa2f Merge branch 'master' into benutzerberechtigungGUIneu 2024-01-18 20:33:42 +01:00
kindlm 146b62d185 Filter in GET-Parameter 2024-01-18 20:33:03 +01:00
Werner Masik 304caf9157 added time recording query 2024-01-18 12:30:35 +01:00
KarpAlex 2c16e293a0 Merge branch 'master' into feature-33003/BIS_Meldung_Personal 2023-12-24 00:00:27 +01:00
KarpAlex 3e7d917184 deleted anrechnung von outgoing lvs file in dbupdate folder 2023-12-22 19:07:15 +01:00
kindlm a246513597 Spalte Organisationseinheit 2023-12-06 18:18:34 +01:00
Manfred a2e6927740 Merge branch 'master' into benutzerberechtigungGUIneu 2023-12-06 18:11:07 +01:00
kindlm c87ae7e74d Suche Person in OE; OE in Rechteliste OE-Suche 2023-12-06 18:06:46 +01:00
Manfred d35223c1a3 Merge branch 'master' into benutzerberechtigungGUIneu 2023-12-06 18:04:25 +01:00
KarpAlex cf85cb084f dbupdate habilitation: added file to dbupdate3.4, code formatting 2023-11-15 20:51:44 +01:00
KarpAlex 3a8216577f added column habilitation to tbl_mitarbeiter 2023-11-09 10:53:04 +01:00
ma0068 8fe72ebcf5 neues Element last_prestudentstatus for studienerfolg.xml 2023-09-28 16:47:44 +02:00
ma0068 cdb351b66b Delete Testdata and outputs 2023-09-18 10:37:14 +02:00
Andreas Österreicher 3e7abf9a45 Merge branch 'master' into feature-18571/EntwicklungsteamBisMeldung 2023-09-05 14:33:31 +02:00
ma0068 01046637fa merge master into feature-18571/Entwicklungsteam 2023-05-11 09:18:32 +02:00
ma0068 fe6746e6bc Ergänzung DB-update um Berechtigung stgv/edit Entwicklungsteam 2023-05-11 09:14:42 +02:00
ma0068 d59b3736a2 Test personalmeldung xml 2023-01-18 13:15:56 +01:00
ma0068 1aada9694e Anzeige EW-Team: nur aktuelle Eintraege oder Eintraege ohne Zeitraum 2022-12-02 12:44:53 +01:00
ma0068 1c0e74e828 Testvarianten zur Anzeige von EW-Team in Personalmeldung 2022-11-30 10:38:40 +01:00
ma0068 8baa5b74dd Revert "personalmeldung.php mit masterstand überschrieben, um letztes commit rückgängig zu machen"
This reverts commit 39572452a0.
2022-11-29 10:39:20 +01:00
ma0068 39572452a0 personalmeldung.php mit masterstand überschrieben, um letztes commit rückgängig zu machen 2022-11-29 10:26:31 +01:00
ma0068 561e4ea21a Erweiterung von Studiengangs_kz_Array um Start und Ende Entwicklungsteam 2022-11-28 10:56:20 +01:00
ma0068 a88e5cbdc2 Ergänzung Prüftabelle um entwicklungsteam_id 2022-11-22 12:22:48 +01:00
ma0068 f9d5a6a6a5 Adaptierungen fuer CheckSystem, dbupdate3.4 2022-11-22 12:14:54 +01:00
ma0068 01ad28021f Fix mergeErrors mitarbeiter.class und dbupdate3.3 2022-11-21 16:10:19 +01:00
ma0068 f94e9a3a15 Update Löschen alter Primary Key pk_tbl_entwicklungsteam_mitarbeiter_uid, studiengang_kz 2022-04-04 09:37:50 +02:00
ma0068 4676a0a7c1 Fix Bug: Übernahme Werte ins Detailfeld 2022-03-31 15:03:35 +02:00
ma0068 f0c40bf449 Adaptierungen Entwicklungsteam UID für FAS 2022-03-31 12:44:45 +02:00
ma0068 f29d838b7c Adaptierungen für checksystem entwicklungteam_id 2022-03-18 13:45:33 +01:00
ma0068 681385946a Adaptierungen Tabelle bis.tbl_entwicklungsteam aufgrund Erweiterung um entwicklungsteam_id 2022-03-17 12:24:18 +01:00
ma0068 67c9c79113 Änderung Klasse Entwicklungsteam auf neuen Key entwicklungsteam_id 2022-03-16 13:02:52 +01:00
ma0068 9c1b6bcd44 Entwicklungsteam: Adpatierungen für Sorierung und Anzeige Mitarbeiter Grid 2022-03-15 09:43:46 +01:00
ma0068 5838e1caa5 neue Funktion getAll für Entwicklungsteam STGV 2022-03-05 12:51:06 +01:00
ma0068 297172113d neue Funktion getAll() für Anzeige Entwicklungsteams 2022-02-10 11:04:31 +01:00
101 changed files with 18574 additions and 1682 deletions
@@ -116,6 +116,96 @@ class Leitung extends FHC_Controller
$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');
@@ -86,7 +86,7 @@ class Unterbrechung extends FHC_Controller
$data = getData($result);
$data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($data->studiensemester_kurzbz);
$data->studiensemester = $this->antraglib->getSemesterForUnterbrechung($prestudent_id, null);
$this->outputJsonSuccess($data);
}
@@ -136,7 +136,7 @@ class Unterbrechung extends FHC_Controller
$datum_wiedereinstieg = $this->input->post('datum_wiedereinstieg');
$dms_id = null;
$result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id);
$result = $this->antraglib->getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester, $datum_wiedereinstieg);
if (isError($result)) {
return $this->outputJsonError(['db' => getError($result)]);
}
@@ -161,6 +161,18 @@ class Wiederholung extends FHC_Controller
{
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')]);
@@ -241,7 +253,8 @@ class Wiederholung extends FHC_Controller
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)
if ($antrag->status != Studierendenantragstatus_model::STATUS_CREATED
&& $antrag->status != Studierendenantragstatus_model::STATUS_LVSASSIGNED)
return $this->outputJsonError($this->p->t('studierendenantrag', 'error_antrag_locked'));
}
@@ -21,7 +21,7 @@ class SearchBar extends FHC_Controller
// NOTE:
// - A user must be authenticated via another controller to access this one
// - It is loaded to be able to call the isLogged function later
$this->load->library('AuthLib', array(false));
$this->load->library('AuthLib');
// Load the library SearchBarLib
$this->load->library('SearchBarLib');
+61 -12
View File
@@ -19,6 +19,8 @@ class AntragJob extends JOB_Controller
// Loads SanchoHelper
$this->load->helper('hlp_sancho_helper');
$this->load->library('AntragLib');
// Load Model
$this->load->model('education/Studierendenantrag_model', 'StudierendenantragModel');
$this->load->model('education/Studierendenantragstatus_model', 'StudierendenantragstatusModel');
@@ -172,7 +174,16 @@ class AntragJob extends JOB_Controller
$cc = $leitung['Details']->email;
// NOTE(chris): Sancho mail
if (sendSanchoMail("Sancho_Mail_Antrag_Stgl", $data, $to, 'Anträge - Aktion(en) erforderlich', DEFAULT_SANCHO_HEADER_IMG, DEFAULT_SANCHO_FOOTER_IMG, '', $cc))
if (sendSanchoMail(
"Sancho_Mail_Antrag_Stgl",
$data,
$to,
'Anträge - Aktion(en) erforderlich',
DEFAULT_SANCHO_HEADER_IMG,
DEFAULT_SANCHO_FOOTER_IMG,
'',
$cc
))
$count++;
}
@@ -316,12 +327,52 @@ class AntragJob extends JOB_Controller
} else {
$deregisterStatus = getData($result);
$result = $this->antraglib->pauseAntrag(
$prestudent->studierendenantrag_id,
Studierendenantragstatus_model::INSERTVON_DEREGISTERED
);
if (isError($result))
$this->logError(getError($result));
$result = $this->prestudentlib->setAbbrecher($prestudent->prestudent_id, '', $insertvon);
if (isError($result)) {
$this->StudierendenantragstatusModel->delete($deregisterStatus);
$this->logError(getError($result));
} else {
$count++;
$datum_kp = new DateTime($prestudent->datum);
$dataMail = array(
'name'=> trim($prestudent->vorname . ' '. $prestudent->nachname),
'vorname' => $prestudent->vorname,
'nachname' => $prestudent->nachname,
'pers_kz'=> $prestudent->matrikelnr,
'stg' => $prestudent->bezeichnung,
'lvbezeichnung' => $prestudent->lvbezeichnung,
'datum_kp' => $datum_kp->format('d.m.Y'),
'studiensemester'=> $prestudent->studiensemester_kurzbz,
'Orgform'=> $prestudent->orgform,
'prestudent_id' => $prestudent->prestudent_id,
'fristablauf' => $dateDeadline->format('d.m.Y')
);
$email = $this->StudentModel->getEmailFH($this->StudentModel->getUID($prestudent->prestudent_id));
// Mail to Student
if (!sendSanchoMail('Sancho_Mail_Antrag_W_DL_Stud', $dataMail, $email, 'Wiederholung: Frist abgelaufen')) {
$this->logWarning("Failed to send Notification to " . $email);
}
$result = $this->StudiengangModel->load($prestudent->studiengang_kz);
if (!hasData($result)) {
$this->logWarning('No Studiengang found');
continue;
}
$studiengang = current(getData($result));
$email = $studiengang->email;
// Mail to Assistenz
if (!sendSanchoMail('Sancho_Mail_Antrag_W_DL_Assist', $dataMail, $email, 'Wiederholung: Frist abgelaufen')) {
$this->logWarning("Failed to send Notification to " . $email);
}
}
}
}
@@ -339,8 +390,6 @@ class AntragJob extends JOB_Controller
{
$this->logInfo('Start Job handleAbmeldungenStglDeadline');
$this->load->library('AntragLib');
$insertvon = $this->config->item('antrag_job_systemuser');
if (!$insertvon) {
$this->logError('Config "antrag_job_systemuser" nicht gesetzt');
@@ -364,7 +413,10 @@ class AntragJob extends JOB_Controller
$this->StudierendenantragModel->addSelect('s.insertamum');
$this->StudierendenantragModel->addSelect('s.insertvon');
$this->StudierendenantragModel->db->where_in('public.get_rolle_prestudent(prestudent_id, studiensemester_kurzbz)', $this->config->item('antrag_prestudentstatus_whitelist'));
$this->StudierendenantragModel->db->where_in(
'public.get_rolle_prestudent(prestudent_id, studiensemester_kurzbz)',
$this->config->item('antrag_prestudentstatus_whitelist')
);
$result = $this->StudierendenantragModel->getWithLastStatusWhere([
'typ' => Studierendenantrag_model::TYP_ABMELDUNG_STGL,
@@ -393,6 +445,10 @@ class AntragJob extends JOB_Controller
else {
$deregisterStatus = getData($result);
$result = $this->antraglib->pauseAntrag($antrag->studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_DEREGISTERED);
if (isError($result))
$this->logError(getError($result));
$result = $this->prestudentlib->setAbbrecher(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
@@ -438,7 +494,6 @@ class AntragJob extends JOB_Controller
$this->logWarning("Failed to send Notification to " . $email);
}
}
}
}
$this->logInfo($count . "/" . count($antraege) . " Students set to Abbrecher");
@@ -569,12 +624,6 @@ class AntragJob extends JOB_Controller
}
}
$this->load->model('crm/Prestudentstatus_model', 'PrestudentstatusModel');
$result = $this->PrestudentstatusModel->loadLastWithStgDetails($prestudent->prestudent_id, $prestudent->studiensemester_kurzbz);
if (hasData($result)) {
$ausbildungssemester = current(getData($result))->semester;
}
$dataMail = array(
'name'=> trim($prestudent->vorname . ' '. $prestudent->nachname),
'vorname' => $prestudent->vorname,
@@ -591,7 +640,7 @@ class AntragJob extends JOB_Controller
'fristablauf' => $fristende->format('d.m.Y'),
'pre_wiederholer_sem' => $next_sem,
'wiederholer_sem' => $sem_after_next_sem,
'sem' => $ausbildungssemester
'sem' => $prestudent->ausbildungssemester
);
// NOTE(chris): Sancho mail
@@ -677,4 +677,35 @@ class MigrateContract extends CLI_Controller
else
return 0;
}
/**
* Habilitation wird aus der Tabelle bis.tbl_bisverwendung in die Tabelle public.tbl_mitarbeiter uebernommen
* Sofern die Person einmal in den Verwendungen eine habiliation eingetragen hat wird diese in den MA-Datensatz übernommen
* Da es in der regel öfter vorkommt dass das hakerl vergessen wurde beim Vertragswechsel als dass die person die habiliation verliert.
*/
public function migrateHabilitation()
{
$this->load->model('ressource/Mitarbeiter_model','MitarbeiterModel');
$db = new DB_Model();
$qry = "
SELECT
distinct mitarbeiter_uid
FROM
bis.tbl_bisverwendung
WHERE
habilitation=true";
$resultHabilitation = $db->execReadOnlyQuery($qry);
if (isSuccess($resultHabilitation) && hasData($resultHabilitation))
{
$habilitationen = getData($resultHabilitation);
foreach ($habilitationen as $row_habilitationen)
{
$this->MitarbeiterModel->update($row_habilitationen->mitarbeiter_uid, array('habilitation'=>true));
}
}
}
}
@@ -3,7 +3,7 @@
* Job zur einmaligen Import der Gehälter
*
* Aufruf (Encode / im Filenmae mit %2F):
* php index.ci.php system/MigrateSalary/import filename
* php index.ci.php system/MigrateSalary/import filename
*
*/
/*
@@ -34,7 +34,7 @@ class MigrateSalary extends CLI_Controller
$this->load->model('vertragsbestandteil/VertragsbestandteilStunden_model','VertragsbestandteilStundenModel');
$this->load->model('vertragsbestandteil/VertragsbestandteilFreitext_model','VertragsbestandteilFreitextModel');
$this->load->model('vertragsbestandteil/VertragsbestandteilFunktion_model','VertragsbestandteilFunktionModel');
}
// -----------------------------------------------------------------------------------------------------------------
@@ -45,7 +45,7 @@ class MigrateSalary extends CLI_Controller
*/
public function import($file)
{
// CSV Laden
$file = urldecode($file);
if($handle = fopen($file, "r"))
@@ -108,8 +108,8 @@ class MigrateSalary extends CLI_Controller
}
else
{
if ($data[$i] != ''
&& isset($gehaltsarr[$gehaltsindex]) && isset($gehaltsarr[$gehaltsindex]['betrag'])
if ($data[$i] != ''
&& isset($gehaltsarr[$gehaltsindex]) && isset($gehaltsarr[$gehaltsindex]['betrag'])
&& $gehaltsarr[$gehaltsindex]['betrag'] == $data[$i])
{
// Gehalt bleibt gleich
@@ -138,30 +138,31 @@ class MigrateSalary extends CLI_Controller
}
}
}
$monat++;
}
// Zeile zu Ende - Ende Datum setzen wenn nicht für alle Monate ein Eintrag vorhanden ist
if($monat < count($monate) && isset($gehaltsarr[$gehaltsindex]))
$gehaltsarr[$gehaltsindex]['ende'] == $monate[$monat-1];
$gehaltsarr[$gehaltsindex]['ende'] = $monate[$monat-1];
}
$this->_saveGehalt($lastuser, $gehaltsarr);
}
}
/**
* Ermittelt das passende Dienstverhaeltnis uns speichert den
* Ermittelt das passende Dienstverhaeltnis uns speichert den
* Gehaltsbestandteil
*/
private function _saveGehalt($uid, $gehaltsarr)
{
{
$failed = false;
$this->db->trans_begin();
foreach($gehaltsarr as $row_gehalt)
{
//var_dump($row_gehalt);
$auszahlungen = 14;
$dvid = '';
$vbsid = '';
@@ -171,16 +172,18 @@ class MigrateSalary extends CLI_Controller
//DV und VBS Ermitteln
$dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $row_gehalt['beginn']);
if (!hasData($dv))
// Wenn keiner gefunden wird oder mit Monatsersteln nur ein externer gefunden wird, weitersuchen ob im Monat noch ein
// "richtiger" Vertrag startet
if (!hasData($dv) || getData($dv)[0]->vertragsart_kurzbz='externerLehrender')
{
$date = new DateTime($row_gehalt['beginn']);
$date->modify('last day of this month');
$last_day_this_month = $date->format('Y-m-d');
// Wenn mit Monatsersten kein DV gefunden wird, wird stattdessen mit Monatsletzten gesucht um DVs zu finden
// Wenn mit Monatsersten kein DV gefunden wird, wird stattdessen mit Monatsletzten gesucht um DVs zu finden
// für Personen die erst später im Monat in ihr DV einsteigen
$dv = $this->DienstverhaeltnisModel->getDVByPersonUID($uid, $this->OE_DEFAULT, $last_day_this_month);
$dv = $this->DienstverhaeltnisModel->getDVByPersonUIDOverlapping($uid, $this->OE_DEFAULT, $row_gehalt['beginn'], $last_day_this_month);
if (!hasData($dv))
{
echo "\nKein passendes DV gefunden für User ".$uid." und Datum ".$row_gehalt['beginn']." -> ROLLBACK\n";
@@ -189,34 +192,53 @@ class MigrateSalary extends CLI_Controller
}
else
{
// Gehaltsstart wird auf den Start des DV korrigiert wenn nicht der Monatserste
$row_gehalt['beginn'] = getData($dv)[0]->von;
$resultdata = getData($dv);
foreach($resultdata as $dvdata)
{
// Externer DV wird in Monatsmitte zu echten DV - daher weitersuchen bei externenDVs da
// diese sowieso kein Gehalt zugeordnet haben
if($dvdata->vertragsart_kurzbz != 'externerLehrender')
{
$dvid = $dvdata->dienstverhaeltnis_id;
// Gehaltsstart wird auf den Start des DV korrigiert wenn nicht der Monatserste
// nur wenn das Beginndatum vor dem DV-Start liegt da sonst das Datum korrigiert wird
// wenn der Vertragsbestandteil wechselt
if($row_gehalt['beginn'] < $dvdata->von)
$row_gehalt['beginn'] = $dvdata->von;
break;
}
}
}
}
$resultdata = getData($dv);
if (count($resultdata) !== 1)
else
{
echo "Kein oder Mehrere DVs gefunden -> ROLLBACK";
$resultdata = getData($dv);
if (count($resultdata) == 1)
$dvid = $resultdata[0]->dienstverhaeltnis_id;
}
if ($dvid == '')
{
echo "Kein oder mehrere DVs gefunden -> ROLLBACK";
$failed = true;
break;
}
$dvid = $resultdata[0]->dienstverhaeltnis_id;
$allin = $this->_isAllIn($dvid, $row_gehalt['beginn']);
$db = new DB_Model();
$resultVBS = $this->_getVBS($dvid, $row_gehalt['beginn']);
if (hasData($resultVBS))
{
$vbsid = getData($resultVBS)[0]->vertragsbestandteil_id;
$vbsbis = getData($resultVBS)[0]->bis;
}
else
{
echo "Vertragsbestandteil wurde nicht gefunden -> ROLLBACK";
echo "Vertragsbestandteil fuer $uid DV $dvid wurde nicht gefunden mit Beginn ".$row_gehalt['beginn']."-> ROLLBACK";
$failed = true;
break;
}
@@ -246,7 +268,7 @@ class MigrateSalary extends CLI_Controller
);
if (isset($row_gehalt['ende']) && $row_gehalt['ende']!='')
$data['bis'] = $row_gehalt['ende'];
$resultVBS = $this->VertragsbestandteilModel->Insert($data);
if(!isSuccess($resultVBS))
{
@@ -286,7 +308,7 @@ class MigrateSalary extends CLI_Controller
);
if (isset($row_gehalt['ende']) && $row_gehalt['ende']!='')
$data['bis'] = $row_gehalt['ende'];
$resultVBS = $this->VertragsbestandteilModel->Insert($data);
if(!isSuccess($resultVBS))
{
@@ -356,16 +378,24 @@ class MigrateSalary extends CLI_Controller
$date->modify('last day of this month');
$last_day_this_month = $date->format('Y-m-d');
// TODO: wenn das Dienstverhaeltnis in diesem Monat endet und nicht der Monatsletzte ist,
// Wenn das Dienstverhaeltnis in diesem Monat endet und nicht der Monatsletzte ist,
// dann muss hier das Ende Datum des DV stehen bzw das Ende
// oder das Ende des VBS falls die Person in der Monatsmitte Stunden wechselt
$data['bis'] = $last_day_this_month;
// Wenn der Vertragsbestandteil endet bevor das Gehalt endet, dann wir das Gehaltsende auf VBS Ende gesetzt
//echo "Ende des VBS: $vbsbis Ende des Gehalt: ".$data['bis'];
if ($vbsbis != '' && $vbsbis < $data['bis'])
{
$data['bis'] = $vbsbis;
//echo "Gehalt auf vbs ende gesetzt";
}
}
$ret = $this->GehaltsbestandteilModel->insert($data,
$this->GehaltsbestandteilModel->getEncryptedColumns()
);
}
}
if(!$failed)
{
@@ -375,7 +405,7 @@ class MigrateSalary extends CLI_Controller
{
echo "ROLLBACK";
$this->db->trans_rollback();
}
}
}
/**
@@ -386,17 +416,17 @@ class MigrateSalary extends CLI_Controller
$db = new DB_Model();
$qry = "
SELECT
*
FROM
hr.tbl_vertragsbestandteil
SELECT
*
FROM
hr.tbl_vertragsbestandteil
JOIN hr.tbl_vertragsbestandteil_freitext USING(vertragsbestandteil_id)
WHERE
dienstverhaeltnis_id=".$db->escape($dvid)."
AND vertragsbestandteiltyp_kurzbz='freitext'
WHERE
dienstverhaeltnis_id=".$db->escape($dvid)."
AND vertragsbestandteiltyp_kurzbz='freitext'
AND ".$db->escape($datum)." BETWEEN von AND COALESCE(bis, '2999-12-31')
AND freitexttyp_kurzbz='allin'";
$resultAllIn = $db->execReadOnlyQuery($qry);
if (hasData($resultAllIn))
@@ -410,15 +440,15 @@ class MigrateSalary extends CLI_Controller
$db = new DB_Model();
$qry = "
SELECT
*
FROM
hr.tbl_vertragsbestandteil
WHERE
dienstverhaeltnis_id=".$db->escape($dvid)."
AND vertragsbestandteiltyp_kurzbz='stunden'
SELECT
*
FROM
hr.tbl_vertragsbestandteil
WHERE
dienstverhaeltnis_id=".$db->escape($dvid)."
AND vertragsbestandteiltyp_kurzbz='stunden'
AND ".$db->escape($datum)." BETWEEN von AND COALESCE(bis, '2999-12-31')";
$resultVBS = $db->execReadOnlyQuery($qry);
return $resultVBS;
@@ -430,22 +460,22 @@ class MigrateSalary extends CLI_Controller
private function _getUser($svnr)
{
$db = new DB_Model();
$qry = "
SELECT
mitarbeiter_uid
FROM
public.tbl_person
SELECT
mitarbeiter_uid
FROM
public.tbl_person
JOIN public.tbl_benutzer using(person_id)
JOIN public.tbl_mitarbeiter ON(uid=mitarbeiter_uid)
WHERE
tbl_person.svnr = ". $db->escape($svnr)."
AND EXISTS(
SELECT
1
FROM
hr.tbl_dienstverhaeltnis
WHERE
SELECT
1
FROM
hr.tbl_dienstverhaeltnis
WHERE
mitarbeiter_uid=tbl_mitarbeiter.mitarbeiter_uid
AND oe_kurzbz=". $db->escape($this->OE_DEFAULT)."
)
+255
View File
@@ -0,0 +1,255 @@
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* Controller using JSON
*/
class FHCAPI_Controller extends FHC_Controller
{
/**
* Response status
* @see https://github.com/omniti-labs/jsend
*/
const STATUS_SUCCESS = 'success';
const STATUS_FAIL = 'fail';
const STATUS_ERROR = 'error';
/**
* Error types
*/
const ERROR_TYPE_PHP = 'php'; // TODO(chris): php types from severity?
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';
/**
* Return Object
*
* @var array
*/
private $returnObj = [];
/**
* Constructor
*
* @param array $requiredPermissions
* @return void
*/
public function __construct($requiredPermissions = [])
{
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;
ob_start(function ($content) {
$http_response_code = http_response_code();
// NOTE(chris): For security reasons 404 will be displayed the same everywhere
if ($http_response_code == REST_Controller::HTTP_NOT_FOUND)
return $content;
header('Content-Type: application/json; charset=utf-8');
if (!isset($this->returnObj['meta']) || !isset($this->returnObj['meta']['status'])) {
switch ($http_response_code) {
case 200:
$this->setStatus(self::STATUS_SUCCESS);
break;
case 400:
$this->setStatus(self::STATUS_FAIL);
break;
default:
$this->setStatus(self::STATUS_ERROR);
break;
}
}
#$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);
// 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);
elseif (isset($_POST['_jsondata'])) {
$_POST = array_merge($_POST, json_decode($_POST['_jsondata'], true));
unset($_POST['_jsondata']);
}
}
// ---------------------------------------------------------------
// Handle Output object
// ---------------------------------------------------------------
/**
* @param array $data
* @param string $type (optional)
* @return void
*/
public function addError($data, $type = null)
{
if (!isset($this->returnObj['errors']))
$this->returnObj['errors'] = [];
$error = [];
if (is_array($data)) {
if ($type == self::ERROR_TYPE_VALIDATION)
$error['messages'] = $data;
else
$error = $data;
} else {
$error['message'] = $data;
}
if ($type)
$error['type'] = $type;
$this->returnObj['errors'][] = $error;
}
/**
* @param mixed $data
* @return void
*/
public function setData($data)
{
$this->returnObj['data'] = $data;
}
/**
* @param string $status
* @return void
*/
public function setStatus($status)
{
if (!isset($this->returnObj['meta']))
$this->returnObj['meta'] = [];
$this->returnObj['meta']['status'] = $status;
}
// ---------------------------------------------------------------
// Handle Output object - Shortcut functions
// ---------------------------------------------------------------
/**
* @param array $errors
* @return void
*/
protected function terminateWithValidationErrors($errors)
{
$this->output->set_status_header(REST_Controller::HTTP_BAD_REQUEST);
$this->addError($errors, self::ERROR_TYPE_VALIDATION);
$this->setStatus(self::STATUS_FAIL);
exit(EXIT_ERROR);
}
/**
* @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 $type (optional)
* @return void
*/
protected function terminateWithError($error, $type = null)
{
$this->output->set_status_header(REST_Controller::HTTP_INTERNAL_SERVER_ERROR);
$this->addError($error, $type);
$this->setStatus(self::STATUS_ERROR);
exit;
}
/**
* @param stdclass $result
* @param string $errortype
* @return void
*/
protected function checkForErrors($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
*
* @param array $requiredPermissions
* @return void
*/
protected function _isAllowed($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->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]);
}
}
+316 -120
View File
@@ -62,9 +62,11 @@ class AntragLib
'insertvon' => $insertvon
]);
// NOTE(chris): remove "preabbrecher" statusgrund for Stgl-Abmeldungen if set
// NOTE(chris): remove "preabbrecher" statusgrund and paused stati for sibling Anträge for Stgl-Abmeldungen if set
$res = $this->_ci->StudierendenantragModel->load($antrag_id);
if (hasData($res) && current(getData($res))->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL) {
$this->unpauseAntrag($antrag_id, Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL);
$this->_ci->PrestudentstatusModel->addSelect('tbl_status_grund.statusgrund_kurzbz');
$res = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail(current(getData($res))->prestudent_id, '', 'Student');
if (hasData($res) && current(getData($res))->statusgrund_kurzbz == 'preabbrecher') {
@@ -83,6 +85,67 @@ class AntragLib
return $result;
}
/**
* @param integer $antrag_id
* @param string $insertvon
*
* @return stdClass
*/
public function pauseAntrag($antrag_id, $insertvon)
{
switch ($insertvon) {
case Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL:
$result = $this->_ci->StudierendenantragstatusModel->stopAntraegeForAbmeldungStgl($antrag_id);
break;
case Studierendenantragstatus_model::INSERTVON_DEREGISTERED:
$result = $this->_ci->StudierendenantragstatusModel->stopAntraegeForAbbruchBy($antrag_id);
break;
default:
$result = $this->_ci->StudierendenantragstatusModel->insert([
'studierendenantrag_id' => $antrag_id,
'studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE,
'insertvon' => $insertvon
]);
break;
}
return $result;
}
/**
* @param integer $antrag_id
* @param string $insertvon
*
* @return stdClass
*/
public function unpauseAntrag($antrag_id, $insertvon)
{
if ($insertvon == Studierendenantragstatus_model::INSERTVON_DEREGISTERED)
return error($this->p->t('studierendenantrag', 'error_no_right'));
if ($insertvon == Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL) {
return $this->_ci->StudierendenantragstatusModel->resumeAntraegeForAbmeldungStgl($antrag_id);
}
// NOTE(chris): get last status that is not pause
$this->_ci->StudierendenantragstatusModel->addOrder('insertamum');
$this->_ci->StudierendenantragstatusModel->addLimit(1);
$result = $this->_ci->StudierendenantragstatusModel->loadWhere([
'studierendenantrag_id' => $antrag_id,
'studierendenantrag_statustyp_kurzbz !=' => Studierendenantragstatus_model::STATUS_PAUSE
]);
if (isError($result))
return $result;
if (!hasData($result))
return error($this->_ci->p->t('studierendenantrag', 'error_no_antragstatus', ['id' => $antrag_id]));
$status = current(getData($result));
$result = $this->_ci->StudierendenantragstatusModel->insert([
'studierendenantrag_id' => $antrag_id,
'studierendenantrag_statustyp_kurzbz' => $status->studierendenantrag_statustyp_kurzbz,
'insertvon' => $insertvon
]);
return $result;
}
/**
* NOTE(chris): permissions & verification must be handled outside
*
@@ -169,7 +232,7 @@ class AntragLib
if (isError($result))
$errors[] = getError($result);
else {
$this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps','studiengang_kz');
$this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps', 'studiengang_kz');
$result = $this->_ci->StudiengangModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]);
$stg = '';
$orgform = '';
@@ -190,6 +253,10 @@ class AntragLib
$vorlage ='Sancho_Mail_Antrag_A_Approve';
$subject = $this->_ci->p->t('studierendenantrag', 'mail_subject_A_Approve');
$result = $this->pauseAntrag($studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_DEREGISTERED);
if (isError($result))
$errors[] = getError($result);
$result = $this->_ci->prestudentlib->setAbbrecher(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
@@ -208,7 +275,13 @@ class AntragLib
$data = [
'student' => $this->_ci->p->t('person', 'studentIn'),
'sem' => $antrag->studiensemester_kurzbz,
'linkPdf' => base_url('content/pdfExport.php?xml=Antrag' . $antrag->typ . '.xml.php&xsl=Antrag' . $antrag->typ . '&id=' . $antrag->studierendenantrag_id . '&output=pdf')
'linkPdf' => base_url('content/pdfExport.php?xml=Antrag' .
$antrag->typ .
'.xml.php&xsl=Antrag' .
$antrag->typ .
'&id=' .
$antrag->studierendenantrag_id .
'&output=pdf')
];
if (hasData($result)) {
$person = current(getData($result));
@@ -229,6 +302,10 @@ class AntragLib
sendSanchoMail($vorlage, $data, $prestudent_status->email, $subject);
}
} else { // ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL)
$result = $this->pauseAntrag($studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL);
if (isError($result))
$errors[] = getError($result);
$result = $this->_ci->PrestudentstatusModel->getLastStatusWithStgEmail($antrag->prestudent_id, '', 'Student');
if (isError($result))
{
@@ -340,6 +417,10 @@ class AntragLib
if (isError($result))
return $result;
else {
$result = $this->pauseAntrag($studierendenantrag_id, Studierendenantragstatus_model::INSERTVON_DEREGISTERED);
// NOTE(chris): here we should have error handling but at the
// moment there is no way to notify the user for "soft" errors
$result = $this->_ci->prestudentlib->setAbbrecher(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
@@ -471,7 +552,6 @@ class AntragLib
'<br>Details:<br>' .
$error_msg;
} else {
$data = getData($data);
$result = $this->_ci->StudierendenantragstatusModel->insert([
@@ -582,7 +662,11 @@ class AntragLib
'nachname' => $data['person']->nachname,
'UID' => $data['UID'],
'sem' => $resultAntrag->studiensemester_kurzbz,
'linkPdf' => base_url('content/pdfExport.php?xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&id=' . $studierendenantrag_id . '&output=pdf'),
'linkPdf' => base_url(
'content/pdfExport.php?xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&id=' .
$studierendenantrag_id .
'&output=pdf'
),
'insertvon' => $approvedBy
],
$data['prestudent_status']->email,
@@ -699,7 +783,9 @@ class AntragLib
'Orgform' => $data['prestudent_status']->orgform_kurzbz,
'prestudent_id' => $data['prestudent_status']->prestudent_id,
'abmeldungLink' => site_url('lehre/Studierendenantrag/abmeldung/' . $data['prestudent_status']->prestudent_id),
'abmeldungLinkCIS' => CIS_ROOT . 'index.ci.php/lehre/Studierendenantrag/abmeldung/' . $data['prestudent_status']->prestudent_id
'abmeldungLinkCIS' => CIS_ROOT .
'index.ci.php/lehre/Studierendenantrag/abmeldung/' .
$data['prestudent_status']->prestudent_id
],
$data['email'],
$this->_ci->p->t('studierendenantrag', 'mail_subject_U_Reject')
@@ -734,7 +820,7 @@ class AntragLib
return error($this->_ci->p->t('studierendenantrag', 'error_no_antrag_found', ['id' => $studierendenantrag_id]));
$result['antrag'] = $antrag = current($res);
$this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps','studiengang_kz');
$this->_ci->StudiengangModel->addJoin('public.tbl_prestudent ps', 'studiengang_kz');
$res = $this->_ci->StudiengangModel->loadWhere(['prestudent_id' => $antrag->prestudent_id]);
if (hasData($res)) {
$result['studiengang'] = current(getData($res));
@@ -862,7 +948,9 @@ class AntragLib
$result = $this->_ci->StudierendenantragstatusModel->insert([
'studierendenantrag_id' => $antrag_id,
'studierendenantrag_statustyp_kurzbz' => $repeat ? Studierendenantragstatus_model::STATUS_CREATED : Studierendenantragstatus_model::STATUS_PASS,
'studierendenantrag_statustyp_kurzbz' => $repeat
? Studierendenantragstatus_model::STATUS_CREATED
: Studierendenantragstatus_model::STATUS_PASS,
'insertvon' => $insertvon
]);
@@ -878,8 +966,7 @@ class AntragLib
$email = $prestudent_status->email;
// NOTE(chris): Sancho mail
$lvzuweisungLink = site_url('lehre/Antrag/Wiederholung/assistenz/' . $antrag_id);
if( defined('VILESCI_ROOT') )
{
if (defined('VILESCI_ROOT')) {
$lvzuweisungLink = VILESCI_ROOT . 'index.ci.php/lehre/Antrag/Wiederholung/assistenz/' . $antrag_id;
}
sendSanchoMail(
@@ -888,7 +975,7 @@ class AntragLib
'antrag_id' => $antrag_id,
'stg' => $prestudent_status->stg_bezeichnung,
'Orgform' => $prestudent_status->orgform,
'lvzuweisungLink' => $lvzuweisungLink
'lvzuweisungLink' => $lvzuweisungLink
],
$email,
$this->_ci->p->t('studierendenantrag', 'mail_subject_W_New')
@@ -1062,7 +1149,11 @@ class AntragLib
if (isError($result))
return $result;
if (!hasData($result))
return error($this->_ci->p->t('studierendenantrag', 'error_no_stdsem', ['studiensemester_kurzbz' => $antrag->studiensemester_kurzbz]));
return error($this->_ci->p->t(
'studierendenantrag',
'error_no_stdsem',
['studiensemester_kurzbz' => $antrag->studiensemester_kurzbz]
));
$asem = current(getData($result));
foreach ($stdsems as $sem) {
@@ -1117,7 +1208,6 @@ class AntragLib
$lv->antrag_anmerkung = $lvszugewiesen[$lv->lehrveranstaltung_id]->anmerkung;
$lv->antrag_zugelassen = true;
}
}
} else {
$lvsA = null;
@@ -1224,10 +1314,10 @@ class AntragLib
* @param integer $prestudent_id
*
* @return \stdClass on success retval 0 means not a student;
* retval 1 means Berechtigt;
* retval -1 means has already an Antrag pending;
* retval -2 means other Antrag pending;
* retval -3 means in blacklist stg
* retval 1 means Berechtigt;
* retval -1 means has already an Antrag pending;
* retval -2 means other Antrag pending;
* retval -3 means in blacklist stg
*/
public function getPrestudentAbmeldeBerechtigt($prestudent_id)
{
@@ -1251,12 +1341,24 @@ class AntragLib
if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist_abmeldung'))) {
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED
], [
Studierendenantrag_model::TYP_ABMELDUNG,
Studierendenantrag_model::TYP_ABMELDUNG_STGL
]);
'prestudent_id' => $prestudent_id,
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED
], [
Studierendenantrag_model::TYP_ABMELDUNG,
Studierendenantrag_model::TYP_ABMELDUNG_STGL
]);
if (isError($result))
return $result;
if (hasData($result))
return success(-1);
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE
], [
Studierendenantrag_model::TYP_ABMELDUNG,
Studierendenantrag_model::TYP_ABMELDUNG_STGL
]);
if (isError($result))
return $result;
if (hasData($result))
@@ -1297,12 +1399,12 @@ class AntragLib
* @param string $studiensemester_kurzbz (optional)
*
* @return \stdClass on success retval 0 means not a student;
* retval 1 means Berechtigt;
* retval 1 means Berechtigt;
* retval -1 means has already an Antrag pending;
* retval -2 means other Antrag pending;
* retval -3 means in blacklist stg
*/
public function getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester_kurzbz = null)
public function getPrestudentUnterbrechungsBerechtigt($prestudent_id, $studiensemester_kurzbz = null, $datum_wiedereinstieg = null)
{
$result = $this->_ci->PrestudentModel->load($prestudent_id);
if (isError($result))
@@ -1320,18 +1422,10 @@ class AntragLib
if (!hasData($result))
return success(0);
$result = current(getData($result));
$prestudent_stdsem = $result->studiensemester_kurzbz;
$datumStatus = $result->datum;
if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist'))) {
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_UNTERBRECHUNG,
'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED
]);
if (isError($result))
return $result;
if (hasData($result))
return success(-1);
if (!in_array($result->status_kurzbz, $this->_ci->config->item('antrag_prestudentstatus_whitelist'))
&& $result->status_kurzbz != 'Unterbrecher') {
return success(0);
}
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere(['prestudent_id' => $prestudent_id]);
@@ -1339,7 +1433,8 @@ class AntragLib
return $result;
if (!hasData($result))
return success(1);
$result= getData($result);
$result = getData($result);
foreach ($result as $antrag)
{
if ($antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG || $antrag->typ == Studierendenantrag_model::TYP_ABMELDUNG_STGL)
@@ -1349,11 +1444,11 @@ class AntragLib
elseif($antrag->status == Studierendenantragstatus_model::STATUS_APPROVED && $antrag->datum > $datumStatus)
return success(-2);
}
if ($studiensemester_kurzbz && $antrag->typ == Studierendenantrag_model::TYP_UNTERBRECHUNG)
if ($antrag->typ == Studierendenantrag_model::TYP_UNTERBRECHUNG)
{
// NOTE(chris): check if this is an old or canceled one
if ($antrag->studiensemester_kurzbz == $studiensemester_kurzbz && $antrag->status != Studierendenantragstatus_model::STATUS_CANCELLED)
return success(-1);
// NOTE(chris): Ignore canceled ones
if ($antrag->status == Studierendenantragstatus_model::STATUS_CANCELLED)
continue;
}
if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG)
{
@@ -1362,6 +1457,17 @@ class AntragLib
}
}
if (!$studiensemester_kurzbz) {
$sems = $this->getSemesterForUnterbrechung($prestudent_id, $prestudent_stdsem);
if (!count(array_filter($sems, function ($item) {
return !$item['disabled'];
})))
return success(-1);
} else {
if ($this->_ci->StudierendenantragModel->hasRunningUnterbrechungBetween($prestudent_id, $studiensemester_kurzbz, $datum_wiedereinstieg))
return success(-1);
}
return success(1);
}
@@ -1406,7 +1512,27 @@ class AntragLib
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG,
'campus.get_status_studierendenantrag(studierendenantrag_id)' => Studierendenantragstatus_model::STATUS_APPROVED
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_APPROVED
]);
if (isError($result))
return $result;
if (hasData($result))
return success(-1);
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG,
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_DEREGISTERED
]);
if (isError($result))
return $result;
if (hasData($result))
return success(-1);
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG,
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE
]);
if (isError($result))
return $result;
@@ -1457,15 +1583,16 @@ class AntragLib
return success($result);
}
/**
* Gets details for the latest Antrag of one or more types
*
* @param integer $prestudent_id
* @param array|string $typ
*
* @return \stdClass
*/
public function getDetailsForLastAntrag($prestudent_id, $typ = null)
{
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($prestudent_id);
if (isError($result))
return $result;
if (!hasData($result))
return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', ['prestudent_id' => $prestudent_id]));
$resultDetails = current(getData($result));
$where = [
'prestudent_id' => $prestudent_id
];
@@ -1494,21 +1621,20 @@ class AntragLib
'prestudent_id' => $prestudent_id
]));
$resultDetails->status = $resultAntrag->status;
$resultDetails->statustyp = $resultAntrag->statustyp;
$resultDetails->grund = $resultAntrag->grund;
$resultDetails->studierendenantrag_id = $resultAntrag->studierendenantrag_id;
$resultDetails->typ = $resultAntrag->typ;
$resultDetails->datum = $resultAntrag->datum;
$resultDetails->studiensemester_kurzbz = $resultAntrag->studiensemester_kurzbz;
return success($resultDetails);
return $this->addDetailsToAntrag($resultAntrag);
}
/**
* Gets details for a specific Antrag
*
* @param integer $studierendenantrag_id
*
* @return \stdClass
*/
public function getDetailsForAntrag($studierendenantrag_id)
{
$where = [
'studierendenantrag_id' => $studierendenantrag_id
's.studierendenantrag_id' => $studierendenantrag_id
];
$result = $this->_ci->StudierendenantragModel->loadWithStatusWhere($where);
@@ -1519,76 +1645,99 @@ class AntragLib
return error($this->_ci->p->t('studierendenantrag', "error_no_antrag_found", ['id' => $studierendenantrag_id]));
$resultAntrag = current(getData($result));
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($resultAntrag->prestudent_id, $resultAntrag->studiensemester_kurzbz);
return $this->addDetailsToAntrag($resultAntrag);
}
/**
* Helper function for getDetailsForAntrag and getDetailsForLastAntrag
*
* @param \stdClass $antrag
*
* @return \stdClass
*/
protected function addDetailsToAntrag($antrag)
{
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails(
$antrag->prestudent_id,
$antrag->studiensemester_kurzbz,
$antrag->insertamum
);
if (isError($result))
return $result;
if (!hasData($result)) {
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails($resultAntrag->prestudent_id);
$result = $this->_ci->PrestudentstatusModel->loadLastWithStgDetails(
$antrag->prestudent_id,
null,
$antrag->insertamum
);
if (isError($result))
return $result;
if (!hasData($result))
return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudentstatus', $resultAntrag));
return error($this->_ci->p->t('studierendenantrag', 'error_no_prestudent_in_sem', $antrag));
$tmp = current(getData($result));
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$res = $this->_ci->StudiensemesterModel->load($antrag->studiensemester_kurzbz);
if (hasData($res))
$tmp->studienjahr_kurzbz = current(getData($res))->studienjahr_kurzbz;
else
$tmp->studienjahr_kurzbz = '';
// NOTE(chris): the semester might not be correct on this fallback so we disable it
$tmp->semester = '';
}
$resultDetails = current(getData($result));
$resultDetails->status = $resultAntrag->status;
$resultDetails->statustyp = $resultAntrag->statustyp;
$resultDetails->grund = $resultAntrag->grund;
$resultDetails->studierendenantrag_id = $resultAntrag->studierendenantrag_id;
$resultDetails->typ = $resultAntrag->typ;
$resultDetails->dms_id = $resultAntrag->dms_id;
$resultDetails->datum_wiedereinstieg = $resultAntrag->datum_wiedereinstieg;
$result = current(getData($result));
return success($resultDetails);
$result->status = $antrag->status;
$result->statustyp = $antrag->statustyp;
$result->status_insertvon = $antrag->status_insertvon;
$result->grund = $antrag->grund;
$result->studierendenantrag_id = $antrag->studierendenantrag_id;
$result->typ = $antrag->typ;
$result->datum = $antrag->datum;
$result->dms_id = $antrag->dms_id;
$result->datum_wiedereinstieg = $antrag->datum_wiedereinstieg;
return success($result);
}
public function getSemesterForUnterbrechung($studiensemester_kurzbz)
/**
* Rearrange the free semester slots for a new Unterbrechung
*
* @param integer $prestudent_id
* @param string $studiensemester_kurzbz
*
* @return array
*/
public function getSemesterForUnterbrechung($prestudent_id, $studiensemester_kurzbz)
{
$this->_ci->load->model('organisation/Studiensemester_model', 'StudiensemesterModel');
$semester = [];
$result = $this->_ci->StudiensemesterModel->getNextFrom($studiensemester_kurzbz);
if (!hasData($result))
return $semester;
$nextSem = current(getData($result));
$semester[0] = [
'studiensemester_kurzbz' => $studiensemester_kurzbz,
'wiedereinstieg' => [$nextSem]
];
$result = $this->_ci->StudiensemesterModel->getNextFrom($nextSem->studiensemester_kurzbz);
if (!hasData($result))
return $semester;
$currSemester = current(getData($result));
$followingSemester = [$currSemester];
$max = $this->_ci->config->item('unterbrecher_semester_max_length');
if(!$max || $max < 1)
$max = 2;
for ($i = 1; $i < $max; $i++) {
$result = $this->_ci->StudiensemesterModel->getNextFrom($currSemester->studiensemester_kurzbz);
if (!hasData($result))
break;
$currSemester = current(getData($result));
$followingSemester[] = $currSemester;
}
$semester[1] = [
'studiensemester_kurzbz' => $nextSem->studiensemester_kurzbz,
'wiedereinstieg' => $followingSemester
];
//remove last Semester of the array
array_pop($followingSemester);
foreach ($followingSemester as $sem)
$semester[0]['wiedereinstieg'][] = $sem;
return $semester;
$result = $this->_ci->StudierendenantragModel->getFreeSlotsForUnterbrechung($prestudent_id, $studiensemester_kurzbz);
if (isError($result))
return [];
$result = getData($result);
if (!$result)
return [];
return array_reduce($result, function ($carry, $item) {
if (!isset($carry[$item->von]))
$carry[$item->von] = [
'studienjahr_kurzbz' => $item->studienjahr_kurzbz,
'studiensemester_kurzbz' => $item->von,
'wiedereinstieg' => [],
'disabled' => true
];
$carry[$item->von]['wiedereinstieg'][] = [
'studiensemester_kurzbz' => $item->bis,
'start' => $item->ende,
'disabled' => (boolean)$item->studierendenantrag_id
];
if ($carry[$item->von]['disabled'] && !$item->studierendenantrag_id) {
$carry[$item->von]['disabled'] = false;
}
return $carry;
}, []);
return $result;
}
public function getAktivePrestudentenInStgs($studiengaenge, $query)
@@ -1664,7 +1813,6 @@ class AntragLib
return error($this->_ci->p->t('studierendenantrag', 'error_no_stg_antrag', ['id' => $antrag_id]));
$stg = current($result);
$studiengang_kz = $stg->studiengang_kz;
$semester = $stg->ausbildungssemester;
$result = $this->_ci->StudierendenantragModel->load($antrag_id);
@@ -1726,9 +1874,7 @@ class AntragLib
$result = $this->getLvsForAntrag($antrag_id);
if (hasData($result)) {
$lvs = getData($result);
$repeat_last = false;
if (isset($lvs['repeat_last'])) {
$repeat_last = true;
unset($lvs['repeat_last']);
$vorlage .= '_Lst';
}
@@ -1895,6 +2041,26 @@ class AntragLib
return $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag');
}
/**
* @param integer $antrag_id
*
* @return boolean
*/
public function isEntitledToPauseAntrag($antrag_id)
{
return ($this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe') || $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag'));
}
/**
* @param integer $antrag_id
*
* @return boolean
*/
public function isEntitledToUnpauseAntrag($antrag_id)
{
return $this->hasAccessToAntrag($antrag_id, 'student/studierendenantrag');
}
/**
* @param integer $antrag_id
*
@@ -1935,6 +2101,36 @@ class AntragLib
return $this->hasAccessToAntrag($antrag_id, 'student/antragfreigabe');
}
/**
* @param integer $antrag_id
*
* @return boolean
*/
public function antragCanBeManualPaused($antrag_id)
{
$this->_ci->StudierendenantragModel->db->where_not_in('campus.get_status_studierendenantrag(studierendenantrag_id)', [
Studierendenantragstatus_model::STATUS_DEREGISTERED,
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_PAUSE
]);
$result = $this->_ci->StudierendenantragModel->loadWhere([
'studierendenantrag_id' => $antrag_id,
'typ' => Studierendenantrag_model::TYP_WIEDERHOLUNG
]);
return hasData($result);
}
/**
* @param integer $antrag_id
*
* @return boolean
*/
public function antragCanBeManualUnpaused($antrag_id)
{
return $this->_ci->StudierendenantragModel->isManuallyPaused($antrag_id);
}
/**
* @param integer $antrag_id
* @param string|array $status
@@ -247,7 +247,7 @@ EOTXT;
$this->validationerrors[] = 'Das Beginndatum muss vor dem Endedatum liegen.';
}
if( $this->checkoverlap && !($this->vertragsart_kurzbz === 'werkvertrag')
if( $this->checkoverlap && !(in_array($this->vertragsart_kurzbz, array('werkvertrag', 'studentischehilfskr')) )
&& $ci->VertragsbestandteilLib->isOverlappingExistingDV($this) )
{
$this->validationerrors[] = 'Es existiert bereits ein überlappendes Dienstverhältnis';
@@ -26,30 +26,35 @@ class VertragsbestandteilLib
{
const INCLUDE_FUTURE = true;
const DO_NOT_INCLUDE_FUTURE = false;
protected $CI;
/** @var Dienstverhaeltnis_model */
protected $DienstverhaeltnisModel;
/** @var Vertragsbestandteil_model */
protected $VertragsbestandteilModel;
/**
/** @var Benutzer_model */
protected $BenutzerModel;
/**
* @var GehaltsbestandteilLib
*/
protected $GehaltsbestandteilLib;
protected $loggedInUser;
public function __construct()
{
$this->loggedInUser = getAuthUID();
$this->CI = get_instance();
$this->CI->load->model('vertragsbestandteil/Dienstverhaeltnis_model',
$this->CI->load->model('vertragsbestandteil/Dienstverhaeltnis_model',
'DienstverhaeltnisModel');
$this->DienstverhaeltnisModel = $this->CI->DienstverhaeltnisModel;
$this->CI->load->model('vertragsbestandteil/Vertragsbestandteil_model',
$this->CI->load->model('vertragsbestandteil/Vertragsbestandteil_model',
'VertragsbestandteilModel');
$this->VertragsbestandteilModel = $this->CI->VertragsbestandteilModel;
$this->CI->load->library('vertragsbestandteil/GehaltsbestandteilLib',
$this->CI->load->model('person/benutzer_model',
'BenutzerModel');
$this->BenutzerModel = $this->CI->BenutzerModel;
$this->CI->load->library('vertragsbestandteil/GehaltsbestandteilLib',
null, 'GehaltsbestandteilLib');
$this->GehaltsbestandteilLib = $this->CI->GehaltsbestandteilLib;
}
@@ -63,49 +68,54 @@ class VertragsbestandteilLib
} catch (Exception $ex)
{
log_message('debug', "Error handling json data from GUI. " . $ex->getMessage());
}
}
return $ret;
}
public function fetchDienstverhaeltnisse($unternehmen, $stichtag=null, $mitarbeiteruid=null) {
$dvs = $this->DienstverhaeltnisModel->fetchDienstverhaeltnisse($unternehmen, $stichtag, $mitarbeiteruid);
return $dvs;
}
public function fetchDienstverhaeltnis($dienstverhaeltnis_id)
{
$result = $this->DienstverhaeltnisModel->load($dienstverhaeltnis_id);
$dv = null;
if(null !== ($row = getData($result)))
if(null !== ($row = getData($result)))
{
$dv = new Dienstverhaeltnis();
$dv->hydrateByStdClass($row[0], true);
}
return $dv;
}
public function fetchVertragsbestandteile($dienstverhaeltnis_id, $stichtag=null, $includefuture=false)
{
$vbs = $this->VertragsbestandteilModel->getVertragsbestandteile($dienstverhaeltnis_id, $stichtag, $includefuture);
$gbs = $this->GehaltsbestandteilLib->fetchGehaltsbestandteile($dienstverhaeltnis_id, $stichtag, $includefuture);
$gbsByVBid = array();
foreach( $gbs as $gb )
foreach( $gbs as $gb )
{
if( intval($gb->getVertragsbestandteil_id()) > 0 )
if( intval($gb->getVertragsbestandteil_id()) > 0 )
{
if( !isset($gbsByVBid[$gb->getVertragsbestandteil_id()])
if( !isset($gbsByVBid[$gb->getVertragsbestandteil_id()])
|| !is_array($gbsByVBid[$gb->getVertragsbestandteil_id()]) ) {
$gbsByVBid[$gb->getVertragsbestandteil_id()] = array();
}
$gbsByVBid[$gb->getVertragsbestandteil_id()][] = $gb;
}
}
foreach ($vbs as $vb)
{
if( isset($gbsByVBid[$vb->getVertragsbestandteil_id()]) )
if( isset($gbsByVBid[$vb->getVertragsbestandteil_id()]) )
{
$vb->setGehaltsbestandteile($gbsByVBid[$vb->getVertragsbestandteil_id()]);
}
}
return $vbs;
}
@@ -113,22 +123,22 @@ class VertragsbestandteilLib
{
return $this->VertragsbestandteilModel->getVertragsbestandteil($vertragsbestandteil_id);
}
public function storeDienstverhaeltnis(Dienstverhaeltnis $dv)
{
if( intval($dv->getDienstverhaeltnis_id()) > 0 )
{
$this->updateDienstverhaeltnis($dv);
}
else
else
{
$this->insertDienstverhaeltnis($dv);
$this->insertDienstverhaeltnis($dv);
}
}
public function storeVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil)
public function storeVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil)
{
$this->CI->db->trans_begin();
$this->CI->db->trans_begin();
try
{
$this->setUIDtoPGSQL();
@@ -144,7 +154,7 @@ class VertragsbestandteilLib
{
log_message('debug', "Transaction failed");
throw new Exception("Transaction failed");
}
}
$this->CI->db->trans_commit();
}
catch (Exception $ex)
@@ -152,7 +162,7 @@ class VertragsbestandteilLib
log_message('debug', "Transaction rolled back. " . $ex->getMessage());
$this->CI->db->trans_rollback();
throw new Exception('Storing Vertragsbestandteil failed.');
}
}
}
public function deleteDienstverhaeltnis(Dienstverhaeltnis $dv)
@@ -220,13 +230,13 @@ class VertragsbestandteilLib
throw new Exception('Delete Vertragsbestandteil failed.');
}
}
protected function insertDienstverhaeltnis(Dienstverhaeltnis $dv)
{
$dv->setInsertvon($this->loggedInUser)
->setInsertamum(strftime('%Y-%m-%d %H:%M:%S'));
$ret = $this->DienstverhaeltnisModel->insert($dv->toStdClass());
if( hasData($ret) )
if( hasData($ret) )
{
$dv->setDienstverhaeltnis_id(getData($ret));
}
@@ -235,14 +245,14 @@ class VertragsbestandteilLib
throw new Exception('error inserting dienstverhaeltnis');
}
}
protected function insertVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil)
{
$vertragsbestandteil->setInsertvon($this->loggedInUser)
->setInsertamum(strftime('%Y-%m-%d %H:%M:%S'));
$vertragsbestandteil->beforePersist();
$ret = $this->VertragsbestandteilModel->insert($vertragsbestandteil->baseToStdClass());
if( hasData($ret) )
if( hasData($ret) )
{
$vertragsbestandteil->setVertragsbestandteil_id(getData($ret));
}
@@ -254,19 +264,19 @@ class VertragsbestandteilLib
$specialisedModel = VertragsbestandteilFactory::getVertragsbestandteilDBModel(
$vertragsbestandteil->getVertragsbestandteiltyp_kurzbz());
$retspecial = $specialisedModel->insert($vertragsbestandteil->toStdClass());
if(isError($retspecial) )
{
throw new Exception('error updating vertragsbestandteil '
throw new Exception('error updating vertragsbestandteil '
. $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz());
}
try
try
{
$gehaltsbestandteile = $vertragsbestandteil->getGehaltsbestandteile();
$this->GehaltsbestandteilLib->storeGehaltsbestandteile($gehaltsbestandteile);
}
catch(Exception $ex)
}
catch(Exception $ex)
{
throw new Exception('VertragsbestandteilLib insertVertragsbestandteil '
. 'failed to store Gehaltsbestandteile. ' . $ex->getMessage());
@@ -278,7 +288,7 @@ class VertragsbestandteilLib
if(!$dv->isDirty()) {
return;
}
$dv->setUpdatevon($this->loggedInUser)
->setUpdateamum(strftime('%Y-%m-%d %H:%M:%S'));
$ret = $this->DienstverhaeltnisModel->update($dv->getDienstverhaeltnis_id(),
@@ -288,20 +298,20 @@ class VertragsbestandteilLib
throw new Exception('error updating dienstverhaeltnis');
}
}
private function deleteVertragsbestandteilHelper(Vertragsbestandteil $vertragsbestandteil)
{
$specialisedModel = VertragsbestandteilFactory::getVertragsbestandteilDBModel(
$vertragsbestandteil->getVertragsbestandteiltyp_kurzbz());
$retspecial = $specialisedModel->delete($vertragsbestandteil->getVertragsbestandteil_id());
if(isError($retspecial) )
{
throw new Exception('error deleting vertragsbestandteil '
. $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz());
}
try
{
$gehaltsbestandteile = $vertragsbestandteil->getGehaltsbestandteile();
@@ -320,76 +330,118 @@ class VertragsbestandteilLib
{
throw new Exception('error deleting vertragsbestandteil');
}
$vertragsbestandteil->afterDelete();
}
protected function updateVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil)
{
if($vertragsbestandteil->isDirty()) {
if($vertragsbestandteil->isDirty()) {
$vertragsbestandteil->setUpdatevon($this->loggedInUser)
->setUpdateamum(strftime('%Y-%m-%d %H:%M:%S'));
$vertragsbestandteil->beforePersist();
$basedata = $vertragsbestandteil->baseToStdClass();
if( count((array) $basedata) > 0 )
if( count((array) $basedata) > 0 )
{
$ret = $this->VertragsbestandteilModel->update(
$vertragsbestandteil->getVertragsbestandteil_id(),
$vertragsbestandteil->getVertragsbestandteil_id(),
$basedata);
if(isError($ret) )
{
throw new Exception('error updating vertragsbestandteil');
}
}
}
$specialisedData = $vertragsbestandteil->toStdClass();
if( count((array) $specialisedData) > 0 )
if( count((array) $specialisedData) > 0 )
{
$specialisedModel = VertragsbestandteilFactory::getVertragsbestandteilDBModel(
$vertragsbestandteil->getVertragsbestandteiltyp_kurzbz());
$retspecial = $specialisedModel->update(
$vertragsbestandteil->getVertragsbestandteil_id(),
$vertragsbestandteil->getVertragsbestandteil_id(),
$specialisedData);
if(isError($retspecial) )
{
throw new Exception('error updating vertragsbestandteil '
throw new Exception('error updating vertragsbestandteil '
. $vertragsbestandteil->getVertragsbestandteiltyp_kurzbz());
}
}
}
try
try
{
$gehaltsbestandteile = $vertragsbestandteil->getGehaltsbestandteile();
$this->GehaltsbestandteilLib->storeGehaltsbestandteile($gehaltsbestandteile);
}
catch(Exception $ex)
}
catch(Exception $ex)
{
throw new Exception('VertragsbestandteilLib updateVertragsbestandteil '
. 'failed to store Gehaltsbestandteile. ' . $ex->getMessage());
}
}
public function isOverlappingExistingDV(Dienstverhaeltnis $dv)
public function isOverlappingExistingDV(Dienstverhaeltnis $dv)
{
return $this->DienstverhaeltnisModel->isOverlappingExistingDV(
$dv->getMitarbeiter_uid(),
$dv->getOe_kurzbz(),
$dv->getVon(),
$dv->getMitarbeiter_uid(),
$dv->getOe_kurzbz(),
$dv->getVon(),
$dv->getBis(),
$dv->getDienstverhaeltnis_id()
);
}
protected function hasOtherActiveDV(Dienstverhaeltnis $dv, $duedate)
{
$hasotheractivedv = false;
$result = $this->DienstverhaeltnisModel->getDVByPersonUID($dv->getMitarbeiter_uid(), null, $duedate);
$dvs = getData($result);
foreach ($dvs as $tmpdv)
{
if(intval($tmpdv->dienstverhaeltnis_id) !== intval($dv->getDienstverhaeltnis_id()))
{
$hasotheractivedv = true;
break;
}
}
return $hasotheractivedv;
}
/**
* like endDienstverhaeltnis, but also sets aktiv flag to false
*/
public function deactivateDienstverhaeltnis(Dienstverhaeltnis $dv, $enddate, $deactivate)
{
$result = $this->endDienstverhaeltnis($dv, $enddate);
if ( $result === true)
{
if (!$deactivate) return $result;
if(!$this->hasOtherActiveDV($dv, $enddate))
{
$result = $this->BenutzerModel->update(
array('uid' => $dv->getMitarbeiter_uid()),
array(
'aktiv' => false,
'updateaktivam' => date('Y-m-d'),
'updateaktivvon' => $this->loggedInUser
)
);
}
}
return $result;
}
public function endDienstverhaeltnis(Dienstverhaeltnis $dv, $enddate)
{
if( $dv->getBis() !== null && $dv->getBis() < $enddate )
if( $dv->getBis() !== null && $dv->getBis() < $enddate )
{
return 'Dienstverhältnis ist bereits beendet.';
}
$this->CI->db->trans_begin();
try
{
@@ -401,13 +453,13 @@ class VertragsbestandteilLib
{
$this->GehaltsbestandteilLib->endGehaltsbestandteil($gb, $enddate);
}
$vbs = $this->fetchVertragsbestandteile($dv->getDienstverhaeltnis_id());
foreach ($vbs as $vb)
{
$this->endVertragsbestandteil($vb, $enddate);
}
}
$dv->setBis($enddate);
$this->updateDienstverhaeltnis($dv);
@@ -428,23 +480,23 @@ class VertragsbestandteilLib
}
return true;
}
public function endVertragsbestandteil(Vertragsbestandteil $vertragsbestandteil, $enddate)
{
if( $vertragsbestandteil->getBis() !== null && $vertragsbestandteil->getBis() < $enddate )
if( $vertragsbestandteil->getBis() !== null && $vertragsbestandteil->getBis() < $enddate )
{
return;
}
$vertragsbestandteil->setBis($enddate);
$this->updateVertragsbestandteil($vertragsbestandteil);
}
protected function setUIDtoPGSQL() {
$ret = $this->VertragsbestandteilModel
->execReadOnlyQuery('SET LOCAL pv21.uid TO \''
->execReadOnlyQuery('SET LOCAL pv21.uid TO \''
. $this->loggedInUser . '\'');
if(isError($ret))
if(isError($ret))
{
throw new Exception('error setting uid to pgsql');
}
@@ -11,4 +11,25 @@ class Bismeldestichtag_model extends DB_Model
$this->dbTable = 'bis.tbl_bismeldestichtag';
$this->pk = 'meldestichtag_id';
}
/**
* Gets last Bismeldestichtag for a Studiensemester.
* @param $studiensemester_kurzbz
* @return object success or error
*/
public function getByStudiensemester($studiensemester_kurzbz)
{
$query = '
SELECT
meldestichtag
FROM
bis.tbl_bismeldestichtag
JOIN public.tbl_studiensemester USING (studiensemester_kurzbz)
WHERE
studiensemester_kurzbz = ?
ORDER BY meldestichtag DESC
LIMIT 1';
return $this->execQuery($query, array($studiensemester_kurzbz));
}
}
@@ -267,7 +267,7 @@ class Prestudentstatus_model extends DB_Model
return $this->loadWhere($where);
}
public function loadLastWithStgDetails($prestudent_id, $studiensemester_kurzbz = null)
public function loadLastWithStgDetails($prestudent_id, $studiensemester_kurzbz = null, $max_date = null)
{
$this->load->config('studierendenantrag');
@@ -304,7 +304,8 @@ class Prestudentstatus_model extends DB_Model
$this->addLimit(1);
$this->db->where_in($this->dbTable . '.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist'));
if ($max_date)
$this->db->where($this->dbTable . '.insertamum <', $max_date);
$whereArr = [
$this->dbTable . '.prestudent_id' => $prestudent_id,
@@ -87,7 +87,13 @@ class Pruefung_model extends DB_Model
$this->addJoin('public.tbl_person pers', 'person_id');
$this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
$this->addJoin('public.tbl_studiengang g', 'ps.studiengang_kz=g.studiengang_kz');
$this->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id=ps.prestudent_id AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', 'LEFT');
$this->addJoin(
'public.tbl_prestudentstatus pss',
'pss.prestudent_id=ps.prestudent_id
AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz
AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)',
'LEFT'
);
$this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT');
$this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz');
$this->db->join('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ = ?', 'LEFT', false);
@@ -167,6 +173,7 @@ class Pruefung_model extends DB_Model
$this->addSelect('a.studierendenantrag_id');
$this->addSelect('a.typ');
$this->addSelect('campus.get_status_studierendenantrag(a.studierendenantrag_id) status');
$this->addSelect('pss.ausbildungssemester');
$this->addJoin('lehre.tbl_lehreinheit le', 'lehreinheit_id');
$this->addJoin('lehre.tbl_lehrveranstaltung lv', 'lehrveranstaltung_id');
@@ -175,12 +182,20 @@ class Pruefung_model extends DB_Model
$this->addJoin('public.tbl_person pers', 'person_id');
$this->addJoin('public.tbl_benutzer b', 's.student_uid=b.uid');
$this->addJoin('public.tbl_studiengang g', 'ps.studiengang_kz=g.studiengang_kz');
$this->addJoin('public.tbl_prestudentstatus pss', 'pss.prestudent_id=ps.prestudent_id AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)', 'LEFT');
$this->addJoin(
'public.tbl_prestudentstatus pss',
'pss.prestudent_id=ps.prestudent_id
AND pss.studiensemester_kurzbz=le.studiensemester_kurzbz
AND pss.status_kurzbz=get_rolle_prestudent(ps.prestudent_id, le.studiensemester_kurzbz)',
'LEFT'
);
$this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT');
$this->addJoin('bis.tbl_orgform o', 'COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, g.orgform_kurzbz)=o.orgform_kurzbz');
$this->addJoin('campus.tbl_studierendenantrag a', 'ps.prestudent_id=a.prestudent_id and a.typ=' . $this->escape(Studierendenantrag_model::TYP_WIEDERHOLUNG), 'LEFT');
$this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist'));
$this->addJoin(
'campus.tbl_studierendenantrag a',
'ps.prestudent_id=a.prestudent_id and a.typ=' . $this->escape(Studierendenantrag_model::TYP_WIEDERHOLUNG),
'LEFT'
);
$this->db->where("g.aktiv", true);
@@ -238,6 +253,8 @@ class Pruefung_model extends DB_Model
$this->db->where("b.aktiv", true);
$this->db->where_in("get_rolle_prestudent(ps.prestudent_id, null)", $this->config->item('antrag_prestudentstatus_whitelist'));
if (is_array($status)) {
if (in_array(null, $status)) {
$status = array_filter($status);
@@ -46,6 +46,8 @@ class Studierendenantrag_model extends DB_Model
$this->addSelect('datum_wiedereinstieg');
$this->addSelect($this->dbTable . '.typ');
$this->addSelect('st.studierendenantrag_statustyp_kurzbz as status');
$this->addSelect('s.insertvon as status_insertvon');
$this->addSelect('s.insertamum as status_insertamum');
$this->addSelect('dms_id');
$this->addSelect('st.bezeichnung[(' . $sql . ')] as statustyp');
@@ -54,7 +56,13 @@ class Studierendenantrag_model extends DB_Model
$this->addJoin('public.tbl_person', 'person_id');
$this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz');
$this->addJoin('public.tbl_studiensemester ss', 'studiensemester_kurzbz');
$this->addJoin('public.tbl_prestudentstatus ps', 'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=ss.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ss.studiensemester_kurzbz)', 'LEFT');
$this->addJoin(
'public.tbl_prestudentstatus ps',
'ps.prestudent_id=p.prestudent_id
AND ps.studiensemester_kurzbz=ss.studiensemester_kurzbz
AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ss.studiensemester_kurzbz)',
'LEFT'
);
$this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT');
$this->addJoin('bis.tbl_orgform of', 'of.orgform_kurzbz=COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, stg.orgform_kurzbz)');
$this->addJoin(
@@ -76,7 +84,9 @@ class Studierendenantrag_model extends DB_Model
public function loadActiveForStudiengaenge($studiengaenge)
{
// NOTE(chris): get language before changing things in the global db object because getUserLanguage() might use it and it should not have been tampered with
// NOTE(chris): get language before changing things in the global
// db object because getUserLanguage() might use it and it should
// not have been tampered with
$sql = "SELECT index FROM public.tbl_sprache WHERE sprache='" . getUserLanguage() . "' LIMIT 1";
$this->db->group_start();
@@ -85,7 +95,8 @@ class Studierendenantrag_model extends DB_Model
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_REJECTED,
Studierendenantragstatus_model::STATUS_OBJECTION_DENIED,
Studierendenantragstatus_model::STATUS_DEREGISTERED
Studierendenantragstatus_model::STATUS_DEREGISTERED,
Studierendenantragstatus_model::STATUS_PAUSE
]);
$this->db->or_group_start();
$this->db->where('s.studierendenantrag_statustyp_kurzbz', Studierendenantragstatus_model::STATUS_APPROVED);
@@ -133,12 +144,18 @@ class Studierendenantrag_model extends DB_Model
$lang = 'SELECT index FROM public.tbl_sprache WHERE sprache=' . $this->escape(getUserLanguage());
$this->addSelect('*');
$this->addSelect('campus.get_status_studierendenantrag(studierendenantrag_id) status');
$this->addSelect($this->dbTable . '.grund AS grund');
$this->addSelect('s.studierendenantrag_statustyp_kurzbz status');
$this->addSelect('s.insertvon status_insertvon');
$this->addSelect('t.bezeichnung[(' . $lang . ')] statustyp');
$this->addJoin(
'campus.tbl_studierendenantrag_status s',
'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id'
);
$this->addJoin(
'campus.tbl_studierendenantrag_statustyp t',
'campus.get_status_studierendenantrag(studierendenantrag_id)=t.studierendenantrag_statustyp_kurzbz'
's.studierendenantrag_statustyp_kurzbz=t.studierendenantrag_statustyp_kurzbz'
);
if ($types && is_array($types)) {
@@ -168,7 +185,11 @@ class Studierendenantrag_model extends DB_Model
$this->addJoin(
'public.tbl_prestudentstatus s',
$this->dbTable . '.prestudent_id=s.prestudent_id AND ' . $this->dbTable . '.studiensemester_kurzbz=s.studiensemester_kurzbz'
$this->dbTable . '.prestudent_id=s.prestudent_id
AND ' .
$this->dbTable . '.studiensemester_kurzbz=s.studiensemester_kurzbz
AND ' .
$this->dbTable . '.insertamum > s.insertamum'
);
$this->addJoin('public.tbl_prestudent p', $this->dbTable . '.prestudent_id=p.prestudent_id');
$this->addJoin('public.tbl_studiengang stg', 'studiengang_kz', 'LEFT');
@@ -180,8 +201,6 @@ class Studierendenantrag_model extends DB_Model
$this->addLimit(1);
$this->db->where_in('s.status_kurzbz', $this->config->item('antrag_prestudentstatus_whitelist'));
return $this->loadWhere([
$this->pk => $antrag_id
]);
@@ -233,20 +252,45 @@ class Studierendenantrag_model extends DB_Model
$this->addSelect($this->dbTable . '.datum_wiedereinstieg');
$this->addSelect($this->dbTable . '.grund');
$this->addSelect($this->dbTable . '.dms_id');
$this->addSelect("(SELECT count(1) FROM campus.tbl_studierendenantrag_status WHERE studierendenantrag_id = " . $this->dbTable . ".studierendenantrag_id AND studierendenantrag_statustyp_kurzbz = 'Genehmigt') AS isapproved", false);
$this->addSelect('s.insertvon AS status_insertvon');
$this->addSelect(
"(SELECT count(1) FROM campus.tbl_studierendenantrag_status WHERE studierendenantrag_id = " .
$this->dbTable .
".studierendenantrag_id AND studierendenantrag_statustyp_kurzbz = 'Genehmigt') AS isapproved",
false
);
$this->addJoin('public.tbl_prestudent p', 'prestudent_id', 'RIGHT');
$this->addJoin('public.tbl_studiengang stg', 'p.studiengang_kz=stg.studiengang_kz');
$this->addJoin('public.tbl_prestudentstatus ps', 'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=' . $this->dbTable . '.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ' . $this->dbTable . '.studiensemester_kurzbz)', 'LEFT');
$this->addJoin(
'public.tbl_prestudentstatus ps',
'ps.prestudent_id=p.prestudent_id AND ps.studiensemester_kurzbz=' .
$this->dbTable .
'.studiensemester_kurzbz AND ps.status_kurzbz=get_rolle_prestudent(p.prestudent_id, ' .
$this->dbTable .
'.studiensemester_kurzbz)',
'LEFT'
);
$this->addJoin('lehre.tbl_studienplan plan', 'studienplan_id', 'LEFT');
$this->addJoin('bis.tbl_orgform of', 'of.orgform_kurzbz=COALESCE(plan.orgform_kurzbz, ps.orgform_kurzbz, stg.orgform_kurzbz)');
$this->addJoin(
'campus.tbl_studierendenantrag_status s',
'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id',
'LEFT'
);
$this->addJoin(
'campus.tbl_studierendenantrag_statustyp st',
'campus.get_status_studierendenantrag(studierendenantrag_id)=st.studierendenantrag_statustyp_kurzbz',
's.studierendenantrag_statustyp_kurzbz=st.studierendenantrag_statustyp_kurzbz',
'LEFT'
);
$this->db->where("(SELECT status_kurzbz FROM public.tbl_prestudentstatus WHERE prestudent_id=p.prestudent_id AND status_kurzbz='Student' LIMIT 1) IS NOT NULL", null, false);
$this->db->where("(
SELECT status_kurzbz
FROM public.tbl_prestudentstatus
WHERE prestudent_id=p.prestudent_id
AND status_kurzbz='Student'
LIMIT 1
) IS NOT NULL", null, false);
return $this->loadWhere([
@@ -287,4 +331,144 @@ class Studierendenantrag_model extends DB_Model
return $this->loadWhere($where);
}
/**
* Checks if the Prestudent has an active Unterbrechung between
* the start of the given semester and the given enddate.
* If the enddate is omitted the end of the given semester is used.
*
* @param integer $prestudent_id
* @param string $studiensemester_kurzbz
* @param string $enddate (optional)
*
* @return boolean
*/
public function hasRunningUnterbrechungBetween($prestudent_id, $studiensemester, $enddate = null)
{
$start = '(SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=' . $this->db->escape($studiensemester) . ')';
$end = $enddate
? $this->db->escape($enddate)
: '(SELECT ende FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=' . $this->db->escape($studiensemester) . ')';
$this->addJoin('public.tbl_studiensemester', 'studiensemester_kurzbz');
$this->db->where([
'prestudent_id' => $prestudent_id,
'typ' => Studierendenantrag_model::TYP_UNTERBRECHUNG,
'campus.get_status_studierendenantrag(studierendenantrag_id) !=' => Studierendenantragstatus_model::STATUS_CANCELLED,
'start < ' . $end => null,
'datum_wiedereinstieg > ' . $start => null,
]);
return (boolean)$this->db->count_all_results($this->dbTable);
}
/**
* Gets free semester slots for a new Unterbrechung.
*
* @param integer $prestudent_id
* @param string $studiensemester_kurzbz (optional)
*
* @return stdClass
*/
public function getFreeSlotsForUnterbrechung($prestudent_id, $studiensemester = null)
{
$max_starters = 2;
$max_length = max(
2,
(integer)$this->config->item('unterbrecher_semester_max_length')
);
$subquery = '';
if ($studiensemester)
$subquery = 'SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=?';
else
$subquery = 'SELECT start FROM public.tbl_studiensemester WHERE studiensemester_kurzbz=public.get_stdsem_prestudent (?, null)';
$sql = "WITH numbered_sems AS (
SELECT
a.studienjahr_kurzbz AS studienjahr_kurzbz,
a.studiensemester_kurzbz AS von,
b.studiensemester_kurzbz AS bis,
a.start AS start,
b.start AS ende,
ROW_NUMBER() OVER (
PARTITION BY a.studiensemester_kurzbz
ORDER BY b.start
) AS row_number
FROM public.tbl_studiensemester a
LEFT JOIN public.tbl_studiensemester b ON (b.start > a.ende)
),
last_sems AS (
SELECT *
FROM numbered_sems
WHERE numbered_sems.row_number <= ?
)
SELECT s.von, s.bis, s.start, s.ende, studierendenantrag_id, studienjahr_kurzbz
FROM last_sems s
LEFT JOIN (
SELECT studierendenantrag_id, start, datum_wiedereinstieg AS ende
FROM campus.tbl_studierendenantrag
LEFT JOIN public.tbl_studiensemester USING(studiensemester_kurzbz)
WHERE typ=?
AND campus.get_status_studierendenantrag(studierendenantrag_id) != ?
AND prestudent_id=?
) a ON (s.start < a.ende AND s.ende > a.start)
WHERE s.start >= (" . $subquery . ")
ORDER BY s.start, s.ende
LIMIT ?;";
return $this->execQuery($sql, [
$max_length,
self::TYP_UNTERBRECHUNG,
Studierendenantragstatus_model::STATUS_CANCELLED,
$prestudent_id,
$studiensemester ?: $prestudent_id,
$max_length * $max_starters
]);
}
/**
* Returns if an Antrag is manually paused
*
* @param integer $antrag_id
*
* @return boolean
*/
public function isManuallyPaused($antrag_id)
{
$this->addJoin(
'campus.tbl_studierendenantrag_status s',
'campus.get_status_id_studierendenantrag(' . $this->dbTable . '.studierendenantrag_id)=s.studierendenantrag_status_id'
);
$this->db->where([
's.studierendenantrag_id' => $antrag_id,
's.studierendenantrag_statustyp_kurzbz' => Studierendenantragstatus_model::STATUS_PAUSE
]);
$this->db->group_start();
$this->db->where_not_in('s.insertvon', [
Studierendenantragstatus_model::INSERTVON_DEREGISTERED,
Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL
]);
$this->db->or_group_start();
$this->db->where('s.insertvon', Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL);
$this->db->where('1 !=', '(
SELECT COUNT(*)%2
FROM campus.tbl_studierendenantrag_status i
WHERE i.studierendenantrag_id = s.studierendenantrag_id
AND i.insertamum > (
SELECT ii.insertamum
FROM campus.tbl_studierendenantrag_status ii
WHERE ii.studierendenantrag_id = s.studierendenantrag_id
AND ii.insertvon <> ' . $this->escape(Studierendenantragstatus_model::INSERTVON_ABMELDUNGSTGL) . '
ORDER BY ii.insertamum DESC
LIMIT 1
)
)', false);
$this->db->group_end();
$this->db->group_end();
return hasData($this->load());
}
}
@@ -15,6 +15,10 @@ class Studierendenantragstatus_model extends DB_Model
const STATUS_OBJECTED = 'Beeinsprucht';
const STATUS_OBJECTION_DENIED = 'EinspruchAbgelehnt';
const STATUS_DEREGISTERED = 'Abgemeldet';
const STATUS_PAUSE = 'Pause';
const INSERTVON_ABMELDUNGSTGL = "AbmeldungStgl";
const INSERTVON_DEREGISTERED = "Studienabbruch";
/**
* Constructor
@@ -49,4 +53,157 @@ class Studierendenantragstatus_model extends DB_Model
return $this->loadWhere($where);
}
public function stopAntraegeForAbmeldungStgl($antrag_id)
{
$sql = 'INSERT INTO campus.tbl_studierendenantrag_status
(studierendenantrag_id, studierendenantrag_statustyp_kurzbz, insertvon, insertamum)
SELECT studierendenantrag_id, ?, ?, (
SELECT insertamum
FROM campus.tbl_studierendenantrag_status
WHERE studierendenantrag_status_id = campus.get_status_id_studierendenantrag(?)
)
FROM campus.tbl_studierendenantrag
WHERE prestudent_id = (
SELECT prestudent_id
FROM campus.tbl_studierendenantrag
WHERE studierendenantrag_id = ?
)
AND studierendenantrag_id <> ?
AND (
(
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) IN ?
)
)';
return $this->execQuery($sql, [
self::STATUS_PAUSE,
self::INSERTVON_ABMELDUNGSTGL,
$antrag_id,
$antrag_id,
$antrag_id,
Studierendenantrag_model::TYP_ABMELDUNG,
[
Studierendenantragstatus_model::STATUS_CREATED
],
Studierendenantrag_model::TYP_UNTERBRECHUNG,
[
Studierendenantragstatus_model::STATUS_CREATED
],
Studierendenantrag_model::TYP_WIEDERHOLUNG,
[
Studierendenantragstatus_model::STATUS_REQUESTSENT_1,
Studierendenantragstatus_model::STATUS_REQUESTSENT_2,
Studierendenantragstatus_model::STATUS_CREATED,
Studierendenantragstatus_model::STATUS_LVSASSIGNED,
Studierendenantragstatus_model::STATUS_PAUSE
],
]);
}
public function resumeAntraegeForAbmeldungStgl($antrag_id)
{
$sql = 'INSERT INTO campus.tbl_studierendenantrag_status
(studierendenantrag_id, studierendenantrag_statustyp_kurzbz, insertvon, insertamum)
SELECT studierendenantrag_id, (
SELECT studierendenantrag_statustyp_kurzbz
FROM campus.tbl_studierendenantrag_status s
WHERE s.studierendenantrag_id=a.studierendenantrag_id
AND campus.get_status_id_studierendenantrag(a.studierendenantrag_id) <> studierendenantrag_status_id
ORDER BY insertamum DESC
LIMIT 1
), ?, (
SELECT insertamum
FROM campus.tbl_studierendenantrag_status
WHERE studierendenantrag_status_id = campus.get_status_id_studierendenantrag(?)
)
FROM campus.tbl_studierendenantrag a
WHERE prestudent_id = (
SELECT prestudent_id
FROM campus.tbl_studierendenantrag
WHERE studierendenantrag_id = ?
)
AND typ <> ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) = ?
';
return $this->execQuery($sql, [
self::INSERTVON_ABMELDUNGSTGL,
$antrag_id,
$antrag_id,
Studierendenantrag_model::TYP_ABMELDUNG_STGL,
Studierendenantragstatus_model::STATUS_PAUSE
]);
}
public function stopAntraegeForAbbruchBy($antrag_id)
{
$sql = 'INSERT INTO campus.tbl_studierendenantrag_status
(studierendenantrag_id, studierendenantrag_statustyp_kurzbz, insertvon, insertamum)
SELECT studierendenantrag_id, ?, ?, (
SELECT insertamum
FROM campus.tbl_studierendenantrag_status
WHERE studierendenantrag_status_id = campus.get_status_id_studierendenantrag(?)
)
FROM campus.tbl_studierendenantrag
WHERE prestudent_id = (
SELECT prestudent_id
FROM campus.tbl_studierendenantrag
WHERE studierendenantrag_id = ?
)
AND studierendenantrag_id <> ?
AND (
(
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ?
) OR (
typ = ?
AND campus.get_status_studierendenantrag(studierendenantrag_id) NOT IN ?
)
)';
return $this->execQuery($sql, [
self::STATUS_PAUSE,
self::INSERTVON_DEREGISTERED,
$antrag_id,
$antrag_id,
$antrag_id,
Studierendenantrag_model::TYP_ABMELDUNG,
[
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_CANCELLED
],
Studierendenantrag_model::TYP_UNTERBRECHUNG,
[
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_CANCELLED,
Studierendenantragstatus_model::STATUS_REMINDERSENT,
Studierendenantragstatus_model::STATUS_REJECTED
],
Studierendenantrag_model::TYP_ABMELDUNG_STGL,
[
Studierendenantragstatus_model::STATUS_CANCELLED,
Studierendenantragstatus_model::STATUS_DEREGISTERED,
Studierendenantragstatus_model::STATUS_OBJECTION_DENIED
],
Studierendenantrag_model::TYP_WIEDERHOLUNG,
[
Studierendenantragstatus_model::STATUS_DEREGISTERED,
Studierendenantragstatus_model::STATUS_APPROVED
],
]);
}
}
@@ -21,4 +21,26 @@ class Zeitaufzeichnung_model extends DB_Model
return $this->execQuery($qry);
}
public function getFullInterval($uid, $fromDate, $toDate)
{
$qry = <<<EOL
SELECT d.dates, z.*
FROM
(SELECT
*, to_char ((ende-start),'HH24:MI') as diff,
(SELECT (to_char(sum(ende-start),'DD')::integer)*24+to_char(sum(ende-start),'HH24')::integer || ':' || to_char(sum(ende-start),'MI')
FROM campus.tbl_zeitaufzeichnung
WHERE uid=? and start between ? AND ?) as summe
FROM campus.tbl_zeitaufzeichnung
WHERE uid=? AND (aktivitaet_kurzbz != 'DienstreiseMT' or aktivitaet_kurzbz is null) AND start between ? AND ?) as z
RIGHT JOIN (select generate_series ( ?::timestamp , ?::timestamp , '1 day'::interval) :: date as dates) d on date(z.ende) = d.dates
ORDER BY d.dates desc, z.start desc
EOL;
return $this->execQuery($qry, array($uid, $fromDate, $toDate, $uid, $fromDate, $toDate, $fromDate, $toDate));
}
}
@@ -18,7 +18,7 @@ class Dienstverhaeltnis_model extends DB_Model
$result = null;
$qry = "
SELECT
SELECT
dv.dienstverhaeltnis_id,
tbl_benutzer.uid,
tbl_mitarbeiter.personalnummer,
@@ -30,8 +30,8 @@ class Dienstverhaeltnis_model extends DB_Model
org.oe_kurzbz,
org.bezeichnung oe_bezeichnung,
dv.von,
dv.bis,
dv.vertragsart_kurzbz,
dv.bis,
dv.vertragsart_kurzbz,
dv.updateamum,
dv.updatevon
FROM tbl_mitarbeiter
@@ -59,13 +59,13 @@ class Dienstverhaeltnis_model extends DB_Model
";
return $this->execQuery($qry, $data);
}
public function getDVByID($dvid) {
$this->addSelect('hr.tbl_dienstverhaeltnis.*, public.tbl_organisationseinheit.bezeichnung as unternehmen');
$this->addJoin('public.tbl_organisationseinheit', 'hr.tbl_dienstverhaeltnis.oe_kurzbz = public.tbl_organisationseinheit.oe_kurzbz');
$result = $this->load($dvid);
$result = $this->load($dvid);
if (hasData($result)) {
return $result;
@@ -81,7 +81,7 @@ class Dienstverhaeltnis_model extends DB_Model
$datestring = $date->format("Y-m-d");
$qry = "
SELECT
SELECT
dv.dienstverhaeltnis_id,
tbl_benutzer.uid,
tbl_mitarbeiter.personalnummer,
@@ -115,26 +115,26 @@ class Dienstverhaeltnis_model extends DB_Model
$params = array_merge($params, array($dvid, $dvid));
$dvidclause = <<<EODVIDC
AND (
SELECT
COUNT(*) AS karenzen
FROM
hr.tbl_vertragsbestandteil vb
WHERE
SELECT
COUNT(*) AS karenzen
FROM
hr.tbl_vertragsbestandteil vb
WHERE
vb.dienstverhaeltnis_id = ?
AND
vb.vertragsbestandteiltyp_kurzbz = 'karenz'
AND
dv.von::date >= COALESCE(vb.von, '1970-01-01'::date)
AND
COALESCE(dv.bis::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31')
AND
vb.vertragsbestandteiltyp_kurzbz = 'karenz'
AND
dv.von::date >= COALESCE(vb.von, '1970-01-01'::date)
AND
COALESCE(dv.bis::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31')
) = 0
AND dv.dienstverhaeltnis_id != ?
EODVIDC;
}
$query = <<<EOSQL
SELECT
SELECT
count(*) AS dvcount
FROM
hr.tbl_dienstverhaeltnis dv
@@ -142,35 +142,104 @@ EODVIDC;
dv.mitarbeiter_uid = ?
AND
dv.oe_kurzbz = ?
AND
dv.vertragsart_kurzbz != 'werkvertrag'
AND
dv.vertragsart_kurzbz NOT IN ('werkvertrag', 'studentischehilfskr')
AND
?::date <= COALESCE(dv.bis, '2170-12-31'::date)
AND
COALESCE(?::date, '2170-12-31'::date) >= dv.von
AND
COALESCE(?::date, '2170-12-31'::date) >= dv.von
AND (
SELECT
COUNT(*) AS karenzen
FROM
hr.tbl_vertragsbestandteil vb
WHERE
SELECT
COUNT(*) AS karenzen
FROM
hr.tbl_vertragsbestandteil vb
WHERE
vb.dienstverhaeltnis_id = dv.dienstverhaeltnis_id
AND
vb.vertragsbestandteiltyp_kurzbz = 'karenz'
AND
?::date >= COALESCE(vb.von, '1970-01-01'::date)
AND
COALESCE(?::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31')
) = 0
AND
vb.vertragsbestandteiltyp_kurzbz = 'karenz'
AND
?::date >= COALESCE(vb.von, '1970-01-01'::date)
AND
COALESCE(?::date, '2170-12-31'::date) <= COALESCE(vb.bis, '2170-12-31')
) = 0
{$dvidclause}
EOSQL;
$ret = $this->execReadOnlyQuery($query, $params);
if( ($dvcount = getData($ret)) && ($dvcount[0]->dvcount > 0) ) {
return true;
}
return false;
return false;
}
}
public function getDVByPersonUIDOverlapping($uid, $oe_kurzbz=null, $beginn=null, $ende=null)
{
$result = null;
$qry = "
SELECT
dv.dienstverhaeltnis_id,
tbl_benutzer.uid,
tbl_mitarbeiter.personalnummer,
tbl_mitarbeiter.kurzbz,
tbl_mitarbeiter.lektor,
tbl_mitarbeiter.fixangestellt,
tbl_person.person_id,
tbl_benutzer.alias,
org.oe_kurzbz,
org.bezeichnung oe_bezeichnung,
dv.von,
dv.bis,
dv.vertragsart_kurzbz,
dv.updateamum,
dv.updatevon
FROM tbl_mitarbeiter
JOIN tbl_benutzer ON tbl_mitarbeiter.mitarbeiter_uid::text = tbl_benutzer.uid::text
JOIN tbl_person USING (person_id)
JOIN hr.tbl_dienstverhaeltnis dv ON(tbl_benutzer.uid::text = dv.mitarbeiter_uid::text)
JOIN public.tbl_organisationseinheit org USING(oe_kurzbz)
WHERE tbl_benutzer.uid=?";
$data = array($uid);
if(!is_null($oe_kurzbz))
{
$qry.=" AND oe_kurzbz=?";
$data[] = $oe_kurzbz;
}
if (!is_null($beginn) && !is_null($ende))
{
$qry.=" AND (?,?) OVERLAPS (dv.von, COALESCE(dv.bis, '2999-12-31'))";
$data[] = $beginn;
$data[] = $ende;
}
$qry .="
ORDER BY dv.von desc
";
return $this->execQuery($qry, $data);
}
public function fetchDienstverhaeltnisse($unternehmen, $stichtag=null, $mitarbeiteruid=null) {
$where = "oe_kurzbz = " . $this->escape($unternehmen);
if( !is_null($stichtag) )
{
$where .= " AND " . $this->escape($stichtag) . " BETWEEN COALESCE(von, '1970-01-01') AND COALESCE(bis, '2070-12-31')";
}
if( !is_null($mitarbeiteruid) )
{
$where .= " AND mitarbeiter_uid = " . $this->escape($mitarbeiteruid);
}
$res = $this->loadWhere($where);
$dvs = array();
if(hasData($res) )
{
$dvs = getData($res);
}
return $dvs;
}
}
@@ -0,0 +1,65 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
// NOTE(chris): For security reasons 404 will be displayed the same everywhere
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>404 Page Not Found</title>
<style type="text/css">
::selection { background-color: #E13300; color: white; }
::-moz-selection { background-color: #E13300; color: white; }
body {
background-color: #fff;
margin: 40px;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #4F5155;
}
a {
color: #003399;
background-color: transparent;
font-weight: normal;
}
h1 {
color: #444;
background-color: transparent;
border-bottom: 1px solid #D0D0D0;
font-size: 19px;
font-weight: normal;
margin: 0 0 14px 0;
padding: 14px 15px 10px 15px;
}
code {
font-family: Consolas, Monaco, Courier New, Courier, monospace;
font-size: 12px;
background-color: #f9f9f9;
border: 1px solid #D0D0D0;
color: #002166;
display: block;
margin: 14px 0 14px 0;
padding: 12px 10px 12px 10px;
}
#container {
margin: 10px;
border: 1px solid #D0D0D0;
box-shadow: 0 0 8px #D0D0D0;
}
p {
margin: 12px 15px 12px 15px;
}
</style>
</head>
<body>
<div id="container">
<h1><?php echo $heading; ?></h1>
<?php echo $message; ?>
</div>
</body>
</html>
@@ -0,0 +1,49 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
global $g_result;
// NOTE(chris): remove p tags from CI_Exceptions::show_error() function
$msg = substr($message, 3);
$msg = substr($msg, 0, -4);
$msg = explode('</p><p>', $msg);
$msgs = [];
$error = [
'heading' => $heading
];
/** NOTE(chris): extract Error Number and SQL
* @see: DB_driver.php:692
*/
if (substr(current($msg), 0, 14) == 'Error Number: ') {
$code = substr(array_shift($msg), 14);
if ($code)
$error['code'] = (int)$code;
$msgs[] = array_shift($msg);
$error['sql'] = array_shift($msg);
}
/** NOTE(chris): extract Line Number and Filename
* @see: DB_driver.php:1782
* @see: DB_driver.php:1783
*/
if (count($msg) >= 2) {
if (substr(end($msg), 0, 13) == 'Line Number: ' && substr(prev($msg), 0, 10) == 'Filename: ') {
$error['line'] = (int)substr(array_pop($msg), 13);
$error['filename'] = substr(array_pop($msg), 10);
}
}
foreach ($msg as $m)
$msgs[] = $m;
if (count($msgs) == 1)
$error['message'] = current($msgs);
else
$error['messages'] = $msgs;
$g_result->addError($error, FHCAPI_Controller::ERROR_TYPE_DB);
$g_result->setStatus(FHCAPI_Controller::STATUS_ERROR);
@@ -0,0 +1,27 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
global $g_result;
$error = [
'message' => $message,
'class' => get_class($exception),
'filename' => $exception->getFile(),
'line' => $exception->getLine()
];
if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true) {
$error['backtrace'] = [];
foreach (debug_backtrace() as $err) {
if (isset($err['file']) && strpos($err['file'], realpath(BASEPATH)) !== 0) {
$error['backtrace'][] = [
'file' => $err['file'],
'line' => $err['line'],
'function' => $err['function']
];
}
}
}
$g_result->addError($error, FHCAPI_Controller::ERROR_TYPE_EXCEPTION);
$g_result->setStatus(FHCAPI_Controller::STATUS_ERROR);
@@ -0,0 +1,20 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
global $g_result;
// NOTE(chris): remove p tags from CI_Exceptions::show_error() function
$msg = substr($message, 3);
$msg = substr($msg, 0, -4);
$msg = explode('</p><p>', $msg);
$error = [
'heading' => $heading
];
if (count($msg) == 1)
$error['message'] = current($msg);
else
$error['messages'] = $msg;
$g_result->addError($error, FHCAPI_Controller::ERROR_TYPE_GENERAL);
$g_result->setStatus(FHCAPI_Controller::STATUS_ERROR);
@@ -0,0 +1,31 @@
<?php
if (! defined('BASEPATH')) exit('No direct script access allowed');
global $g_result;
$error = [
'message' => $message,
'severity' => $severity,
'filename' => $filepath,
'line' => $line
];
if (defined('SHOW_DEBUG_BACKTRACE') && SHOW_DEBUG_BACKTRACE === true) {
$error['backtrace'] = [];
foreach (debug_backtrace() as $err) {
if (isset($err['file']) && strpos($err['file'], realpath(BASEPATH)) !== 0) {
$error['backtrace'][] = [
'file' => $err['file'],
'line' => $err['line'],
'function' => $err['function']
];
}
}
}
// TODO(chris): change type with severity
$g_result->addError($error, 'php');
if (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity) {
$g_result->setStatus('error');
}
+2 -2
View File
@@ -31,9 +31,9 @@ $this->load->view(
<div class="fhc-container row">
<div class="col-sm-8 mb-3">
<studierendenantrag-antrag
prestudent-id="<?= $prestudent_id; ?>"
:prestudent-id="<?= $prestudent_id; ?>"
antrag-type="<?= $antrag_type; ?>"
studierendenantrag-id="<?= $studierendenantrag_id; ?>"
:studierendenantrag-id="<?= $studierendenantrag_id ?: 'undefined'; ?>"
v-model:info-array="infoArray"
v-model:status-msg="status.msg"
v-model:status-severity="status.severity"
+105 -16
View File
@@ -38,7 +38,10 @@ $this->load->view(
<div class="alert alert-secondary">
<p><?= $this->p->t('studierendenantrag', 'calltoaction_' . $type); ?></p>
<hr>
<a href="<?= site_url('lehre/Studierendenantrag/' . strtolower($type) . '/' . $prestudent_id); ?>" class="btn btn-outline-secondary">
<a
href="<?= site_url('lehre/Studierendenantrag/' . strtolower($type) . '/' . $prestudent_id); ?>"
class="btn btn-outline-secondary"
>
<i class="fa fa-plus"></i> <?= $this->p->t('studierendenantrag', 'antrag_typ_' . $type); ?>
</a>
</div>
@@ -63,7 +66,16 @@ $this->load->view(
<tr>
<td><?= $antrag->studierendenantrag_id; ?></td>
<td><?= $this->p->t('studierendenantrag', 'antrag_typ_' . $antrag->typ); ?></td>
<td><?= $antrag->status_bezeichnung; ?></td>
<td>
<?=
(
$antrag->status == Studierendenantragstatus_model::STATUS_PAUSE
&& $antrag->status_insertvon == Studierendenantragstatus_model::INSERTVON_DEREGISTERED
)
? $this->p->t('studierendenantrag', 'status_stop')
: $antrag->status_bezeichnung;
?>
</td>
<td><?= $antrag->studiensemester_kurzbz; ?></td>
<td><?= (new DateTime($antrag->datum))->format('d.m.Y'); ?></td>
<td><?= $antrag->datum_wiedereinstieg ? (new DateTime($antrag->datum_wiedereinstieg))->format('d.m.Y') : ''; ?></td>
@@ -74,15 +86,32 @@ $this->load->view(
</a>
<!-- Modal -->
<div class="modal fade" id="modalgrund<?= $antrag->studierendenantrag_id; ?>" tabindex="-1" aria-labelledby="modalgrundLabel<?= $antrag->studierendenantrag_id; ?>" aria-hidden="true">
<div
class="modal fade"
id="modalgrund<?= $antrag->studierendenantrag_id; ?>"
tabindex="-1"
aria-labelledby="modalgrundLabel<?= $antrag->studierendenantrag_id; ?>"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalgrundLabel<?= $antrag->studierendenantrag_id; ?>"><?= $this->p->t('studierendenantrag', 'antrag_grund'); ?></h5>
<h5
class="modal-title"
id="modalgrundLabel<?= $antrag->studierendenantrag_id; ?>"
>
<?= $this->p->t('studierendenantrag', 'antrag_grund'); ?>
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<textarea class="form-control" style="width: 100%; height: 250px;" readonly><?= $antrag->grund; ?></textarea>
<textarea
class="form-control"
style="width: 100%; height: 250px;"
readonly
>
<?= $antrag->grund; ?>
</textarea>
</div>
</div>
</div>
@@ -100,18 +129,78 @@ $this->load->view(
<?php } ?>
</td>
<td>
<a href="<?= site_url('lehre/Studierendenantrag/' . strtolower($antrag->typ) . '/' . $antrag->prestudent_id . '/' . $antrag->studierendenantrag_id); ?>"><i class="fa-solid fa-pen" title="<?= $this->p->t('studierendenantrag', 'btn_edit'); ?>"></i></a>
<?php if ($antrag->typ != Studierendenantrag_model::TYP_WIEDERHOLUNG && in_array($antrag->status, [
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_OBJECTED,
Studierendenantragstatus_model::STATUS_OBJECTION_DENIED,
Studierendenantragstatus_model::STATUS_REMINDERSENT
])) { ?>
<a class="ms-2" target="_blank" href="<?= base_url('cis/private/pdfExport.php?xml=Antrag' . $antrag->typ . '.xml.php&xsl=Antrag' . $antrag->typ . '&id=' . $antrag->studierendenantrag_id . '&uid=' . getAuthUID()); ?>"><i class="fa-solid fa-download" title="<?= $this->p->t('studierendenantrag', 'btn_download_antrag'); ?>"></i></a>
<a
href="<?= site_url('lehre/Studierendenantrag/' .
strtolower($antrag->typ) .
'/' .
$antrag->prestudent_id .
'/' .
$antrag->studierendenantrag_id); ?>"
>
<i class="fa-solid fa-pen" title="<?= $this->p->t('studierendenantrag', 'btn_edit'); ?>"></i>
</a>
<?php
$allowed = [];
switch ($antrag->typ) {
case Studierendenantrag_model::TYP_ABMELDUNG:
$allowed = [
Studierendenantragstatus_model::STATUS_APPROVED
];
break;
case Studierendenantrag_model::TYP_ABMELDUNG_STGL:
$allowed = [
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_OBJECTED,
Studierendenantragstatus_model::STATUS_OBJECTION_DENIED,
Studierendenantragstatus_model::STATUS_DEREGISTERED
];
break;
case Studierendenantrag_model::TYP_UNTERBRECHUNG:
$allowed = [
Studierendenantragstatus_model::STATUS_APPROVED,
Studierendenantragstatus_model::STATUS_REMINDERSENT
];
break;
case Studierendenantrag_model::TYP_WIEDERHOLUNG:
$allowed = [
Studierendenantragstatus_model::STATUS_DEREGISTERED
];
break;
}
if (in_array($antrag->status, $allowed)) { ?>
<a
class="ms-2"
target="_blank"
href="<?= base_url('cis/private/pdfExport.php?xml=Antrag' .
$antrag->typ .
'.xml.php&xsl=Antrag' .
$antrag->typ .
'&id=' .
$antrag->studierendenantrag_id .
'&uid=' .
getAuthUID()); ?>"
>
<i
class="fa-solid fa-download"
title="<?= $this->p->t('studierendenantrag', 'btn_download_antrag'); ?>"
>
</i>
</a>
<?php } ?>
<?php if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG && $antrag->status == Studierendenantragstatus_model::STATUS_APPROVED) { ?>
<a class="ms-2" href="#modallv<?= $antrag->studierendenantrag_id; ?>" data-bs-toggle="modal"><?= $this->p->t('studierendenantrag', 'btn_show_lvs'); ?></a>
<lv-popup id="modallv<?= $antrag->studierendenantrag_id; ?>" antrag-id = "<?= $antrag->studierendenantrag_id; ?>">
<?php if ($antrag->typ == Studierendenantrag_model::TYP_WIEDERHOLUNG
&& $antrag->status == Studierendenantragstatus_model::STATUS_APPROVED
) { ?>
<a
class="ms-2"
href="#modallv<?= $antrag->studierendenantrag_id; ?>"
data-bs-toggle="modal"
>
<?= $this->p->t('studierendenantrag', 'btn_show_lvs'); ?>
</a>
<lv-popup
id="modallv<?= $antrag->studierendenantrag_id; ?>"
antrag-id = "<?= $antrag->studierendenantrag_id; ?>"
>
<?= $this->p->t('studierendenantrag', 'my_lvs'); ?>
</lv-popup>
<?php } ?>
-147
View File
@@ -1,147 +0,0 @@
<?php
/* Copyright (C) 2024 FH Technikum-Wien
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Authors: Andreas Oesterreicher <andreas.oesterreicher@technikum-wien.at>
* Manuela Thamer <manuela.thamer@technikum-wien.at>
*/
/**
* Dieses Script liefert Zeitverfügbarkeiten und -sperren des übergebenen Parameters (uid, foreign_uid oder oekurz_bz)
*
* Aufruf: link + [params]
* link: URL:',APP_ROOT'/fhcomplete/cis/public/ical_zeitsperren.php/cipher_encryption/
* [params]
* uid=oesi (Termine: "ZEITSPERRE" bzw."VERFUEGBAR", Bezeichnungen der Zeitsperren)
* oe_kurzbz=SystemEntwicklungCore (Termine: "ZEITSPERRE" bzw."VERFUEGBAR", "NAME MITARBEITER")
* foreign_uid=oesi (Termine: "ZEITSPERRE" bzw."VERFUEGBAR", "NAME MITARBEITER")
* Beispielaufruf php
* echo "<a href=" . APP_ROOT. "cis/public/ical_zeitsperren.php/cipher_encryption/".encryptData('uid=oesi',ZEITSPERREN_CYPHER_KEY).">Beispielaufruf <a/>";
*/
require_once('../../config/cis.config.inc.php');
require_once('../../include/benutzer.class.php');
require_once('../../include/zeitsperre.class.php');
require_once('../../include/datum.class.php');
require_once('../../include/benutzerberechtigung.class.php');
require_once('../../include/benutzerfunktion.class.php');
$params = mb_substr($_SERVER['PATH_INFO'],1);
$paramsArray = explode('/',$params);
if ($paramsArray[0] == 'cipher_encryption')
{
$string = decryptData($paramsArray[1],ZEITSPERREN_CYPHER_KEY);
}
$delimiter = "=";
$position = strpos($string, $delimiter);
if ($position !== false)
{
$substring = substr($string, 0, $position);
}
else
{
die('invalid Parameterformat');
}
$private = ($substring == 'uid') ? true : false;
if($substring == 'uid' || $substring == 'foreign_uid')
{
$uid = substr($string, $position + 1);
$bn = new benutzer();
if(!$bn->load($uid))
die('uid' . $uid . ' not found');
$filename = $uid;
}
elseif($substring == 'oe_kurzbz')
{
$oe = substr($string, $position + 1);
//check if valid Oe
$bf = new benutzerfunktion();
if ($bf->getOeFunktionen($oe, 'oezuordnung'))
{
$uidArr = array();
foreach ($bf->result as $uid) {
$uidArr[] = $uid->uid;
}
if ($uidArr == null)
die('oe_kurzbz not found');
else
$uid = $uidArr;
$filename = $oe;
}
}
else
{
die('Parameter not valid');
}
header("Content-Type: text/calendar; charset=UTF-8");
header("Content-disposition: filename=".$filename."_Zeitsperren_Verfuegbarkeiten.ics");
echo "BEGIN:VCALENDAR\n";
echo "VERSION:2.0\n";
echo "PRODID:-//FH TECHNIKUM WIEN//EN\n";
echo 'DTSTART;TZID=Europe/Vienna:',date('Ymd', mktime(0,0,0,date('m'),date('d')-5,date('Y'))),"T000000\n";
echo 'DTEND;TZID=Europe/Vienna:',date('Ymd', mktime(0,0,0,date('m'),date('d')+30,date('Y'))),"T000000\n";
echo "BEGIN:VTIMEZONE
TZID:Europe/Vienna
BEGIN:DAYLIGHT
TZOFFSETFROM:+0100
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
DTSTART:19810329T020000
TZNAME:GMT+02:00
TZOFFSETTO:+0200
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:+0200
RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
DTSTART:19961027T030000
TZNAME:GMT+01:00
TZOFFSETTO:+0100
END:STANDARD
END:VTIMEZONE\n";
//echo 'URL:',APP_ROOT,'cis/public/ical_zeitsperren.php/',$uid,"\n";
//Zeitsperren des Users (der User) laden
$zeitsperre = new zeitsperre();
$zeitsperre->getZeitsperrenForIcal($uid);
foreach ($zeitsperre->result as $z)
{
$typ = $z->zeitsperretyp_kurzbz;
$name = trim($z->vorname . " " . $z->nachname);
$titel = $typ == 'ZVerfueg' ? "VERFUEGBAR" : "ZEITSPERRE";
$bezeichnung = $private ? ($typ . " " . $z->bezeichnung) : $name;
$dateVon = new DateTime($z->von);
$dtstart = $dateVon->format('Ymd\THis');
$dateBis = new DateTime($z->bis);
$dtend = $dateBis->format('Ymd\THis');
echo "BEGIN:VEVENT\r\n"
."SUMMARY: ". $titel."\r\n"
."DESCRIPTION: ". $bezeichnung."\r\n"
."DTSTART;TZID=Europe/Vienna:".$dtstart."\r\n"
."DTEND;TZID=Europe/Vienna:".$dtend."\r\n"
."TRANSP:OPAQUE\r\n"
."END:VEVENT\r\n";
}
echo "END:VCALENDAR\r\n";
?>
-3
View File
@@ -155,9 +155,6 @@ define('LVPLAN_KATEGORIE', 'StundenplanTW');
// Key zum Verschluesseln des LV-Plan Google Links
define('LVPLAN_CYPHER_KEY',pack('H*', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'));
// Key zum Verschluesseln Zeitsperren/Zeitverfügbarkeiten
define('ZEITSPERREN_CYPHER_KEY',pack('H*', 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'));
// Gibt an ob Termine aus dem Vorsemester nach der Semesterhaelfte des Folgesemesters
// noch im pers. LVPan aufscheinen.
// true | false
+16
View File
@@ -141,7 +141,9 @@ foreach($addon_obj->result as $addon)
<command id="menu-dokumente-accountinfoblatt:command" oncommand="PrintAccountInfoBlatt(event);"/>
<command id="menu-dokumente-zutrittskarte:command" oncommand="PrintZutrittskarte();"/>
<command id="menu-dokumente-antrag-abmeldung:command" oncommand="StudentPrintAntragAbmeldung(event);"/>
<command id="menu-dokumente-antrag-abmeldungstgl:command" oncommand="StudentPrintAntragAbmeldungStgl(event);"/>
<command id="menu-dokumente-antrag-unterbrechung:command" oncommand="StudentPrintAntragUnterbrechung(event);"/>
<command id="menu-dokumente-antrag-wiederholung:command" oncommand="StudentPrintAntragWiederholung(event);"/>
<command id="menu-dokumente-studienblatt:command" oncommand="PrintStudienblatt(event);"/>
<command id="menu-dokumente-studienblatt_englisch:command" oncommand="PrintStudienblattEnglisch(event);"/>
<command id="menu-dokumente-pruefungsprotokoll:command" oncommand="StudentAbschlusspruefungPrintPruefungsprotokollMultiple(event,'de');"/>
@@ -518,6 +520,13 @@ foreach($addon_obj->result as $addon)
command = "menu-dokumente-antrag-abmeldung:command"
accesskey = "&menu-dokumente-antrag-abmeldung.accesskey;"
/>
<menuitem
id = "menu-dokumente-antrag-abmeldungstgl"
key = "menu-dokumente-antrag-abmeldungstgl:key"
label = "&menu-dokumente-antrag-abmeldungstgl.label;"
command = "menu-dokumente-antrag-abmeldungstgl:command"
accesskey = "&menu-dokumente-antrag-abmeldungstgl.accesskey;"
/>
<menuitem
id = "menu-dokumente-antrag-unterbrechung"
key = "menu-dokumente-antrag-unterbrechung:key"
@@ -525,6 +534,13 @@ foreach($addon_obj->result as $addon)
command = "menu-dokumente-antrag-unterbrechung:command"
accesskey = "&menu-dokumente-antrag-unterbrechung.accesskey;"
/>
<menuitem
id = "menu-dokumente-antrag-wiederholung"
key = "menu-dokumente-antrag-wiederholung:key"
label = "&menu-dokumente-antrag-wiederholung.label;"
command = "menu-dokumente-antrag-wiederholung:command"
accesskey = "&menu-dokumente-antrag-wiederholung.accesskey;"
/>
</menupopup>
</menu>
<menuseparator/>
+7 -9
View File
@@ -280,7 +280,7 @@ if(!$error)
if($_POST['neu']!='true')
{
if(!$entwt->load($_POST['mitarbeiter_uid'],$_POST['studiengang_kz_old']))
if(!$entwt->load($_POST['entwicklungsteam_id']))
{
$error = true;
$return = false;
@@ -291,12 +291,6 @@ if(!$error)
else
{
if($entwt->exists($_POST['mitarbeiter_uid'],$_POST['studiengang_kz']))
{
$error = true;
$errormsg = 'Es existiert bereits ein Eintrag fuer diesen Studiengang';
$return = false;
}
$entwt->new = true;
$entwt->insertamum = date('Y-m-d H:i:s');
$entwt->insertvon = $user;
@@ -304,6 +298,7 @@ if(!$error)
if(!$error)
{
$entwt->entwicklungsteam_id= $_POST['entwicklungsteam_id'];
$entwt->mitarbeiter_uid = $_POST['mitarbeiter_uid'];
$entwt->studiengang_kz = $_POST['studiengang_kz'];
$entwt->studiengang_kz_old = $_POST['studiengang_kz_old'];
@@ -328,15 +323,17 @@ if(!$error)
elseif(isset($_POST['type']) && $_POST['type']=='entwicklungsteamdelete')
{
//Loescht einen Entwicklungsteameintrag
$entwicklungsteam_id = $_POST['entwicklungsteam_id'];
$entwt = new entwicklungsteam();
if($entwt->delete($_POST['mitarbeiter_uid'],$_POST['studiengang_kz']))
if($entwt->delete($entwicklungsteam_id))
{
$return = true;
}
else
{
$return = false;
$errormsg = $entwt->errormsg;
$errormsg = $entwt->errormsg;
}
}
elseif(isset($_POST['type']) && $_POST['type']=='buchungsave')
@@ -803,6 +800,7 @@ if(!$error)
$errormsg = $konto->errormsg;
}
else
{
$error = false;
$return = true;
@@ -199,7 +199,7 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
class="sortDirectionIndicator"
sort="rdf:http://www.technikum-wien.at/bisfunktion/rdf#sws" onclick="MitarbeiterTreeFunktionSort()"/>
<splitter class="tree-splitter"/>
<treecol id="mitarbeiter-funktion-treecol-bisverwendung_id" label="VerwendungID" flex="1" persist="hidden, width" hidden="true"
<treecol id="mitarbeiter-funktion-treecol-bisverwendung_id" label="VerwendungID" flex="1" persist="hidden, width" hidden="false"
class="sortDirectionIndicator"
sort="rdf:http://www.technikum-wien.at/bisfunktion/rdf#bisverwendung_id" onclick="MitarbeiterTreeFunktionSort()"/>
<splitter class="tree-splitter"/>
@@ -286,15 +286,19 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
class="sortDirectionIndicator"
sort="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#studiengang" onclick="MitarbeiterTreeEntwicklungsteamSort()"/>
<splitter class="tree-splitter"/>
<treecol id="mitarbeiter-entwicklungsteam-treecol-entwicklungsteam_id" label="entwicklungsteam_id" flex="1" persist="hidden, width" hidden="true"
class="sortDirectionIndicator"
sort="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#entwicklungsteam_id" onclick="MitarbeiterTreeEntwicklungteamSort()"/>
<splitter class="tree-splitter"/>
<treecol id="mitarbeiter-entwicklungsteam-treecol-besqual" label="Besondere Qualifikation" flex="1" persist="hidden, width" hidden="false"
class="sortDirectionIndicator"
sort="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#besqual" onclick="MitarbeiterTreeEntwicklungteamSort()"/>
<splitter class="tree-splitter"/>
<treecol id="mitarbeiter-entwicklungsteam-treecol-beginn" label="Beginn" flex="1" persist="hidden, width" hidden="true"
<treecol id="mitarbeiter-entwicklungsteam-treecol-beginn" label="Beginn" flex="1" persist="hidden, width" hidden="false"
class="sortDirectionIndicator"
sort="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#beginn" onclick="MitarbeiterTreeEntwicklungsteamSort()"/>
<splitter class="tree-splitter"/>
<treecol id="mitarbeiter-entwicklungsteam-treecol-ende" label="Ende" flex="1" persist="hidden, width" hidden="true"
<treecol id="mitarbeiter-entwicklungsteam-treecol-ende" label="Ende" flex="1" persist="hidden, width" hidden="false"
class="sortDirectionIndicator"
sort="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#ende" onclick="MitarbeiterTreeEntwicklungsteamSort()"/>
<splitter class="tree-splitter"/>
@@ -318,6 +322,7 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
<treeitem uri="rdf:*">
<treerow>
<treecell label="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#studiengang" />
<treecell label="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#entwicklungsteam_id" />
<treecell label="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#besqual" />
<treecell label="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#beginn" />
<treecell label="rdf:http://www.technikum-wien.at/entwicklungsteam/rdf#ende" />
@@ -345,6 +350,7 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
<column flex="5"/>
</columns>
<rows>
<row>
<label value="Studiengang" control="mitarbeiter-entwicklungsteam-detail-menulist-studiengang"/>
<menulist id="mitarbeiter-entwicklungsteam-detail-menulist-studiengang" disabled="true"
@@ -359,6 +365,7 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
</template>
</menulist>
</row>
<row>
<label value="Besondere Qualifikation" control="mitarbeiter-entwicklungsteam-detail-menulist-besqual"/>
<menulist id="mitarbeiter-entwicklungsteam-detail-menulist-besqual" disabled="true"
@@ -373,14 +380,17 @@ echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
</template>
</menulist>
</row>
<row>
<label value="Beginn" control="mitarbeiter-entwicklungsteam-detail-datum-beginn"/>
<box id="mitarbeiter-entwicklungsteam-detail-datum-beginn" class="Datum" disabled="true"/>
</row>
<row>
<label value="Ende" control="mitarbeiter-entwicklungsteam-detail-datum-ende"/>
<box id="mitarbeiter-entwicklungsteam-detail-datum-ende" class="Datum" disabled="true"/>
</row>
<row>
<spacer />
<button id="mitarbeiter-entwicklungsteam-detail-button-speichern" label="Speichern" disabled="true" oncommand="MitarbeiterEntwicklungsteamSpeichern()" />
+26 -23
View File
@@ -39,6 +39,7 @@ var MitarbeiterFunktionTreeDatasource=null; // Datasource des Verwendungstrees
var MitarbeiterFunktionSelectVerwendungID=null; // ID der Verwendung der Funktion die nach dem rebuild markiert werden soll
var MitarbeiterFunktionSelectStudiengangID=null; // ID des Studiengangs der Funktion die nach dem rebuild markiert werden soll
var MitarbeiterEntwicklungsteamTreeDatasource=null; // Datasource des Entwicklungsteamtrees
var MitarbeiterEntwicklungsteamSelectEntwicklungsteamID=null; //ID Entwicklungsteameintrag
var MitarbeiterEntwicklungsteamSelectMitarbeiterUID=null; // UID des Mitarbeiters des Entwicklugnsteams das nach dem rebuild markiert werden soll
var MitarbeiterEntwicklungsteamSelectStudiengangID=null; // ID des Stg des Entwicklungsteams das nach dem rebuild markiert werden soll
var MitarbeiterEntwicklungsteamDoubleRefresh=false; // Wenn auf einen Tree der eine leere Datasource enthaelt eine neue Datasource angehaengt wird, dann muss doppelt refresht werden
@@ -685,6 +686,7 @@ function MitarbeiterAuswahl()
// **** ENTWICKLUNGSTEAM ****
entwicklungsteamtree = document.getElementById('mitarbeiter-tree-entwicklungsteam');
url='<?php echo APP_ROOT;?>rdf/entwicklungsteam.rdf.php?mitarbeiter_uid='+uid+"&"+gettimestamp();
try
@@ -1603,24 +1605,27 @@ function MitarbeiterEntwicklungsteamTreeSelect()
var tree=document.getElementById('mitarbeiter-tree-entwicklungsteam');
var items = tree.view.rowCount; //Anzahl der Zeilen ermitteln
//In der globalen Variable ist der zu selektierende Verwendung gespeichert
if(MitarbeiterEntwicklungsteamSelectStudiengangID!=null)
//In der globalen Variable ist der zu selektierende Entwicklungsteameintrag gespeichert
if (MitarbeiterEntwicklungsteamSelectStudiengangID!=null)
{
for(var i=0;i<items;i++)
{
col = tree.columns ? tree.columns["mitarbeiter-entwicklungsteam-treecol-entwicklungsteam_id"] : "mitarbeiter-entwicklungsteam-treecol-entwicklungsteam_id";
entwicklungsteam_id=tree.view.getCellText(i,col);
col = tree.columns ? tree.columns["mitarbeiter-entwicklungsteam-treecol-mitarbeiter_uid"] : "mitarbeiter-entwicklungsteam-treecol-mitarbeiter_uid";
mitarbeiter_uid=tree.view.getCellText(i,col);
mitarbeiter_uid=tree.view.getCellText(i,col);
col = tree.columns ? tree.columns["mitarbeiter-entwicklungsteam-treecol-studiengang_kz"] : "mitarbeiter-entwicklungsteam-treecol-studiengang_kz";
studiengang_kz=tree.view.getCellText(i,col);
if(mitarbeiter_uid == MitarbeiterEntwicklungsteamSelectMitarbeiterUID && studiengang_kz==MitarbeiterEntwicklungsteamSelectStudiengangID)
{
//Zeile markieren
tree.view.selection.select(i);
//Sicherstellen, dass die Zeile im sichtbaren Bereich liegt
tree.treeBoxObject.ensureRowIsVisible(i);
return true;
}
if(entwicklungsteam_id == MitarbeiterEntwicklungsteamSelectEntwicklungsteamID && mitarbeiter_uid == MitarbeiterEntwicklungsteamSelectMitarbeiterUID && studiengang_kz==MitarbeiterEntwicklungsteamSelectStudiengangID)
{
//Zeile markieren
tree.view.selection.select(i);
//Sicherstellen, dass die Zeile im sichtbaren Bereich liegt
tree.treeBoxObject.ensureRowIsVisible(i);
return true;
}
}
}
}
@@ -1673,20 +1678,21 @@ function MitarbeiterEntwicklungsteamSelect()
if (tree.currentIndex==-1)
return false;
var col = tree.columns ? tree.columns["mitarbeiter-entwicklungsteam-treecol-entwicklungsteam_id"] : "mitarbeiter-entwicklungsteam-treecol-entwicklungsteam_id";
entwicklungsteam_id=tree.view.getCellText(tree.currentIndex,col);
col = tree.columns ? tree.columns["mitarbeiter-entwicklungsteam-treecol-studiengang_kz"] : "mitarbeiter-entwicklungsteam-treecol-studiengang_kz";
studiengang_kz=tree.view.getCellText(tree.currentIndex,col);
col = tree.columns ? tree.columns["mitarbeiter-entwicklungsteam-treecol-mitarbeiter_uid"] : "mitarbeiter-entwicklungsteam-treecol-mitarbeiter_uid";
mitarbeiter_uid=tree.view.getCellText(tree.currentIndex,col);
var url = '<?php echo APP_ROOT ?>rdf/entwicklungsteam.rdf.php?studiengang_kz='+studiengang_kz+'&mitarbeiter_uid='+mitarbeiter_uid+'&'+gettimestamp();
var url = '<?php echo APP_ROOT ?>rdf/entwicklungsteam.rdf.php?studiengang_kz='+studiengang_kz+'&mitarbeiter_uid='+mitarbeiter_uid+'&entwicklungsteam_id='+entwicklungsteam_id+'&'+gettimestamp();
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].
getService(Components.interfaces.nsIRDFService);
var dsource = rdfService.GetDataSourceBlocking(url);
var dsource = rdfService.GetDataSourceBlocking(url);
var subject = rdfService.GetResource("http://www.technikum-wien.at/entwicklungsteam/" + mitarbeiter_uid+'/'+studiengang_kz);
var subject = rdfService.GetResource("http://www.technikum-wien.at/entwicklungsteam/" + mitarbeiter_uid+'/'+studiengang_kz+'/'+entwicklungsteam_id);
var predicateNS = "http://www.technikum-wien.at/entwicklungsteam/rdf";
@@ -1743,6 +1749,7 @@ function MitarbeiterEntwicklungsteamSpeichern()
req.add('type', 'entwicklungsteamsave');
req.add('neu', neu);
req.add('entwicklungsteam_id', entwicklungsteam_id);
req.add('studiengang_kz', studiengang_kz);
req.add('studiengang_kz_old', studiengang_kz_old);
req.add('besqualcode', besqualcode);
@@ -1765,6 +1772,7 @@ function MitarbeiterEntwicklungsteamSpeichern()
else
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
MitarbeiterEntwicklungsteamSelectEntwicklungsteamID = entwicklungsteam_id;
MitarbeiterEntwicklungsteamSelectMitarbeiterUID = mitarbeiter_uid;
MitarbeiterEntwicklungsteamSelectStudiengangID = studiengang_kz;
MitarbeiterEntwicklungsteamDoubleRefresh=true;
@@ -1788,11 +1796,8 @@ function MitarbeiterEntwicklungsteamLoeschen()
return false;
}
col = tree.columns ? tree.columns["mitarbeiter-entwicklungsteam-treecol-studiengang_kz"] : "mitarbeiter-entwicklungsteam-treecol-studiengang_kz";
studiengang_kz=tree.view.getCellText(tree.currentIndex,col);
col = tree.columns ? tree.columns["mitarbeiter-entwicklungsteam-treecol-mitarbeiter_uid"] : "mitarbeiter-entwicklungsteam-treecol-mitarbeiter_uid";
mitarbeiter_uid=tree.view.getCellText(tree.currentIndex,col);
col = tree.columns ? tree.columns["mitarbeiter-entwicklungsteam-treecol-entwicklungsteam_id"] : "mitarbeiter-entwicklungsteam-treecol-entwicklungsteam_id";
entwicklungsteam_id=tree.view.getCellText(tree.currentIndex,col);
if(confirm("Wollen Sie diesen Eintrag wirklich loeschen?"))
{
@@ -1800,9 +1805,7 @@ function MitarbeiterEntwicklungsteamLoeschen()
var req = new phpRequest(url,'','');
req.add('type', 'entwicklungsteamdelete');
req.add('studiengang_kz', studiengang_kz);
req.add('mitarbeiter_uid', mitarbeiter_uid);
req.add('entwicklungsteam_id', entwicklungsteam_id);
var response = req.executePOST();
+96
View File
@@ -6225,6 +6225,54 @@ function StudentPrintAntragAbmeldung(event)
window.open('<?php echo APP_ROOT; ?>/content/pdfExport.php?xml=AntragAbmeldung.xml.php&xsl=AntragAbmeldung&uid='+student_uid+'&prestudent_id='+prestudent_id+'&output='+output,'AntragAbmeldung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes');
}
function StudentPrintAntragAbmeldungStgl(event)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var tree = document.getElementById('student-tree');
if (tree.currentIndex==-1)
return alert('Bitte eine/n Studierende/n auswaehlen');
//Uids aller markierten Studenten holen
var start = new Object();
var end = new Object();
var numRanges = tree.view.selection.getRangeCount();
var prestudent_id= '';
var student_uid= '';
for (var t = 0; t < numRanges; t++)
{
tree.view.selection.getRangeAt(t,start,end);
for (var v = start.value; v <= end.value; v++)
{
var col = tree.columns ? tree.columns["student-treecol-prestudent_id"] : "student-treecol-prestudent_id";
var prestudentId=tree.view.getCellText(v,col);
prestudent_id += ';'+prestudentId;
col = tree.columns ? tree.columns["student-treecol-uid"] : "student-treecol-uid";
var uid=tree.view.getCellText(v,col);
student_uid += ';'+uid;
}
}
if (event.shiftKey)
{
var output='odt';
}
else if (event.ctrlKey)
{
var output='doc';
}
else
{
var output='pdf';
}
window.open('<?php echo APP_ROOT; ?>/content/pdfExport.php?xml=AntragAbmeldungStgl.xml.php&xsl=AntragAbmeldungStgl&uid='+student_uid+'&prestudent_id='+prestudent_id+'&output='+output,'AntragAbmeldung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes');
}
function StudentPrintAntragUnterbrechung(event)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
@@ -6273,6 +6321,54 @@ function StudentPrintAntragUnterbrechung(event)
window.open('<?php echo APP_ROOT; ?>/content/pdfExport.php?xml=AntragUnterbrechung.xml.php&xsl=AntragUnterbrechung&uid='+student_uid+'&prestudent_id='+prestudent_id+'&output='+output,'AntragUnterbrechung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes');
}
function StudentPrintAntragWiederholung(event)
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var tree = document.getElementById('student-tree');
if (tree.currentIndex==-1)
return alert('Bitte eine/n Studierende/n auswaehlen');
//Uids aller markierten Studenten holen
var start = new Object();
var end = new Object();
var numRanges = tree.view.selection.getRangeCount();
var prestudent_id= '';
var student_uid= '';
for (var t = 0; t < numRanges; t++)
{
tree.view.selection.getRangeAt(t,start,end);
for (var v = start.value; v <= end.value; v++)
{
var col = tree.columns ? tree.columns["student-treecol-prestudent_id"] : "student-treecol-prestudent_id";
var prestudentId=tree.view.getCellText(v,col);
prestudent_id += ';'+prestudentId;
col = tree.columns ? tree.columns["student-treecol-uid"] : "student-treecol-uid";
var uid=tree.view.getCellText(v,col);
student_uid += ';'+uid;
}
}
if (event.shiftKey)
{
var output='odt';
}
else if (event.ctrlKey)
{
var output='doc';
}
else
{
var output='pdf';
}
window.open('<?php echo APP_ROOT; ?>/content/pdfExport.php?xml=AntragWiederholung.xml.php&xsl=AntragWiederholung&uid='+student_uid+'&prestudent_id='+prestudent_id+'&output='+output,'AntragUnterbrechung', 'height=200,width=350,left=0,top=0,hotkeys=0,resizable=yes,status=no,scrollbars=yes,toolbar=no,location=no,menubar=no,dependent=yes');
}
// ****
// * Erstellt den Ausbildungsvertrag fuer einen oder mehrere Studenten
// ****
@@ -152,8 +152,8 @@ $is_hidden = (!defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN')
</template>
</tree>
<vbox>
<button id="student-projektarbeit-button-neu" label="Neu" oncommand="StudentProjektarbeitNeu();" disabled="true"/>
<button id="student-projektarbeit-button-loeschen" label="Loeschen" oncommand="StudentProjektarbeitLoeschen();" disabled="true"/>
<button id="student-projektarbeit-button-neu" label="Neue PA" oncommand="StudentProjektarbeitNeu();" disabled="true"/>
<button id="student-projektarbeit-button-loeschen" label="PA Loeschen" oncommand="StudentProjektarbeitLoeschen();" disabled="true"/>
</vbox>
</hbox>
<hbox>
@@ -322,7 +322,7 @@ $is_hidden = (!defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN')
<spacer />
<hbox>
<spacer flex="1" />
<button id="student-projektarbeit-button-speichern" oncommand="StudentProjektarbeitSpeichern()" label="Speichern" disabled="true"/>
<button id="student-projektarbeit-button-speichern" oncommand="StudentProjektarbeitSpeichern()" label="PA Speichern" disabled="true"/>
</hbox>
</row>
</rows>
@@ -428,8 +428,8 @@ $is_hidden = (!defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN')
</template>
</tree>
<vbox>
<button id="student-projektbetreuer-button-neu" label="Neu" oncommand="StudentProjektbetreuerNeu();" disabled="true"/>
<button id="student-projektbetreuer-button-loeschen" label="Loeschen" oncommand="StudentProjektbetreuerLoeschen();" disabled="true"/>
<button id="student-projektbetreuer-button-neu" label="Neue Betreuung" oncommand="StudentProjektbetreuerNeu();" disabled="true"/>
<button id="student-projektbetreuer-button-loeschen" label="Betreuung Loeschen" oncommand="StudentProjektbetreuerLoeschen();" disabled="true"/>
</vbox>
</hbox>
<vbox hidden="true">
@@ -534,7 +534,7 @@ $is_hidden = (!defined('FAS_STUDIERENDE_PROJEKTARBEIT_VERTRAGSDETAILS_ANZEIGEN')
<spacer />
<hbox>
<spacer flex="1" />
<button id="student-projektbetreuer-button-speichern" label="Speichern" oncommand="StudentProjektbetreuerSpeichern()" />
<button id="student-projektbetreuer-button-speichern" label="Betreuung Speichern" oncommand="StudentProjektbetreuerSpeichern()" />
</hbox>
</row>
</rows>
+1 -1
View File
@@ -181,7 +181,7 @@ abstract class db extends basis
if (!include(dirname(__FILE__).'/../application/config/'.CI_ENVIRONMENT.'/db_crypt.php')) return null;
// Array that will contains all the DB decryption password
$decryptionPasswordsArray = array();
$decryptionPasswordArray = array();
// Array that will contains all the DB decryption password names
$decryptionPasswordNamesArray = array();
+109
View File
@@ -0,0 +1,109 @@
<?php
/* Copyright (C) 2013 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Authors: Manuela Thamer <manuela.thamer@technikum-wien.at>
*/
require_once(dirname(__FILE__). '/basis_db.class.php');
require_once(dirname(__FILE__). '/sprache.class.php');
require_once(dirname(__FILE__). '/functions.inc.php');
class besqualcode extends basis_db
{
//Objekt besqualcode
public $result = array();
//Tabellenspalten
public $besqualcode;
public $besqualbez;
/**
* Konstruktor - Laedt optional einen besqualcode
* @param char $besqualcode Besqualcode der geladen werden soll.
*/
public function __construct($besqualcode = null)
{
parent::__construct();
if($besqualcode != null)
$this->load($besqualcode);
}
/**
* Liefert alle Lehrmodi aus der table tbl_besqualcode
* @return true wenn ok, false im Fehlerfall
*/
public function getAll()
{
$qry = "SELECT * FROM bis.tbl_besqual";
if ($this->db_query($qry))
{
while ($row = $this->db_fetch_object())
{
$besqualcode = new besqualcode();
$besqualcode->besqualcode = $row->besqualcode;
$besqualcode->besqualbez = $row->besqualbez;
$this->result[] = $besqualcode;
}
return true;
}
else
{
$this->errormsg = "Fehler bei der Abfrage aufgetreten";
return false;
}
}
/**
* Laedt einen besqualcode
* @param char $besqualcode ID des Datensatzes der zu laden ist.
* @return true wenn ok, false im Fehlerfall
*/
public function load($besqualcode)
{
$qry = "SELECT
*
FROM
bis.tbl_besqual
WHERE
besqualcode=".$this->db_add_param($besqualcode).";";
if (!$this->db_query($qry))
{
$this->errormsg = 'Fehler beim Lesen vom besqualcode';
return false;
}
if ($row = $this->db_fetch_object())
{
$this->besqualcode = $row->besqualcode;
$this->besqualbez = $row->besqualbez;
}
else
{
$this->errormsg = 'Es ist kein besqualcode mit dieser ID vorhanden';
return false;
}
return true;
}
}
?>
+144 -27
View File
@@ -16,8 +16,9 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*
* Authors: Christian Paminger <christian.paminger@technikum-wien.at>,
* Andreas Oesterreicher <andreas.oesterreicher@technikum-wien.at> and
* Rudolf Hangl <rudolf.hangl@technikum-wien.at>.
* Andreas Oesterreicher <andreas.oesterreicher@technikum-wien.at>,
* Rudolf Hangl <rudolf.hangl@technikum-wien.at>
* Manuela Thamer <manuela.thamer@technikum-wien.at>
*/
require_once(dirname(__FILE__).'/basis_db.class.php');
@@ -27,7 +28,10 @@ class entwicklungsteam extends basis_db
public $result = array();
//Tabellenspalten
public $entwicklungsteam_id;
public $mitarbeiter_uid;
public $nachname;
public $vorname;
public $studiengang_kz;
public $besqualcode;
public $beginn;
@@ -43,38 +47,40 @@ class entwicklungsteam extends basis_db
/**
* Konstruktor
* @param mitarbeiter_uid ID des zu ladenden Datensatzes
* @param entwicklungsteam_id ID des zu ladenden Datensatzes
* studiengang_kz
*/
public function __construct($mitarbeiter_uid=null, $studiengang_kz=null)
public function __construct($entwicklungsteam_id = null)
{
parent::__construct();
if(!is_null($mitarbeiter_uid) && !is_null($studiengang_kz))
$this->load($mitarbeiter_uid, $studiengang_kz);
if(!is_null($entwicklungsteam_id))
$this->load($entwicklungsteam_id);
}
/**
* Laedt einen Datensatz
* @param mitarbeiter_uid ID des zu ladenden Datensatzes
* studiengang_kz
* @param entwicklungsteam_id ID des zu ladenden Datensatzes
*/
public function load($mitarbeiter_uid, $studiengang_kz)
public function load($entwicklungsteam_id)
{
if(!is_numeric($studiengang_kz) || $studiengang_kz == '')
if(!is_numeric($entwicklungsteam_id))
{
$this->errormsg = 'studiengang_kz muss eine gueltige Zahl sein';
$this->errormsg = 'entwicklungsteam_id muss eine gueltige Zahl sein';
return false;
}
//laden des Datensatzes
$qry = "SELECT * FROM bis.tbl_entwicklungsteam JOIN bis.tbl_besqual USING(besqualcode)
WHERE mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid)." AND studiengang_kz=".$this->db_add_param($studiengang_kz, FHC_INTEGER).";";
WHERE entwicklungsteam_id=".$this->db_add_param($entwicklungsteam_id);
$qry.=";";
if($this->db_query($qry))
{
if($row = $this->db_fetch_object())
{
$this->entwicklungsteam_id = $row->entwicklungsteam_id;
$this->mitarbeiter_uid = $row->mitarbeiter_uid;
$this->studiengang_kz = $row->studiengang_kz;
$this->besqualcode = $row->besqualcode;
@@ -103,19 +109,19 @@ class entwicklungsteam extends basis_db
/**
* Loescht einen Datensatz
* @param bisverwendung_id ID des zu loeschenden Datensatzes
* @param entwicklungsteam_id ID des zu loeschenden Datensatzes
* @return true wenn ok, false im Fehlerfall
*/
public function delete($mitarbeiter_uid, $studiengang_kz)
public function delete($entwicklungsteam_id)
{
if(!is_numeric($studiengang_kz) || $studiengang_kz == '')
if(!is_numeric($entwicklungsteam_id))
{
$this->errormsg = 'studiengang_kz muss eine gueltige Zahl sein';
$this->errormsg = 'entwicklungsteam_id muss eine gueltige Zahl sein';
return false;
}
$qry = "DELETE FROM bis.tbl_entwicklungsteam
WHERE mitarbeiter_uid = ".$this->db_add_param($mitarbeiter_uid)." AND studiengang_kz=".$this->db_add_param($studiengang_kz, FHC_INTEGER).";";
WHERE entwicklungsteam_id = ".$this->db_add_param($entwicklungsteam_id).";";
if($this->db_query($qry))
{
@@ -148,7 +154,12 @@ class entwicklungsteam extends basis_db
}
if($this->besqualcode=='')
{
$this->errormsg = 'BesondereQualifikation muss eingetragen werden';
$this->errormsg = 'Besondere Qualifikation muss eingetragen werden';
return false;
}
if($this->ende != '' && $this->beginn > $this->ende)
{
$this->errormsg = 'Endedatum darf nicht vor Anfangsdatum liegen';
return false;
}
return true;
@@ -160,7 +171,7 @@ class entwicklungsteam extends basis_db
* andernfalls wird der Datensatz mit der ID in $akte_id aktualisiert
* @return true wenn ok, false im Fehlerfall
*/
public function save($new=null)
public function save($new = null)
{
if(!$this->validate())
return false;
@@ -181,7 +192,6 @@ class entwicklungsteam extends basis_db
$this->db_add_param($this->updatevon).', '.
$this->db_add_param($this->insertamum).', '.
$this->db_add_param($this->insertvon).');';
}
else
{
@@ -196,7 +206,7 @@ class entwicklungsteam extends basis_db
" ende=".$this->db_add_param($this->ende).",".
" updateamum=".$this->db_add_param($this->updateamum).",".
" updatevon=".$this->db_add_param($this->updatevon).
" WHERE mitarbeiter_uid=".$this->db_add_param($this->mitarbeiter_uid)." AND studiengang_kz=".$this->db_add_param($this->studiengang_kz_old, FHC_INTEGER).";";
" WHERE entwicklungsteam_id=".$this->db_add_param($this->entwicklungsteam_id).";";
}
if($this->db_query($qry))
@@ -215,7 +225,7 @@ class entwicklungsteam extends basis_db
* @param $uid UID des Mitarbeiters
* @return true wenn ok, false wenn Fehler
*/
public function getEntwicklungsteam($mitarbeiter_uid, $studiengang_kz=null)
public function getEntwicklungsteam($mitarbeiter_uid, $studiengang_kz = null)
{
//laden des Datensatzes
$qry = "SELECT * FROM bis.tbl_entwicklungsteam JOIN bis.tbl_besqual USING(besqualcode)
@@ -232,6 +242,7 @@ class entwicklungsteam extends basis_db
{
$obj = new entwicklungsteam();
$obj->entwicklungsteam_id = $row->entwicklungsteam_id;
$obj->mitarbeiter_uid = $row->mitarbeiter_uid;
$obj->studiengang_kz = $row->studiengang_kz;
$obj->besqualcode = $row->besqualcode;
@@ -256,16 +267,15 @@ class entwicklungsteam extends basis_db
}
/**
* Preuft ob der Eintrag schon existiert
* Prueft ob der Eintrag schon existiert
*
* @param $mitarbeiter_uid
* @param $studiengang_kz
* @param entwicklungsteam_id
* @return true wenn vorhanden, false wenn nicht
*/
public function exists($mitarbeiter_uid,$studiengang_kz)
public function exists($entwicklungsteam_id)
{
$qry = "SELECT count(*) as anzahl FROM bis.tbl_entwicklungsteam
WHERE mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid)." AND studiengang_kz=".$this->db_add_param($studiengang_kz, FHC_INTEGER).";";
WHERE entwicklungsteam_id=".$this->db_add_param($entwicklungsteam_id).";";
if($this->db_query($qry))
{
@@ -288,5 +298,112 @@ class entwicklungsteam extends basis_db
return false;
}
}
/**
* Liefert alle Entwicklungsteameinträge
* @param int $studiengang_kz Studiengangkennzeichen.
* @param char $sort Parameter, nach dem sortiert werden soll.
* @return alle Entwicklungsteameinträge
*/
public function getAll($studiengang_kz = null, $sort = null)
{
$qry = "SELECT e.*, p.nachname, p.vorname FROM bis.tbl_entwicklungsteam e
JOIN public.tbl_benutzer b ON e.mitarbeiter_uid = b.uid
JOIN public.tbl_person p ON b.person_id = p.person_id
";
if ($studiengang_kz != null)
$qry .= " WHERE e.studiengang_kz = ".$this->db_add_param($studiengang_kz);
if ($sort != null)
{
$qry .= " ORDER BY ".$sort;
}
$qry .= ";";
if ($this->db_query($qry))
{
while ($row = $this->db_fetch_object())
{
$obj = new entwicklungsteam();
$obj->entwicklungsteam_id = $row->entwicklungsteam_id;
$obj->mitarbeiter_uid = $row->mitarbeiter_uid;
$obj->nachname = $row->nachname;
$obj->vorname = $row->vorname;
$obj->studiengang_kz = $row->studiengang_kz;
$obj->besqualcode = $row->besqualcode;
$obj->beginn = $row->beginn;
$obj->ende = $row->ende;
$obj->insertamum = $row->insertamum;
$obj->insertvon = $row->insertvon;
$obj->updateamum = $row->updateamum;
$obj->updatevon = $row->updatevon;
$this->result[] = $obj;
}
return true;
}
else
{
$this->errormsg = 'Fehler beim Laden der Entwicklungsteameinträge.';
return false;
}
}
/*
* Laedt alle Entwicklungsteameintraege eines Mitarbeiters für eine bestimmte Bisperiode
* @param $uid UID des Mitarbeiters
* @param $stichtag Stichtag im Format 'Y-m-d'
* @return true wenn ok, false wenn Fehler
*/
public function getEntwicklungsteamBis($mitarbeiter_uid, $stichtag, $studiengang_kz = null)
{
$datetime = new DateTime($stichtag);
$bismeldung_jahr = $datetime->format('Y');
//laden des Datensatzes
$qry = "SELECT *
FROM bis.tbl_entwicklungsteam
JOIN bis.tbl_besqual USING(besqualcode)
WHERE mitarbeiter_uid=".$this->db_add_param($mitarbeiter_uid)."
AND (beginn is NULL OR beginn <= make_date(". $this->db_add_param($bismeldung_jahr). "::INTEGER, 12, 31))
AND (ende is NULL OR ende >= make_date(". $this->db_add_param($bismeldung_jahr). "::INTEGER, 1, 1))";
if($studiengang_kz!=null)
$qry.=" AND studiengang_kz=".$this->db_add_param($studiengang_kz);
$qry.=";";
if($this->db_query($qry))
{
while($row = $this->db_fetch_object())
{
$obj = new entwicklungsteam();
$obj->entwicklungsteam_id = $row->entwicklungsteam_id;
$obj->mitarbeiter_uid = $row->mitarbeiter_uid;
$obj->studiengang_kz = $row->studiengang_kz;
$obj->besqualcode = $row->besqualcode;
$obj->beginn = $row->beginn;
$obj->ende = $row->ende;
$obj->updateamum = $row->updateamum;
$obj->updatevon = $row->updatevon;
$obj->insertamum = $row->insertamum;
$obj->insertvon = $row->insertvon;
$obj->ext_id = $row->ext_id;
$obj->besqual = $row->besqualbez;
$this->result[] = $obj;
}
return true;
}
else
{
$this->errormsg = 'Fehler bei der Datenbankabfrage';
return false;
}
}
}
?>
+64 -4
View File
@@ -184,13 +184,30 @@ class filter extends basis_db
}
/**
* Ausgabe des HTML Widgets
* @param kurzbz des Datensatzes, der gefunden werden soll
* Ausgabe des HTML Widgets. Parameter, die als GET übergeben werden, werden ausgelesen und vorselektiert
* @param $kurzbz String Kurzbz des Datensatzes, der gefunden werden soll
* @return boolean true wenn ok, false im Fehlerfall
*/
public function getHtmlWidget($kurzbz)
{
$html='';
// GET-Parameter parsen und in String rausschreiben
parse_str($this->getVars(), $getParams);
foreach ($getParams AS $key=>$value)
{
// Vordefinierte Parameter entfernen
if ($key == 'type' ||
$key == 'statistik_kurzbz' ||
$key == 'report_id' ||
$key == 'putlog' ||
$key == 'systemfilter_id' ||
$key == 'debug')
{
unset($getParams[$key]);
}
}
foreach ($this->result as $filter)
{
if ($filter->kurzbz==$kurzbz)
@@ -206,15 +223,58 @@ class filter extends basis_db
$sql = str_replace('$user', $this->db_add_param($user), $filter->sql);
$this->loadValues($sql, $filter->valuename, $filter->showvalue);
foreach ($this->values as $value)
$html.="\n\t\t\t\t".'<option value="'.$value->value.'">'.$value->text.'</option>';
{
// Wenn ein Attribut als GET-Parameter übergeben wurde, dann vorselektieren
if (isset($getParams[$filter->kurzbz]))
{
//GET-Parameter aufsplitten
$paramsArr = explode(',',$getParams[$filter->kurzbz]);
//echo '<pre>', var_dump($value->value), '</pre>';
//$value->value = preg_replace('/(.*?)\s*selected.*/im', '$1', $value->value);
$value->value = preg_replace('/"\s*.*/im', '', $value->value);
//echo '<pre>', var_dump($value->value), '</pre>';
if (in_array($value->value, $paramsArr))
$html .= "\n\t\t\t\t".'<option value="'.$value->value.'" selected="selected">'.$value->text.'</option>';
else
{
//$value->value = preg_replace('/(.*?)selected=.selected./', '$1', $value->value);
//$value->value = preg_replace('/(.*?)\s*[selected=?selected?]/', '$1', $value->value);
//$value->value = preg_replace('/(.*?)\s*selected="selected"\s*/', '${1}', $value->value);
//$value->value = preg_replace('/^\s*selected=.*?selected.*?\s*/', ' ', $value->value);
//$value->value = str_replace('selected=', '', $value->value);
//echo '<pre>', var_dump($value->value), '</pre>';
$html .= "\n\t\t\t\t".'<option value="'.$value->value.'">'.$value->text.'</option>';
}
}
else
{
//$value->value = str_replace('selected="selected', '', $value->value);
$html .= "\n\t\t\t\t".'<option value="'.$value->value.'">'.$value->text.'</option>';
}
}
$html.="\n\t\t\t</select>";
break;
case 'datepicker':
$html .= '<input type="text" id="' . $filter->kurzbz . '" class="form-control" name="' . $filter->kurzbz . '">';
$html .= '<input type="text" id="'.$filter->kurzbz.'" class="form-control" name="'.$filter->kurzbz.'"';
if (isset($getParams[$filter->kurzbz]))
{
$html .= ' value="'.$getParams[$filter->kurzbz].'"';
}
$html .= ' >';
$html .= '<script>';
$html .= '$("#' . $filter->kurzbz . '").datepicker({ dateFormat: \'yy-mm-dd\' });';
$html .= '</script>';
break;
case 'text':
$html .= '<input type="text" id="'.$filter->kurzbz.'" class="form-control" name="'.$filter->kurzbz.'" '.$filter->htmlattr;
if (isset($getParams[$filter->kurzbz]))
{
$html .= ' value="'.$getParams[$filter->kurzbz].'"';
}
$html .= '>';
break;
}
return $html;
}
+40 -1
View File
@@ -1889,6 +1889,46 @@ class mitarbeiter extends benutzer
}
/**
* Liefert alle Mitarbeiter*innen
*
* @param $filter
* @return boolean
*/
public function getAll()
{
$qry = '
SELECT
ma.mitarbeiter_uid, p.nachname, p.vorname, b.alias
FROM
public.tbl_mitarbeiter ma
JOIN public.tbl_benutzer b ON (mitarbeiter_uid=uid)
JOIN public.tbl_person p USING(person_id)
ORDER BY p.nachname
';
if($this->db_query($qry))
{
while($row = $this->db_fetch_object())
{
$ma_obj = new mitarbeiter();
$ma_obj->nachname = $row->nachname;
$ma_obj->vorname = $row->vorname;
$ma_obj->mitarbeiter_uid = $row->mitarbeiter_uid;
$ma_obj->alias = $row->alias;
$this->maData[] = $ma_obj;
}
return true;
}
else
{
$this->errormsg = 'Fehler beim Laden der Daten';
return false;
}
}
/**
* Generiert nächste freie Personalnummer anhand der sequence tbl_mitarbeiter_personalnummer_seq
* @return string $personalnummer
@@ -1947,6 +1987,5 @@ class mitarbeiter extends benutzer
return true;
}
}
}
?>
File diff suppressed because it is too large Load Diff
-70
View File
@@ -633,75 +633,5 @@ class zeitsperre extends basis_db
return true;
}
/**
* Laedt alle Zeitsperren eines Benutzers (bzw. einer OE) für Ical Export
* @param $uid bzw Array($uids)
* @param $bisgrenze wenn true werden nur die Zeitsperren des
* aktuellen Geschaeftsjahres geholt (1.9.-31.8.)
* @return true wenn ok, false im Fehlerfall
*/
public function getZeitsperrenForIcal($uid, $bisgrenze=true)
{
if(!is_array($uid))
$uid = [$uid];
$qry = "SELECT
zeitsperretyp_kurzbz,
bezeichnung,
mitarbeiter_uid,
CONCAT(vondatum, ' ', std1.beginn) AS von,
CONCAT(bisdatum, ' ', std2.ende) AS bis,
vondatum, vonstunde, bisdatum, bisstunde,
p.vorname, p.nachname
FROM campus.tbl_zeitsperre zs
JOIN campus.tbl_zeitsperretyp USING (zeitsperretyp_kurzbz)
JOIN public.tbl_benutzer bn ON (bn.uid = zs.mitarbeiter_uid)
JOIN public.tbl_person p ON (bn.person_id = p.person_id)
LEFT JOIN lehre.tbl_stunde std1 ON (std1.stunde = zs.vonstunde)
LEFT JOIN lehre.tbl_stunde std2 ON (std2.stunde = zs.bisstunde)
WHERE mitarbeiter_uid in (". $this->db_implode4SQL($uid) . ")";
if($bisgrenze)
{
$qry.=" AND (
(date_part('month',vondatum)>=9 AND date_part('year', vondatum)>='".(date('Y')-1)."')
OR
(date_part('month',vondatum)<9 AND date_part('year', vondatum)>='".(date('Y'))."')
)";
}
$qry.= " ORDER BY vondatum DESC";
var_dump($qry);
if($this->db_query($qry))
{
while($row = $this->db_fetch_object())
{
$obj = new zeitsperre();
$obj->mitarbeiter_uid = $row->mitarbeiter_uid;
$obj->zeitsperretyp_kurzbz = $row->zeitsperretyp_kurzbz;
$obj->bezeichnung = $row->bezeichnung;
$obj->vondatum = $row->vondatum;
$obj->vonstunde = $row->vonstunde;
$obj->bisdatum = $row->bisdatum;
$obj->bisstunde = $row->bisstunde;
$obj->von = $row->von;
$obj->bis = $row->bis;
$obj->vorname = $row->vorname;
$obj->nachname = $row->nachname;
$this->result[] = $obj;
}
return true;
}
else
{
$this->errormsg = 'Fehler beim Laden der Zeitsperren für ical';
return false;
}
}
}
?>
+5 -5
View File
@@ -187,16 +187,16 @@ class zgv extends basis_db
public function getAllDoktor($onlyAktiv = false)
{
$sprache = new sprache();
$qry='SELECT *,'.$sprache->getSprachQuery('bezeichnung').' FROM bis.tbl_zgvdoktor;';
$qry='SELECT *,'.$sprache->getSprachQuery('bezeichnung').' FROM bis.tbl_zgvdoktor';
if ($onlyAktiv === true)
{
$qry .= " WHERE aktiv";
}
$qry .= " ORDER BY zgvdoktor_bez";
if($result = $this->db_query($qry))
{
while($row= $this->db_fetch_object($result))
+8
View File
@@ -219,10 +219,18 @@
<!ENTITY menu-dokumente-antrag-abmeldung.label "Abmeldung">
<!ENTITY menu-dokumente-antrag-abmeldung.accesskey "A">
<!ENTITY menu-dokumente-antrag-abmeldungstgl.key "S">
<!ENTITY menu-dokumente-antrag-abmeldungstgl.label "Abmeldung durch Stgl">
<!ENTITY menu-dokumente-antrag-abmeldungstgl.accesskey "S">
<!ENTITY menu-dokumente-antrag-unterbrechung.key "U">
<!ENTITY menu-dokumente-antrag-unterbrechung.label "Unterbrecher">
<!ENTITY menu-dokumente-antrag-unterbrechung.accesskey "U">
<!ENTITY menu-dokumente-antrag-wiederholung.key "W">
<!ENTITY menu-dokumente-antrag-wiederholung.label "Abmeldung durch Ablauf der Wiederholungsfrist">
<!ENTITY menu-dokumente-antrag-wiederholung.accesskey "W">
<!ENTITY menu-dokumente-ausbildungsvertrag.key "A">
<!ENTITY menu-dokumente-ausbildungsvertrag.label "Ausbildungsvertrag Deutsch">
<!ENTITY menu-dokumente-ausbildungsvertrag.accesskey "A">
+6146
View File
File diff suppressed because it is too large Load Diff
+33
View File
@@ -0,0 +1,33 @@
{
"name": "fhc-core",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"build": "rollup -c",
"watch": "rollup --watch -c"
},
"dependencies": {
"@vuepic/vue-datepicker": "^7.2.0",
"axios": "^1.6.8",
"primevue": "^3.29.1",
"tabulator-tables": "^5.5.2",
"vue": "^3.3.8",
"vue-router": "^4.1.3"
},
"devDependencies": {
"@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^25.0.7",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5",
"@rollup/plugin-terser": "^0.4.4",
"babel-plugin-transform-class-properties": "^6.24.1",
"glob": "^10.3.10",
"node-sass": "^9.0.0",
"rollup": "^4.13.2",
"rollup-plugin-postcss": "^4.0.2",
"rollup-plugin-vue": "^6.0.0"
}
}
+81 -64
View File
@@ -1,83 +1,100 @@
.text-prewrap {
.fhc-header {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
align-items: baseline;
margin-bottom: 3rem;
}
.fhc-header > h1:first-child {
font-size: calc(1.325rem + .9vw);
}
.fhc-header > :first-child > small {
color: var(--bs-secondary);
font-size: .65em;
padding-inline-start: 1em;
}
.fhc-alert.p-toast-center {
width: 35rem;
max-width: 100vw;
}
.fhc-alert.p-toast-top-right {
max-width: calc(100vw - 40px);
}
.fhc-alert.p-toast-top-right .p-toast-detail,
.fhc-alert.p-toast-center .p-toast-message-text .card {
white-space: pre-wrap;
}
.text-preline {
white-space: pre-line;
}
.accordion-button-primary {
background-color: #e7f1ff;
color: #0c63e4;
}
.accordion-button-primary:not(.collapsed) {
background-color: #cfe2ff;
color: #0a58ca;
.text-prewrap {
white-space: pre-wrap;
}
.accordion-button-secondary {
background-color: #f0f1f2;
color: #616971;
}
.accordion-button-secondary:not(.collapsed) {
background-color: #e2e3e5;
color: #565e64;
.btn-p-0 {
padding: 0 .375rem;
}
.accordion-button-success {
background-color: #e8f3ee;
color: #177a4c;
}
.accordion-button-success:not(.collapsed) {
background-color: #d1e7dd;
color: #146c43;
.z-1 {
z-index: 1;
}
.accordion-button-info {
background-color: #e7fafe;
color: #0cb6d8;
}
.accordion-button-info:not(.collapsed) {
background-color: #cff4fc;
color: #0aa2c0;
.input-group > .input-group-item {
position: relative;
flex: 1 1 auto;
width: 1%;
min-width: 0;
}
.accordion-button-warning {
background-color: #fff9e6;
color: #e6ae06;
}
.accordion-button-warning:not(.collapsed) {
background-color: #fff3cd;
color: #cc9a06;
.input-group > .input-group-item .form-control:focus,
.input-group > .input-group-item .form-select:focus {
z-index: 3;
position: relative;
}
.accordion-button-danger {
background-color: #fcebec;
color: #c6303e;
}
.accordion-button-danger:not(.collapsed) {
background-color: #f8d7da;
color: #b02a37;
.input-group-lg > .input-group-item .form-control,
.input-group-lg > .input-group-item .form-select {
padding: 0.5rem 1rem;
font-size: 1.25rem;
border-radius: 0.3rem;
}
.accordion-button-light {
background-color: #fefeff;
color: #dfe0e1;
}
.accordion-button-light:not(.collapsed) {
background-color: #fefefe;
color: #c6c7c8;
.input-group-sm > .input-group-item .form-control,
.input-group-sm > .input-group-item .form-select {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
border-radius: 0.2rem;
}
.accordion-button-dark {
background-color: #e9e9ea;
color: #1e2125;
}
.accordion-button-dark:not(.collapsed) {
background-color: #d3d3d4;
color: #1a1e21;
.input-group-lg > .input-group-item .form-select,
.input-group-sm > .input-group-item .form-select {
padding-right: 3rem;
}
.tabulator-edit-list .tabulator-edit-list-item {
background-color: white;
.input-group:not(.has-validation) > .input-group-item:not(:last-child) .form-control,
.input-group:not(.has-validation) > .input-group-item:not(:last-child) .form-select {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.input-group.has-validation > .input-group-item:nth-last-child(n+3) .form-control,
.input-group.has-validation > .input-group-item:nth-last-child(n+3) .form-select {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.input-group > .input-group-item:not(:first-child) .form-control,
.input-group > .input-group-item:not(:first-child) .form-select {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.form-control-color.is-invalid,
.was-validated .form-control-color:invalid,
.form-control-color.is-valid,
.was-validated .form-control-color:valid {
padding-right: .375rem;
background-image: none;
}
.tabulator-edit-list .tabulator-edit-list-item:hover,
.tabulator-edit-list .tabulator-edit-list-item.active {
color: white;
}
@@ -64,3 +64,12 @@
margin-top: 20px;
}
.tabulator {
font-size: 1rem;
}
.tabulator-cell .btn {
padding: 0 .375rem;
font-size: .875rem;
border-radius: .2rem;
}
@@ -82,6 +82,7 @@
/*
* To be moved outside
*/
.navbar.navbar-left-side ~ *,
#content {
position: inherit;
margin: 0 0 0 250px;
+16
View File
@@ -0,0 +1,16 @@
.nav-item.nav-link:focus {
box-shadow: 0 0 0 .24rem rgba(13,110,253,.25);
z-index: 1;
outline: 0;
position: relative;
}
.nav-item.nav-link:focus::after {
content: "";
display: block;
position: absolute;
left: -.5rem;
right: -.5rem;
top: calc(100% + 1px);
background: white;
height: .25rem;
}
File diff suppressed because it is too large Load Diff
+46
View File
@@ -0,0 +1,46 @@
@import '../../../vendor/vuejs/vuedatepicker_css/main.css';
:root {
/*General*/
--dp-font-family: var(--bs-body-font-family);
--dp-border-radius: .25rem;
--dp-cell-border-radius: .25rem; /*Specific border radius for the calendar cell*/
/*Sizing*/
--dp-button-height: 2.1875rem; /*Size for buttons in overlays*/
--dp-month-year-row-height: 2.1875rem; /*Height of the month-year select row*/
--dp-month-year-row-button-size: 2.1875rem; /*Specific height for the next/previous buttons*/
--dp-button-icon-height: 1.25rem; /*Icon sizing in buttons*/
--dp-cell-size: 2.1875rem; /*Width and height of calendar cell*/
--dp-cell-padding: .3125rem; /*Padding in the cell*/
--dp-common-padding: .625rem; /*Common padding used*/
--dp-input-icon-padding: 2.1875rem;
--dp-input-padding: .375rem .75rem;
--dp-action-buttons-padding: .125rem .3125rem; /*Adjust padding for the action buttons in action row*/
--dp-row-margin: .3125rem 0; /*Adjust the spacing between rows in the calendar*/
--dp-calendar-header-cell-padding: 0.5rem; /*Adjust padding in calendar header cells*/
--dp-two-calendars-spacing: .625rem; /*Space between multiple calendars*/
--dp-overlay-col-padding: .1875rem; /*Padding in the overlay column*/
--dp-time-inc-dec-button-size: 2rem; /*Sizing for arrow buttons in the time picker*/
--dp-menu-padding: .375rem .5rem; /*Menu padding*/
}
.dp__theme_light {
--dp-text-color: var(--text-color);
--dp-primary-color: var(--bs-primary);
--dp-primary-disabled-color: rgba(var(--bs-primary-rgb), .65);
--dp-primary-text-color: var(--primary-color-text);
--dp-secondary-color: var(--bs-secondary);
--dp-border-color: var(--bs-gray-400);
--dp-menu-border-color: var(--bs-gray-400);
--dp-border-color-hover: var(--bs-gray-400);
--dp-icon-color: rgba(var(--bs-black-rgb), .5);
--dp-hover-icon-color: rgba(var(--bs-black-rgb), .75);
--dp-range-between-dates-text-color: var(--dp-hover-text-color, var(--text-color));
}
.dp__theme_light .form-control.is-invalid {
--dp-border-color-hover: var(--bs-danger);
}
.dp__theme_light .form-control.is-valid {
--dp-border-color-hover: var(--bs-success);
}
.form-control.is-invalid ~ .dp__clear_icon,
.was-validated .form-control:invalid ~ .dp__clear_icon { margin-right: calc(1.5em + .75rem - 12px) }
@@ -24,6 +24,8 @@ import {CoreRESTClient} from '../../RESTClient.js';
import {CoreFetchCmpt} from '../../components/Fetch.js';
import {BismeldestichtagAPIs} from './API.js';
import Phrasen from '../../plugin/Phrasen.js';
const bismeldestichtagApp = Vue.createApp({
data: function() {
return {
@@ -187,4 +189,4 @@ const bismeldestichtagApp = Vue.createApp({
}
});
bismeldestichtagApp.mount('#main');
bismeldestichtagApp.use(Phrasen).mount('#main');
+3 -1
View File
@@ -21,6 +21,8 @@ import {LogsViewerTabulatorEventHandlers} from './TabulatorSetup.js';
import {CoreFilterCmpt} from '../../components/filter/Filter.js';
import {CoreNavigationCmpt} from '../../components/navigation/Navigation.js';
import Phrasen from '../../plugin/Phrasen.js';
const logsViewerApp = Vue.createApp({
data: function() {
return {
@@ -40,5 +42,5 @@ const logsViewerApp = Vue.createApp({
}
});
logsViewerApp.mount('#main');
logsViewerApp.use(Phrasen).mount('#main');
+2 -2
View File
@@ -1,5 +1,5 @@
import {CoreFilterCmpt} from '../components/Filter.js';
import {CoreNavigationCmpt} from '../components/Navigation.js';
import {CoreFilterCmpt} from '../components/filter/Filter.js';
import {CoreNavigationCmpt} from '../components/navigation/Navigation.js';
import verticalsplit from "../components/verticalsplit/verticalsplit.js";
import searchbar from "../components/searchbar/searchbar.js";
import fhcapifactory from "./api/fhcapifactory.js";
+123
View File
@@ -0,0 +1,123 @@
import FhcFragment from "../Fragment.js";
export default {
components: {
FhcFragment
},
provide() {
return {
$registerToForm: component => {
if (this.inputs.indexOf(component) < 0)
this.inputs.push(component);
},
$clearValidationForName: this.clearValidationForName
};
},
props: {
tag: {
type: String,
default: 'form'
}
},
data() {
return {
inputs: []
}
},
computed: {
sortedInputs() {
return this.inputs.reduce((a,c) => {
let name = c.name || '_default';
if (!a[name])
a[name] = [];
a[name].push(c);
if (c.lcType == 'checkbox' && name.substr(-1) == ']' && name.indexOf('[')) {
name = name.substr(0, name.lastIndexOf('['));
if (!a[name])
a[name] = [];
a[name].push(c);
}
return a;
}, {});
},
factory() {
const factory = Object.create(Object.getPrototypeOf(this.$fhcApi.factory), Object.getOwnPropertyDescriptors(this.$fhcApi.factory));
factory.$fhcApi = {
get: this.get,
post: this.post
};
return factory;
}
},
methods: {
get(...args) {
if (typeof args[0] == 'object' && args[0].clearValidation && args[0].setFeedback)
args[0] = this;
else
args.unshift(this);
return this.$fhcApi.get(...args);
},
post(...args) {
if (typeof args[0] == 'object' && args[0].clearValidation && args[0].setFeedback)
args[0] = this;
else
args.unshift(this);
return this.$fhcApi.post(...args);
},
_sendFeedbackToInput(inputs, feedback, valid) {
if (inputs.length) {
inputs.forEach(input => input.setFeedback(valid, feedback));
return false;
}
if (this.$fhcAlert) {
this.$fhcAlert[valid ? 'alertSuccess' : 'alertError'](feedback);
return false;
}
return true;
},
setFeedback(valid, feedback) {
if (Array.isArray(feedback)) {
let remaining = feedback.filter(fb =>
this._sendFeedbackToInput(
this.sortedInputs['_default'] || [],
fb,
valid
)
);
return remaining.length ? remaining : null;
}
if (typeof feedback === 'object') {
let remaining = Object.entries(feedback).filter(([name, fb]) =>
this._sendFeedbackToInput(
this.sortedInputs[name.split('.')[0] + name.split('.').slice(1).map(p => `[${p}]`).join("")] || this.sortedInputs['_default'] || [],
fb,
valid
)
);
return remaining.length ? Object.fromEntries(remaining) : null;
}
let remaining = this._sendFeedbackToInput(
this.sortedInputs['_default'] || [],
feedback,
valid
);
return remaining ? feedback : null;
},
clearValidation() {
this.inputs.forEach(input => input.clearValidation());
},
clearValidationForName(name) {
(this.sortedInputs[name.split('.')[0] + name.split('.').slice(1).map(p => `[${p}]`).join("")] || this.sortedInputs['_default'] || [])
.forEach(input => input.clearValidation());
}
},
template: `
<component :is="tag || 'FhcFragment'" v-bind="$attrs">
<slot></slot>
</component>`
}
+315
View File
@@ -0,0 +1,315 @@
import FhcFragment from "../Fragment.js";
let _uuid = {};
export default {
inheritAttrs: false,
components: {
FhcFragment
},
inject: {
registerToForm: {
from: '$registerToForm',
default: null
},
clearValidationForName: {
from: '$clearValidationForName',
default: null
}
},
props: {
bsFeedback: Boolean,
noAutoClass: Boolean,
noFeedback: Boolean,
inputGroup: Boolean,
type: String,
name: String,
containerClass: [String, Array, Object]
},
data() {
return {
valid: undefined,
feedback: [],
modelValueDummy: undefined
}
},
computed: {
hasContainer() {
if (!this.bsFeedback)
return true;
if (this.containerClass)
return true;
for (const prop in this.autoContainerClass)
if (Object.hasOwn(this.autoContainerClass, prop))
return true;
return false;
},
acc() {
if (!this.containerClass)
return {};
if (typeof this.containerClass === 'string' || this.containerClass instanceof String)
return this.containerClass.split(' ').reduce((a,c) => {a[c] = true; return a}, {});
if (Array.isArray(this.containerClass))
return this.containerClass.reduce((a,c) => {a[c] = true; return a}, {});
return this.containerClass;
},
autoContainerClass() {
if (this.noAutoClass)
return this.acc;
const acc = {...this.acc};
if (this.inputGroup)
acc['input-group-item'] = true;
if (this.lcType == 'radio' || this.lcType == 'checkbox')
acc['form-check'] = true;
if (this.inputGroup && acc['form-check']) {
acc['input-group-item'] = false;
acc['form-check'] = false;
acc['input-group-text'] = true;
}
return acc;
},
lcType() {
if (!this.type)
return 'text';
return this.type.toLowerCase();
},
tag() {
switch (this.lcType) {
case 'textarea':
case 'select':
return this.lcType;
case 'datepicker':
return 'VueDatePicker';
case 'autocomplete':
return 'PvAutocomplete';
case 'uploadimage':
return 'UploadImage';
case 'uploadfile':
case 'uploaddms':
return 'UploadDms';
default:
return 'input';
}
},
validationClass() {
const classes = [];
if (this.valid)
classes.push('is-valid');
else if (this.valid === false)
classes.push('is-invalid');
if (!this.noAutoClass) {
let c = this.$attrs.class ? this.$attrs.class.split(' ') : [];
switch (this.lcType) {
// TODO(chris): complete list!
case 'select':
if (!c.includes('form-select'))
classes.push('form-select');
break;
case 'range':
if (!c.includes('form-range'))
classes.push('form-range');
break;
case 'radio':
case 'checkbox':
// TODO(chris): maybe different handling?
if (!c.includes('form-check-input') && !c.includes('btn-check'))
classes.push('form-check-input');
break;
case 'color':
if (!c.includes('form-control-color'))
classes.push('form-control-color');
if (!c.includes('form-control'))
classes.push('form-control');
break;
case 'autocomplete':
case 'datepicker':
classes.push('p-0');
classes.push('border-0');
if (!c.includes('form-control'))
classes.push('form-control');
break;
case 'text':
case 'number':
case 'password':
case 'textarea':
if (!c.includes('form-control'))
classes.push('form-control');
break;
}
}
return classes;
},
feedbackClass() {
if (!this.feedback || this.feedback === true)
return '';
if (!this.bsFeedback)
return {
'valid-tooltip': this.valid === true,
'invalid-tooltip': this.valid === false
};
return {
'valid-feedback': this.valid === true,
'invalid-feedback': this.valid === false
};
},
modelValueCmp: {
get() {
if (this.$attrs.modelValue === undefined)
return this.modelValueDummy;
return this.$attrs.modelValue;
},
set(v) {
if (this.$attrs.modelValue === undefined)
this.modelValueDummy = v;
this.$emit('update:modelValue', v);
}
},
idCmp() {
let uuid = this.$attrs.id;
if (this.lcType == 'datepicker')
uuid = this.$attrs.uid;
if (!uuid && this.$attrs.label)
uuid = 'fhc-form-input';
if (!uuid)
return undefined;
if (this.lcType == 'datepicker')
uuid = 'dp-input-' + uuid;
if (_uuid[uuid] === undefined)
_uuid[uuid] = 0;
return uuid + '-' + (_uuid[uuid]++);
}
},
methods: {
clearValidation() {
this.valid = undefined;
this.feedback = [];
},
clearValidationForThisName() {
if (this.valid === undefined)
return;
if (this.clearValidationForName && this.name)
this.clearValidationForName(this.name);
else
this.clearValidation();
},
setFeedback(valid, feedback) {
if (!feedback)
feedback = [];
if (!Array.isArray(feedback))
feedback = [feedback];
this.valid = valid;
// NOTE(chris): On a list of radios/checkboxes only add the feedback message to the last item
if (this.name && (this.lcType == 'radio' || this.lcType == 'checkbox')) {
const selector = 'input[type="' + this.lcType + '"][name="' + this.name + '"]';
if ([...this.$el.parentNode.querySelectorAll(selector)].pop() != this.$refs.input)
return;
}
this.feedback = feedback;
},
_loadComponents() {
if (this.tag == 'VueDatePicker' && !this._.components.VueDatePicker) {
this._.components.VueDatePicker = Vue.defineAsyncComponent(() => import("../vueDatepicker.js.php"));
} else if (this.tag == 'PvAutocomplete' && !this._.components.PvAutocomplete) {
this._.components.PvAutocomplete = Vue.defineAsyncComponent(() => import(FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/public/js/components/primevue/autocomplete/autocomplete.esm.min.js"));
} else if (this.tag == 'UploadImage' && !this._.components.UploadImage) {
this._.components.UploadImage = Vue.defineAsyncComponent(() => import("./Upload/Image.js"));
} else if (this.tag == 'UploadDms' && !this._.components.UploadDms) {
this._.components.UploadDms = Vue.defineAsyncComponent(() => import("./Upload/Dms.js"));
}
}
},
beforeMount() {
this._loadComponents();
},
beforeUpdate() {
this._loadComponents();
},
mounted() {
if (this.registerToForm)
this.registerToForm(this);
},
template: `
<component :is="!hasContainer ? 'FhcFragment' : 'div'" class="position-relative" :class="autoContainerClass">
<label v-if="$attrs.label && lcType != 'radio' && lcType != 'checkbox'" :for="idCmp">{{$attrs.label}}</label>
<input v-if="tag == 'input'" :type="lcType" ref="input" v-model="modelValueCmp" v-bind="$attrs" :id="idCmp" :name="name" :class="validationClass" :modelValue="undefined" @input="clearValidationForThisName(); $emit('input', $event)">
<textarea v-else-if="tag == 'textarea'" ref="input" v-model="modelValueCmp" v-bind="$attrs" :id="idCmp" :name="name" :class="validationClass" :modelValue="undefined" @input="clearValidationForThisName(); $emit('input', $event)"></textarea>
<select v-else-if="tag == 'select'" ref="input" v-model="modelValueCmp" v-bind="$attrs" :id="idCmp" :name="name" :class="validationClass" :modelValue="undefined" @input="clearValidationForThisName(); $emit('input', $event)">
<slot></slot>
</select>
<component
v-else-if="tag == 'VueDatePicker'"
ref="input"
:is="tag"
:type="type"
v-model="modelValueCmp"
v-bind="$attrs"
:uid="idCmp ? idCmp.substr(9) : idCmp"
:name="name"
:class="validationClass"
:input-class-name=
"[...Object.entries({'form-control': !noAutoClass, 'is-valid': valid === true, 'is-invalid': valid === false}).reduce((a,[k,v]) => {if(v) a.push(k);return a}, []), ...($attrs['input-class-name'] ? $attrs['input-class-name'].split(' ') : [])].join(' ')"
@update:model-value="clearValidationForThisName"
>
<slot></slot>
</component>
<component
v-else-if="tag == 'PvAutocomplete'"
ref="input"
:is="tag"
:type="type"
v-model="modelValueCmp"
v-bind="$attrs"
:id="idCmp"
:input-props="{name}"
:class="validationClass"
:input-class="[...Object.entries({'form-control': !noAutoClass, 'is-valid': valid === true, 'is-invalid': valid === false}).reduce((a,[k,v]) => {if(v) a.push(k);return a}, []), ...($attrs['input-class'] ? $attrs['input-class'].split(' ') : [])].join(' ')"
@update:model-value="clearValidationForThisName"
>
<slot></slot>
</component>
<component
v-else-if="tag == 'UploadDms'"
ref="input"
:is="tag"
:type="type"
v-model="modelValueCmp"
v-bind="$attrs"
:id="idCmp"
:name="name"
:class="validationClass"
:input-class="validationClass"
:no-list="inputGroup"
@update:model-value="clearValidationForThisName"
>
<slot></slot>
</component>
<component
v-else
ref="input"
:is="tag"
:type="type"
v-model="modelValueCmp"
v-bind="$attrs"
:id="idCmp"
:name="name"
:class="validationClass"
@update:model-value="clearValidationForThisName"
>
<slot></slot>
</component>
<label v-if="$attrs.label && (lcType == 'radio' || lcType == 'checkbox')" :for="idCmp" :class="!noAutoClass && 'form-check-label'">{{$attrs.label}}</label>
<div v-if="valid !== undefined && feedback.length && !noFeedback" :class="feedbackClass">
<template v-for="(msg, i) in feedback" :key="i">
<hr v-if="i" class="m-0">
{{msg}}
</template>
</div>
</component>
`
}
+87
View File
@@ -0,0 +1,87 @@
export default {
emits: [
'update:modelValue'
],
props: {
modelValue: {
type: [ FileList, Array ],
required: true
},
multiple: Boolean,
id: String,
name: String,
inputClass: [String, Array, Object],
noList: Boolean
},
methods: {
stringifyFile(file) {
return JSON.stringify({
lastModified: file.lastModified,
lastModifiedDate: file.lastModifiedDate,
name: file.name,
size: file.size,
type: file.type
});
},
addFiles(event) {
if (!this.multiple)
return this.$emit('update:modelValue', event.target.files);
const dt = new DataTransfer();
const doubles = [];
for (var file of this.modelValue) {
dt.items.add(file);
doubles.push(this.stringifyFile(file));
}
for (var file of event.target.files) {
// NOTE(chris): deep check (with FileReader) would require an async function so we only check the basic attributes
if (doubles.indexOf(this.stringifyFile(file)) < 0)
dt.items.add(file);
}
this.$emit('update:modelValue', dt.files);
},
removeFile(id) {
const fileToRemove = Array.from(this.modelValue)[id];
const dt = new DataTransfer();
for (var file of this.modelValue) {
if (file !== fileToRemove)
dt.items.add(file);
}
this.$emit('update:modelValue', dt.files);
}
},
watch: {
modelValue(n) {
if (n instanceof FileList)
return this.$refs.upload.files = n;
const dt = new DataTransfer();
const dms = [];
for (var file of n) {
if (file instanceof File) {
dt.items.add(file);
} else {
const dmsFile = new File([JSON.stringify(file)], file.name, {
type: 'application/x.fhc-dms+json'
});
dt.items.add(dmsFile);
}
}
this.$emit('update:modelValue', dt.files);
}
},
template: `
<div class="form-upload-dms">
<input ref="upload" class="form-control" :class="inputClass" :id="id" :name="name" :multiple="multiple" type="file" @change="addFiles">
<ul v-if="modelValue.length && multiple && !noList" class="list-unstyled m-0">
<li v-for="(file, index) in modelValue" :key="index" class="d-flex mx-1 mt-1 align-items-start">
<span class="col-auto"><i class="fa fa-file me-1"></i></span>
<span class="col">{{ file.name }}</span>
<button class="col-auto btn btn-outline-secondary btn-p-0" @click="removeFile(index)">
<i class="fa fa-close"></i>
</button>
</li>
</ul>
</div>`
}
+62
View File
@@ -0,0 +1,62 @@
export default {
emits: [
'update:modelValue'
],
props: {
modelValue: String
},
computed: {
valueAsBase64DataString() {
if (!this.modelValue || this.modelValue.substring(0, 10) == 'data:image')
return this.modelValue;
return 'data:image/jpeg;charset=utf-8;base64,' + this.modelValue;
}
},
methods: {
openUploadDialog() {
this.$refs.fileInput.click();
},
pickFile() {
let file = this.$refs.fileInput.files;
if (file && file[0]) {
let reader = new FileReader();
reader.onload = e => {
this.$emit('update:modelValue', e.target.result);
}
reader.readAsDataURL(file[0]);
}
},
deleteImage() {
this.$emit('update:modelValue', '');
}
},
template: `
<div class="form-upload-image">
<template v-if="modelValue">
<img class="img-thumbnail" :src="valueAsBase64DataString" />
<div class="fotobutton">
<div class="d-grid gap-2 d-md-flex">
<button type="button" class="btn btn-outline-dark btn-sm" @click="deleteImage">
<i class="fa fa-close"></i>
</button>
<button type="button" class="btn btn-outline-dark btn-sm" @click="openUploadDialog">
<i class="fa fa-pen"></i>
</button>
</div>
</div>
</template>
<template v-else>
<slot>
<svg class="bd-placeholder-img img-thumbnail" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="A generic square placeholder image with a white border around it, making it resemble a photograph taken with an old instant camera: 200x200" preserveAspectRatio="xMidYMid slice" focusable="false"><title>A generic square placeholder image with a white border around it, making it resemble a photograph taken with an old instant camera</title><rect width="100%" height="100%" fill="#868e96"></rect><text x="50%" y="50%" fill="#dee2e6" dy=".3em"></text></svg>
</slot>
<div class="fotobutton-visible">
<div class="d-grid gap-2 d-md-flex">
<button type="button" class="btn btn-outline-dark btn-sm" @click="openUploadDialog">
<i class="fa fa-pen"></i>
</button>
</div>
</div>
</template>
<input :id="$attrs.id" class="d-none" type="file" ref="fileInput" @input="pickFile" accept="image/*">
</div>`
}
+41
View File
@@ -0,0 +1,41 @@
export default {
inject: [
'$registerToForm'
],
data() {
return {
feedback: {
success: [],
danger: []
}
};
},
methods: {
clearValidation() {
this.feedback = {
success: [],
danger: []
};
},
setFeedback(valid, feedback) {
if (!feedback)
feedback = [];
if (!Array.isArray(feedback))
feedback = [feedback];
const ts = Date.now();
this.feedback[valid ? 'success' : 'danger'] = feedback.map(msg => [msg, ts]);
}
},
mounted() {
if (this.$registerToForm)
this.$registerToForm(this);
},
template: `
<template v-for="(arr, key) in feedback" :key="key">
<div v-for="[msg, ts] in arr" :key="ts + msg" class="alert alert-dismissible fade show" :class="'alert-' + key" role="alert">
{{msg}}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</template>
`
};
+5
View File
@@ -0,0 +1,5 @@
export default {
render() {
return (this.$slots && this.$slots.default) ? this.$slots.default() : null;
}
};
@@ -29,8 +29,10 @@ export default {
switch (this.data.status)
{
case 'Erstellt': return 'info';
case 'Pause':
case 'Zurueckgezogen': return 'danger';
case 'Genehmigt': return 'success';
default: return 'info';
default: return 'warning';
}
},
loadUrl() {
@@ -51,8 +53,12 @@ export default {
result => {
this.data = result.data.retval;
if (this.data.status) {
const msg = (this.data.status == 'Pause' && this.data.status_insertvon == "Studienabbruch") ? Vue.computed(() => {
let status = this.$p.t('studierendenantrag/status_stop');
return this.$p.t('studierendenantrag', 'status_x', {status});
}) : Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp}));
this.$emit("setStatus", {
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
msg,
severity: this.statusSeverity
});
}
@@ -29,9 +29,11 @@ export default {
switch (this.data?.status)
{
case 'Erstellt': return 'info';
case 'Genehmigt':
case 'Pause':
case 'Zurueckgezogen': return 'danger';
case 'EinspruchAbgelehnt':
case 'Abgemeldet': return 'success';
default: return 'info';
default: return 'warning';
}
},
loadUrl() {
@@ -52,8 +54,12 @@ export default {
result => {
this.data = result.data.retval;
if (this.data.status) {
const msg = (this.data.status == 'Pause' && this.data.status_insertvon == "Studienabbruch") ? Vue.computed(() => {
let status = this.$p.t('studierendenantrag/status_stop');
return this.$p.t('studierendenantrag', 'status_x', {status});
}) : Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp}));
this.$emit("setStatus", {
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
msg,
severity: this.statusSeverity
});
}
@@ -37,9 +37,12 @@ export default {
switch (this.data.status)
{
case 'Erstellt': return 'info';
case 'Genehmigt': return 'success';
case 'Zurueckgezogen': return 'danger';
default: return 'info';
case 'Pause':
case 'Zurueckgezogen':
case 'Abgelehnt': return 'danger';
case 'Genehmigt':
case 'EmailVersandt': return 'success';
default: return 'warning';
}
},
loadUrl() {
@@ -62,6 +65,18 @@ export default {
return datumUnformatted;
let datum = new Date(datumUnformatted);
return datum.toLocaleDateString();
},
semesterOffsets() {
if (!this.data || !this.data.studiensemester)
return [];
return Object.values(this.data.studiensemester)
.filter(el => !el.disabled)
.map(el => el.studiensemester_kurzbz);
},
semester() {
if (!this.stsem)
return '';
return this.data.semester + this.semesterOffsets.indexOf(this.stsem);
}
},
methods: {
@@ -74,8 +89,12 @@ export default {
result => {
this.data = result.data.retval;
if (this.data.status) {
const msg = (this.data.status == 'Pause' && this.data.status_insertvon == "Studienabbruch") ? Vue.computed(() => {
let status = this.$p.t('studierendenantrag/status_stop');
return this.$p.t('studierendenantrag', 'status_x', {status});
}) : Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp}));
this.$emit("setStatus", {
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
msg,
severity: this.statusSeverity
});
}
@@ -235,7 +254,7 @@ export default {
<tr>
<th>{{$p.t('lehre', 'semester')}}</th>
<td align="right" v-if="data.studierendenantrag_id">{{data.semester}}</td>
<td align="right" v-else>{{stsem === null ? '' : data.studiensemester[stsem].semester}}</td>
<td align="right" v-else>{{semester}}</td>
</tr>
</table>
</div>
@@ -256,7 +275,7 @@ export default {
:id="'studierendenantrag-form-abmeldung-' + uuid + '-stsem'"
@input="currentWiedereinstieg = ''"
>
<option v-for="(stsem, index) in data.studiensemester" :key="index" :value="index">
<option v-for="(stsem, index) in data.studiensemester" :key="index" :value="index" :disabled="stsem.disabled">
{{stsem.studiensemester_kurzbz}}
</option>
</select>
@@ -280,7 +299,7 @@ export default {
</div>
<div v-else>
<select v-model="currentWiedereinstieg" class="form-select">
<option v-for="sem in data.studiensemester[stsem].wiedereinstieg" :key="sem.studiensemester_kurzbz" :value="sem.start">
<option v-for="sem in data.studiensemester[stsem].wiedereinstieg" :key="sem.studiensemester_kurzbz" :value="sem.start" :disabled="sem.disabled">
{{sem.studiensemester_kurzbz}}
</option>
</select>
@@ -35,11 +35,14 @@ export default {
statusSeverity() {
switch (this.data.status)
{
case 'Erstellt': return 'info';
case 'Offen':
case 'Erstellt':
case 'ErsteAufforderungVersandt': return 'info';
case 'Genehmigt': return 'success';
case 'Pause':
case 'Verzichtet':
case 'Abgemeldet': return 'danger';
default: return 'info';
default: return 'warning';
}
},
loadUrl() {
@@ -67,8 +70,12 @@ export default {
this.data.statustyp = this.$p.t('studierendenantrag', 'status_open');
}
this.$emit('update:status', this.data.status);
const msg = (this.data.status == 'Pause' && this.data.status_insertvon == "Studienabbruch") ? Vue.computed(() => {
let status = this.$p.t('studierendenantrag/status_stop');
return this.$p.t('studierendenantrag', 'status_x', {status});
}) : Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp}));
this.$emit("setStatus", {
msg: Vue.computed(() => this.$p.t('studierendenantrag', 'status_x', {status: this.data.statustyp})),
msg,
severity: this.statusSeverity
});
return result;
@@ -184,6 +184,44 @@ export default {
.then(this.showValidation)
.catch(this.showError);
},
actionPause(evt) {
var antraege = evt || this.selectedData;
this.$refs.loader.show();
axios
.all(
antraege.map(
antrag => axios.post(
FHC_JS_DATA_STORAGE_OBJECT.app_root +
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
'/components/Antrag/Leitung/pauseAntrag/',
{
studierendenantrag_id: antrag.studierendenantrag_id
}
)
)
)
.then(this.showValidation)
.catch(this.showError);
},
actionUnpause(evt) {
var antraege = evt || this.selectedData;
this.$refs.loader.show();
axios
.all(
antraege.map(
antrag => axios.post(
FHC_JS_DATA_STORAGE_OBJECT.app_root +
FHC_JS_DATA_STORAGE_OBJECT.ci_router +
'/components/Antrag/Leitung/unpauseAntrag/',
{
studierendenantrag_id: antrag.studierendenantrag_id
}
)
)
)
.then(this.showValidation)
.catch(this.showError);
},
actionObject(evt) {
var antraege = evt || this.selectedData;
this.$refs.loader.show();
@@ -347,6 +385,8 @@ export default {
@action:objectionDeny="actionoObjectionDeny"
@action:objectionApprove="actionObjectionApprove"
@action:cancel="actionCancel"
@action:pause="actionPause"
@action:unpause="actionUnpause"
@reload="reload"
>
</leitung-table>
@@ -25,7 +25,9 @@ export default {
'action:object',
'action:objectionDeny',
'action:objectionApprove',
'action:cancel'
'action:cancel',
'action:pause',
'action:unpause'
],
data() {
return {
@@ -60,6 +62,29 @@ export default {
this.historyData = res.data.retval.sort((a, b) => a.insertamum > b.insertamum);
});
},
getHistoryStatus(data, index) {
if (data.insertvon == 'Studienabbruch')
return this.$p.t('studierendenantrag/status_stop');
if (index > 0 && this.historyData[index-1].studierendenantrag_statustyp_kurzbz == 'Pause') {
if (index > 1 && this.historyData[index-2].studierendenantrag_statustyp_kurzbz != 'Pause') {
// NOTE(chris): this is a AbmeldungStgl Pause right after a manual Pause
if (data.studierendenantrag_statustyp_kurzbz == 'Pause')
return data.typ;
// NOTE(chris): this is a manual Pause resumed
else
return data.typ + ' (' + this.$p.t('studierendenantrag/status_unpaused') + ')';
}
// NOTE(chris): a series of pause stati always starts with a manual and alternate afterwards
let i = 2;
while (index-i > 0 && this.historyData[index-i].studierendenantrag_statustyp_kurzbz == 'Pause') i++;
if (data.studierendenantrag_statustyp_kurzbz == 'Pause')
i++;
return i%2
? data.typ
: data.typ + ' (' + this.$p.t('studierendenantrag/status_unpaused') + ')';
}
return data.typ;
},
showHistoryGrund(grund) {
this.$refs.modalGrund.$el.addEventListener(
'hidden.bs.modal',
@@ -89,7 +114,7 @@ export default {
this.table = new Tabulator(this.$refs.table, {
placeholder:"Keine zu bearbeitenden Datensätze",
movableColumns: true,
maxHeight: '50vh',
height: '65vh',
layout: "fitDataFill",
ajaxURL: this.ajaxUrl + (this.filter || ''),
persistence: { // NOTE(chris): do not store column titles
@@ -153,9 +178,13 @@ export default {
autocomplete: true,
},
formatter: (cell, formatterParams, onRendered) => {
let data = cell.getData();
let status = cell.getValue();
if (data.status_insertvon == 'Studienabbruch' && data.status == 'Pause')
status = this.$p.t('studierendenantrag/status_stop');
let link = document.createElement('a');
link.href = "#";
link.innerHTML = cell.getValue();
link.innerHTML = status;
link.addEventListener('click', e => {
e.preventDefault();
this.lastHistoryClickedId = cell.getData().studierendenantrag_id;
@@ -176,7 +205,7 @@ export default {
}, {
field: 'name',
title: this.$p.t('global', 'name'),
mutator: (value, data) => (data.vorname + ' ' + data.nachname).replace(/^\s*(.*)\s*$/, '$1'),
mutator: (value, data) => (data.nachname + ' ' + data.vorname).replace(/^\s*(.*)\s*$/, '$1'),
headerFilter: 'input'
}, {
field: 'datum',
@@ -234,7 +263,22 @@ export default {
container.className = "d-flex gap-2";
if ((data.typ == 'Abmeldung' || data.typ == 'AbmeldungStgl' || data.typ == 'Unterbrechung') && (data.status == 'Genehmigt' || data.status == 'Beeinsprucht' || data.status == 'EinspruchAbgelehnt' || data.status == 'EmailVersandt')) {
let allowed_status_for_download = [];
switch (data.typ) {
case 'Abmeldung':
allowed_status_for_download = ['Genehmigt'];
break;
case 'AbmeldungStgl':
allowed_status_for_download = ['Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt', 'Abgemeldet'];
break;
case 'Unterbrechung':
allowed_status_for_download = ['Genehmigt', 'EmailVersandt'];
break;
case 'Wiederholung':
allowed_status_for_download = ['Abgemeldet'];
break;
}
if (allowed_status_for_download.includes(data.status)) {
// NOTE(chris): Download PDF
let button = document.createElement('a');
// NOTE(chris): phrasen in attribues don't work if they are not preloaded
@@ -246,6 +290,56 @@ export default {
'content/pdfExport.php?xml=Antrag' + data.typ + '.xml.php&xsl=Antrag' + data.typ + '&id=' + data.studierendenantrag_id + '&output=pdf';
container.append(button);
}
if (data.typ == 'Wiederholung' && (data.status == 'ErsteAufforderungVersandt' || data.status == 'ZweiteAufforderungVersandt')) {
// NOTE(chris): Pause
let button = document.createElement('button');
let icon = document.createElement('i');
let span = document.createElement('span');
icon.className = "fa-solid fa-pause";
icon.setAttribute('aria-hidden', true);
icon.setAttribute('title', this.$p.t('studierendenantrag', 'btn_pause'));
span.className = "fa-sr-only";
span.append(this.$p.t('studierendenantrag', 'btn_pause'));
button.append(icon);
button.append(span);
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:pause', [cell.getData()]));
container.append(button);
}
let canUnpause = data.status == 'Pause' && !['AbmeldungStgl', 'Studienabbruch'].includes(data.status_insertvon);
if (!canUnpause && data.status == 'Pause' && data.status_insertvon == 'AbmeldungStgl') {
canUnpause = cell.getTable().getData().filter(row =>
row.prestudent_id == data.prestudent_id
&& row.typ == 'AbmeldungStgl'
&& row.status == 'Zurueckgezogen'
&& row.status_insertamum == data.status_insertamum
).length;
}
if (canUnpause) {
// NOTE(chris): Unpause
let button = document.createElement('button');
let icon = document.createElement('i');
let span = document.createElement('span');
icon.className = "fa-solid fa-play";
icon.setAttribute('aria-hidden', true);
icon.setAttribute('title', this.$p.t('studierendenantrag', 'btn_unpause'));
span.className = "fa-sr-only";
span.append(this.$p.t('studierendenantrag', 'btn_unpause'));
button.append(icon);
button.append(span);
button.className = "btn btn-outline-secondary";
button.addEventListener('click', () => this.$emit('action:unpause', [cell.getData()]));
container.append(button);
}
if (data.typ == 'AbmeldungStgl' && data.status == 'Genehmigt') {
// NOTE(chris): Object
let button = document.createElement('button');
@@ -377,10 +471,10 @@ export default {
<template #title>{{$p.t('studierendenantrag', 'title_history', {id: lastHistoryClickedId})}}</template>
<core-fetch-cmpt ref="historyLoader" :api-function="getHistory">
<table v-if="historyData.length" class="table">
<tr v-for="status in historyData" :key="status.studierendenantrag_status_id">
<tr v-for="(status, index) in historyData" :key="status.studierendenantrag_status_id">
<td>{{(new Date(status.insertamum)).toLocaleString()}}</td>
<td>{{status.insertvon}}</td>
<td>{{status.typ}}</td>
<td>{{getHistoryStatus(status, index)}}</td>
<td>
<a v-if="status.grund" href="#modal-grund" data-bs-toggle="modal" @click="showHistoryGrund(status.grund)">
{{$p.t('studierendenantrag', 'antrag_grund')}}
+67 -25
View File
@@ -1,3 +1,4 @@
import { markRaw, defineAsyncComponent } from 'vue';
import {CoreRESTClient} from '../RESTClient.js';
import accessibility from "../directives/accessibility.js";
@@ -6,12 +7,19 @@ export default {
accessibility
},
emits: [
'update:modelValue'
'update:modelValue',
'change',
'changed'
],
props: {
configUrl: String,
config: {
type: [String, Object],
required: true
},
default: String,
modelValue: [String, Number, Boolean, Array, Object, Date, Function, Symbol]
modelValue: [String, Number, Boolean, Array, Object, Date, Function, Symbol],
vertical: Boolean,
border: Boolean
},
data() {
return {
@@ -35,51 +43,85 @@ export default {
}
}
},
created() {
CoreRESTClient
.get(this.configUrl)
.then(result => CoreRESTClient.getData(result.data))
.then(result => {
const tabs = {};
// TODO(chris): check if result is array
Object.entries(result).forEach(([key, config]) => {
if (!config.component)
watch: {
config(n) {
this.initConfig(n);
}
},
methods: {
change(key) {
this.$emit("change", key)
this.current = key;
this.$nextTick(() => this.$emit("changed", key));
},
initConfig(config) {
if (!config)
return;
if (typeof config === 'string' || config instanceof String)
return CoreRESTClient.get(config)
.then(result => CoreRESTClient.getData(result.data))
.then(this.initConfig)
.catch(this.$fhcAlert.handleSystemError);
const tabs = {};
if (Array.isArray(config)) {
config.forEach((item, key) => {
if (!item.component)
return console.error('Component missing for ' + key);
tabs[key] = {
component: Vue.markRaw(Vue.defineAsyncComponent(() => import(config.component))),
title: config.title || key,
config: config.config,
component: markRaw(defineAsyncComponent(() => import(item.component))),
title: item.title || key,
config: item.config,
key
}
});
} else {
Object.entries(config).forEach(([key, item]) => {
if (!item.component)
return console.error('Component missing for ' + key);
tabs[key] = {
component: markRaw(defineAsyncComponent(() => import(item.component))),
title: item.title || key,
config: item.config,
key
}
});
}
if (this.current === null || !tabs[this.current]) {
if (tabs[this.default])
this.current = this.default;
else
this.current = Object.keys(tabs)[0];
this.tabs = tabs;
})
.catch(this.$fhcAlert.handleSystemError);
}
this.tabs = tabs;
}
},
created() {
this.initConfig(this.config);
},
template: `
<div class="fhc-tabs d-flex flex-column">
<div class="nav nav-tabs">
<div class="fhc-tabs d-flex" :class="vertical ? 'align-items-stretch gap-3' : (border ? 'flex-column' : 'flex-column gap-3')" v-if="Object.keys(tabs).length">
<div class="nav" :class="vertical ? 'nav-pills flex-column' : 'nav-tabs'">
<div
v-for="tab in tabs"
:key="tab.key"
class="nav-item nav-link"
:class="{active: tab.key == current}"
@click="current=tab.key"
@click="change(tab.key)"
:aria-current="tab.key == current ? 'page' : ''"
v-accessibility:tab
v-accessibility:tab.[vertical]
>
{{tab.title}}
</div>
</div>
<div style="flex: 1 1 0%; height: 0%" class="border-bottom border-start border-end overflow-auto p-3">
<div :style="vertical ? '' : 'flex: 1 1 0%; height: 0%'" class="overflow-auto flex-grow-1" :class="vertical || !border ? '' : 'p-3 border-bottom border-start border-end'">
<keep-alive>
<component :is="currentTab.component" v-model="value" :config="currentTab.config"></component>
<component ref="current" :is="currentTab.component" v-model="value" :config="currentTab.config"></component>
</keep-alive>
</div>
</div>`
};
};
+19 -7
View File
@@ -15,6 +15,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { TabulatorFull as Tabulator } from 'tabulator-tables';
import {CoreFilterAPIs} from './API.js';
import {CoreRESTClient} from '../../RESTClient.js';
import {CoreFetchCmpt} from '../../components/Fetch.js';
@@ -136,9 +137,9 @@ export const CoreFilterCmpt = {
for (let col of columns)
{
// If the column has to be displayed or not
col.visible = selectedFields.indexOf(col.field) >= 0;
if (col.formatter == 'rowSelection')
col.visible = true;
/* fields.indexOf(col.field) == -1; ensures displaying formatter colums
e.g. column with rowSelection checkboxes or with custom formatted action buttons */
col.visible = selectedFields.indexOf(col.field) >= 0 || fields.indexOf(col.field) == -1;
if (col.hasOwnProperty('resizable'))
col.resizable = col.visible;
@@ -185,13 +186,23 @@ export const CoreFilterCmpt = {
else
this.getFilter();
},
initTabulator() {
async initTabulator() {
let placeholder = '< Phrasen Plugin not loaded! >';
if (this.$p) {
await this.$p.loadCategory('ui');
placeholder = this.$p.t('ui/keineDatenVorhanden');
}
// Define a default tabulator options in case it was not provided
let tabulatorOptions = {...{
height: 500,
layout: "fitColumns",
layout: "fitDataStretch",
movableColumns: true,
reactiveData: true
columnDefaults:{
tooltip: true,
},
placeholder,
reactiveData: true,
persistence: true
}, ...(this.tabulatorOptions || {})};
if (!this.tableOnly) {
@@ -265,6 +276,7 @@ export const CoreFilterCmpt = {
this.filterName = data.filterName;
this.dataset = data.dataset;
this.datasetMetadata = data.datasetMetadata;
this.fields = data.fields;
this.selectedFields = data.selectedFields;
this.notSelectedFields = this.fields.filter(x => this.selectedFields.indexOf(x) === -1);
@@ -435,7 +447,7 @@ export const CoreFilterCmpt = {
*
*/
handlerRemoveCustomFilter: function(event) {
filterId = event.currentTarget.getAttribute("href").substring(1);
let filterId = event.currentTarget.getAttribute("href").substring(1);
if (filterId === this.selectedFilter)
this.selectedFilter = null;
//
+54
View File
@@ -0,0 +1,54 @@
/**
* Copyright (C) 2022 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/>.
*/
export default {
props: {
title: '',
subtitle: '',
mainCols: {
type: Array,
default: []
},
asideCols: {
type: Array,
default: []
},
},
computed: {
mainGridCols() {
return this.mainCols.length > 0 ? `col-md-${this.mainCols[0]}` : "col-md-12";
},
asideGridCols() {
return this.asideCols.length > 0 ? `col-md-${this.asideCols[0]}` : "";
}
},
template: `
<div class="overflow-hidden">
<header v-if="title">
<h1 class="h2 mb-5">{{ title }}<span class="fhc-subtitle">{{ subtitle }}</span></h1>
</header>
<div class="row gx-5">
<main :class="mainGridCols">
<slot name="main">{{ mainGridCols }}</slot>
</main>
<aside v-if="asideCols.length > 0" :class="asideGridCols">
<slot name="aside">{{ asideGridCols }}</slot>
</aside>
</div>
</div>
`
};
+5 -1
View File
@@ -103,7 +103,11 @@ export default {
this.showsearchresult();
this.searchfunction(this.searchsettings)
.then(function(response) {
that.searchresult = response.data.data;
if( response.data?.error === 1 ) {
that.error = 'Bei der Suche ist ein Fehler aufgetreten.';
} else {
that.searchresult = response.data.data;
}
})
.catch(function(error) {
that.error = 'Bei der Suche ist ein Fehler aufgetreten.'
+7 -5
View File
@@ -1,3 +1,5 @@
import { ref, unref, triggerRef } from 'vue';
const categories = {};
const loadingModules = {};
@@ -12,8 +14,8 @@ function reloadRefs(category) {
while (loadingModules[category].length) {
var v = loadingModules[category].pop();
v[0].value = getValueForLoadedPhrase(category, v[1], v[2]);
Vue.triggerRef(v[0]);
/*Vue.unref(v);*/
triggerRef(v[0]);
/*unref(v);*/
}
}
function loadLazy(category, val, phrase, params) {
@@ -70,16 +72,16 @@ const phrasen = {
if (!categories[category] || Object.keys(categories[category]).length === 0) {
categories[category] = undefined;
let val = Vue.ref(initialval);
let val = ref(initialval);
loadLazy(category, val, phrase, params);
return val;
}
}
var result = getValueForLoadedPhrase(category, phrase, params);
return Vue.ref(result);
return ref(result);
},
t(category, phrase, params) {
return Vue.unref(this.t_ref(category, phrase, params));
return unref(this.t_ref(category, phrase, params));
}
};
+20 -12
View File
@@ -92,16 +92,24 @@
* @param mixed message
* @return void
*/
/*
import PvConfig from "../../../index.ci.php/public/js/components/primevue/config/config.esm.min.js";
import PvToast from "../../../index.ci.php/public/js/components/primevue/toast/toast.esm.min.js";
import PvConfirm from "../../../index.ci.php/public/js/components/primevue/confirmdialog/confirmdialog.esm.min.js";
import PvConfirmationService from "../../../index.ci.php/public/js/components/primevue/confirmationservice/confirmationservice.esm.min.js";
*/
import { createApp } from 'vue';
import PvConfig from 'primevue/config';
import PvToast from 'primevue/toast';
import PvConfirm from 'primevue/confirmdialog';
import PvConfirmationService from 'primevue/confirmationservice';
import {CoreRESTClient} from '../RESTClient.js';
const helperAppContainer = document.createElement('div');
const helperApp = Vue.createApp({
const helperApp = createApp({
components: {
PvToast,
PvConfirm
@@ -133,8 +141,8 @@ const helperApp = Vue.createApp({
helperAppContainer.parentElement.removeChild(helperAppContainer);
},
template: `
<pv-toast ref="toast" base-z-index="99999"></pv-toast>
<pv-toast ref="alert" base-z-index="99999" position="center">
<pv-toast ref="toast" class="fhc-alert" :base-z-index="99999"></pv-toast>
<pv-toast ref="alert" class="fhc-alert" :base-z-index="99999" position="center">
<template #message="slotProps">
<i class="fa fa-circle-exclamation fa-2xl mt-3"></i>
<div class="p-toast-message-text">
@@ -161,7 +169,7 @@ const helperApp = Vue.createApp({
</a>
</div>
<div ref="messageCard" :id="'fhcAlertCollapseMessageCard' + slotProps.message.id" class="collapse mt-3">
<div class="card card-body text-body small" style="white-space: pre-wrap">
<div class="card card-body text-body small">
{{slotProps.message.detail}}
</div>
</div>
@@ -237,7 +245,7 @@ export default {
alertMultiple(messageArray, severity = 'info', title = 'Info', sticky = false){
// Check, if array has only string values
if (messageArray.every(message => typeof message === 'string')) {
messageArray.every(message => this.alertDefault(severity, title, message, sticky));
messageArray.forEach(message => this.alertDefault(severity, title, message, sticky));
return true;
}
return false;
@@ -281,21 +289,21 @@ export default {
handleSystemMessage(message) {
// Message is string
if (typeof message === 'string')
return fhcerror.alertWarning(message);
return $fhcAlert.alertWarning(message);
// Message is array of strings
if (Array.isArray(message)) {
// If Array has only Strings
if (message.every(msg => typeof msg === 'string'))
return message.every(fhcerror.alertWarning);
return message.every($fhcAlert.alertWarning);
// If Array has only Objects
if (message.every(msg => typeof msg === 'object') && msg !== null) {
return message.every(msg => {
if (msg.hasOwnProperty('data') && msg.data.hasOwnProperty('retval')) {
fhcerror.alertWarning(JSON.stringify(msg.data.retval));
$fhcAlert.alertWarning(JSON.stringify(msg.data.retval));
} else {
fhcerror.alertSystemError(JSON.stringify(msg));
$fhcAlert.alertSystemError(JSON.stringify(msg));
}
});
}
@@ -305,15 +313,15 @@ export default {
if (typeof message === 'object' && message !== null){
if (message.hasOwnProperty('data') && message.data.hasOwnProperty('retval')) {
// NOTE(chris): changed: alertSystemError => alertWarning
fhcerror.alertWarning(JSON.stringify(message.data.retval));
$fhcAlert.alertWarning(JSON.stringify(message.data.retval));
} else {
fhcerror.alertSystemError(JSON.stringify(message));
$fhcAlert.alertSystemError(JSON.stringify(message));
}
return;
}
// Fallback
fhcerror.alertSystemError('alertSystemError throws Generic Error\r\nError Controller Path: ' + FHC_JS_DATA_STORAGE_OBJECT.called_path + '/' + FHC_JS_DATA_STORAGE_OBJECT.called_method);
$fhcAlert.alertSystemError('alertSystemError throws Generic Error\r\nError Controller Path: ' + FHC_JS_DATA_STORAGE_OBJECT.called_path + '/' + FHC_JS_DATA_STORAGE_OBJECT.called_method);
},
resetFormValidation(form) {
const event = new Event('fhc-form-reset');
+282
View File
@@ -0,0 +1,282 @@
import FhcAlert from './FhcAlert.js';
import FhcApiFactory from '../apps/api/fhcapifactory.js';
export default {
install: (app, options) => {
app.use(FhcAlert);
function _get_config(form, uri, data, config) {
if (typeof form == 'string' && config === undefined) {
[uri, data, config] = [form, uri, data];
form = undefined;
} else if (form) {
if (typeof form != 'object')
throw new TypeError('Parameter 1 of _get_config must be an object or a string');
if (uri === undefined && data === undefined && config === undefined) {
config = form;
form = undefined;
}
}
if (form) {
// NOTE(chris): check if form is fhc-form
if (!form.clearValidation || !form.setFeedback)
throw new TypeError("'form' is not a Form Component");
form = {
clearValidation: form.clearValidation,
setFeedback: form.setFeedback
};
if (config)
config.form = form;
else
config = {form};
}
return [uri, data, config];
}
function _clean_return_value(response) {
const result = response.data;
delete response.data;
if (!result.meta)
result.meta = {response};
else
result.meta.response = response;
return result;
}
const fhcApiAxios = axios.create({
timeout: 5000,
baseURL: FHC_JS_DATA_STORAGE_OBJECT.app_root + FHC_JS_DATA_STORAGE_OBJECT.ci_router + "/"
});
fhcApiAxios.interceptors.request.use(config => {
if (config.method != 'post' || !config.data)
return config;
if (config.data instanceof FormData)
return config;
if (!Object.values(config.data).every(item => {
if (item instanceof FileList)
return false;
if (Array.isArray(item))
return item.every(i => !(i instanceof File));
return true;
})) {
const newData = Object.entries(config.data).reduce((nd, [key, item]) => {
if (item instanceof FileList) {
for (const file of item)
nd.FormData.append(key + (item.length > 1 ? '[]' : ''), file);
} else if (Array.isArray(item)) {
if (item.every(i => !(i instanceof File))) {
nd.jsondata[key] = item;
} else {
item.forEach(file => nd.FormData.append(key + (item.length > 1 ? '[]' : ''), file));
}
} else {
nd.jsondata[key] = item;
}
return nd;
}, {
FormData: new FormData(),
jsondata: {}
});
newData.FormData.append('_jsondata', JSON.stringify(newData.jsondata));
config.data = newData.FormData;
}
return config;
});
fhcApiAxios.interceptors.response.use(response => {
if (response.config?.errorHandling == 'off'
|| response.config?.errorHandling === false
|| response.config?.errorHandling == 'fail')
return _clean_return_value(response);
// NOTE(chris): loop through errors
if (response.data.errors)
response.data.errors = response.data.errors.filter(
err => (response.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$fhcApi._defaultErrorHandlers[err.type])(err, response.config.form)
);
return _clean_return_value(response);
}, error => {
if (error.code == 'ERR_CANCELED')
return new Promise(() => {});
if (error.config?.errorHandling == 'off'
|| error.config?.errorHandling === false
|| error.config?.errorHandling == 'success')
return Promise.reject(error);
if (error.response) {
if (error.response.status == 404) {
app.config.globalProperties.$fhcAlert.alertDefault('error', error.message, error.request.responseURL, true);
return new Promise(() => {});
}
// NOTE(chris): loop through errors
error.response.data.errors = error.response.data.errors.filter(
err => (error.config[err.type + 'ErrorHandler'] || app.config.globalProperties.$fhcApi._defaultErrorHandlers[err.type])(err, error.config.form)
);
if (!error.response.data.errors.length)
return new Promise(() => {});
} else if (error.request) {
app.config.globalProperties.$fhcAlert.alertDefault('error', error.message, error.request.responseURL);
return new Promise(() => {});
} else {
app.config.globalProperties.$fhcAlert.alertError(error.message);
return new Promise(() => {});
}
return Promise.reject(error);
});
app.config.globalProperties.$fhcApi = {
get(form, uri, params, config) {
[uri, params, config] = _get_config(form, uri, params, config);
if (params) {
if (config)
config.params = params;
else
config = {params};
}
return fhcApiAxios.get(uri, config);
},
post(form, uri, data, config) {
[uri, data, config] = _get_config(form, uri, data, config);
return fhcApiAxios.post(uri, data, config);
},
_defaultErrorHandlers: {
validation(error, form) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
if (form) {
form.clearValidation();
form.setFeedback(false, error.messages);
return false;
}
if (Array.isArray(error.messages)) {
error.messages.forEach($fhcAlert.alertError);
return false;
} else if (typeof error.messages == 'object') {
Object.entries(error.messages).forEach(
([key, value]) => $fhcAlert.alertDefault('error', key, value, true)
);
return false;
}
return true;
},
general(error, form) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
if (form)
form.setFeedback(false, error.message);
else
$fhcAlert.alertError(error.message);
},
php(error) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
var message = '';
message += 'Message: ' + error.message + '\n\n';
message += 'Filename: ' + error.filename + '\n';
message += 'Line Number: ' + error.line + '\n';
if (error.backtrace && error.backtrace.length) {
message += '\nBacktrace: ';
error.backtrace.forEach(err => {
message += '\n\tFile: ' + err.file + '\n';
message += '\tLine: ' + err.line + '\n';
message += '\tFunction: ' + err.function + '\n';
});
}
switch (error.severity) {
case 'Warning':
case 'Core Warning':
case 'Compile Warning':
case 'User Warning':
$fhcAlert.alertDefault('warn', 'PHP ' + error.severity, message, true);
break;
case 'Notice':
case 'User Notice':
case 'Runtime Notice':
$fhcAlert.alertDefault('info', 'PHP ' + error.severity, message, true);
break;
default:
message = 'Type: PHP ' + error.severity + '\n\n' + message;
$fhcAlert.alertSystemError(message);
break;
}
},
exception(error) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
var message = '';
message += 'Type: ' + error.class + '\n\n';
message += 'Message: ' + error.message + '\n\n';
message += 'Filename: ' + error.filename + '\n';
message += 'Line Number: ' + error.line + '\n';
if (error.backtrace && error.backtrace.length) {
message += '\nBacktrace: ';
error.backtrace.forEach(err => {
message += '\n\tFile: ' + err.file + '\n';
message += '\tLine: ' + err.line + '\n';
message += '\tFunction: ' + err.function + '\n';
});
}
$fhcAlert.alertSystemError(message);
},
db(error) {
const $fhcAlert = app.config.globalProperties.$fhcAlert;
var message = '';
if (error.heading !== undefined)
message += error.heading + '\n\n';
if (error.code !== undefined)
message += 'Code: ' + error.code + '\n\n';
if (error.sql !== undefined)
message += 'SQL: ' + error.sql + '\n\n';
if (error.message !== undefined)
message += 'Message: ' + error.message + '\n\n';
else if (error.messages !== undefined)
message += 'Messages: ' + error.messages.join('\n\t') + '\n\n';
if (error.filename !== undefined)
message += 'Filename: ' + error.filename + '\n';
if (error.line !== undefined)
message += 'Line Number: ' + error.line + '\n';
$fhcAlert.alertSystemError(message);
}
}
};
class FhcApiFactoryWrapper {
constructor(factorypart, root) {
if (root === undefined)
this.$fhcApi = app.config.globalProperties.$fhcApi;
else
Object.defineProperty(this, '$fhcApi', {
get() {
return (root || this).$fhcApi;
}
})
Object.keys(factorypart).forEach(key => {
Object.defineProperty(this, key, {
get() {
if (typeof factorypart[key] == 'function')
return factorypart[key].bind(this);
return new FhcApiFactoryWrapper(factorypart[key], root || this);
}
});
});
}
}
app.config.globalProperties.$fhcApi.factory = new FhcApiFactoryWrapper(FhcApiFactory);
}
};
+5 -3
View File
@@ -1,4 +1,6 @@
const categories = Vue.reactive({});
import { reactive, computed } from 'vue';
const categories = reactive({});
const loadingModules = {};
function extractCategory(obj, category) {
@@ -35,7 +37,7 @@ const phrasen = {
},
t_ref(category, phrase, params) {
console.warn('depricated');
return Vue.computed(() => this.t(category, phrase, params));
return computed(() => this.t(category, phrase, params));
},
t(category, phrase, params) {
if (params === undefined && (
@@ -49,7 +51,7 @@ const phrasen = {
console.error('invalid input', category, phrase, params);
return '';
}
let val = Vue.computed(() => {
let val = computed(() => {
if (!categories[category])
return '';
return getValueForLoadedPhrase(category, phrase, params);
+1 -1
View File
@@ -36,7 +36,7 @@ else
$query = "
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, public.get_absem_prestudent(a.prestudent_id, NULL) AS semester, a.grund
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, pss.ausbildungssemester AS semester, a.grund
FROM
campus.tbl_studierendenantrag a
JOIN public.tbl_student USING (prestudent_id)
+3 -3
View File
@@ -14,7 +14,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
$id = $_GET['id'];
$where = " WHERE studierendenantrag_id = " . $db->db_add_param($id) . "
AND a.typ = 'AbmeldungStgl' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) IN ('Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt');";
AND a.typ = 'AbmeldungStgl' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) IN ('Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt', 'Abgemeldet');";
$not_found_error = 'Studierendenantrag not found'. $id;
} elseif(isset($_GET['uid']) && isset($_GET['prestudent_id'])) {
$uid = $_GET['uid'];
@@ -26,7 +26,7 @@ if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
$prestudent_id = (array_filter($prestudent_id, 'strlen'));
$where = " WHERE a.prestudent_id in (" . $db->db_implode4SQL($prestudent_id) . ")
AND a.typ = 'AbmeldungStgl' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) IN ('Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt');";
AND a.typ = 'AbmeldungStgl' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) IN ('Genehmigt', 'Beeinsprucht', 'EinspruchAbgelehnt', 'Abgemeldet');";
$not_found_error = 'Studierendenantrag not found for: ' . implode(',', $uid);
} else
die('<error>wrong parameters</error>');
@@ -36,7 +36,7 @@ else
$query = "
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, public.get_absem_prestudent(a.prestudent_id, NULL) AS semester, a.grund
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, pss.ausbildungssemester AS semester, a.grund
FROM
campus.tbl_studierendenantrag a
JOIN public.tbl_student USING (prestudent_id)
+1 -1
View File
@@ -37,7 +37,7 @@ else
$query = "
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, public.get_absem_prestudent(a.prestudent_id, NULL) AS semester, a.grund, datum_wiedereinstieg, a.datum
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, pss.ausbildungssemester AS semester, a.grund, datum_wiedereinstieg, a.datum
FROM
campus.tbl_studierendenantrag a
JOIN public.tbl_student USING (prestudent_id)
+70
View File
@@ -0,0 +1,70 @@
<?php
header("Content-type: application/xhtml+xml");
require_once('../config/vilesci.config.inc.php');
require_once('../include/functions.inc.php');
require_once('../include/basis_db.class.php');
$db = new basis_db();
if (isset($_REQUEST["xmlformat"]) && $_REQUEST["xmlformat"] == "xml")
{
if(isset($_GET['id'])) {
$id = $_GET['id'];
$where = " WHERE studierendenantrag_id = " . $db->db_add_param($id) . "
AND a.typ = 'Wiederholung' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) = 'Abgemeldet';";
$not_found_error = 'Studierendenantrag not found'. $id;
} elseif(isset($_GET['uid']) && isset($_GET['prestudent_id'])) {
$uid = $_GET['uid'];
$uid = explode(';', $uid);
$uid = (array_filter($uid, 'strlen'));
$prestudent_id = $_GET['prestudent_id'];
$prestudent_id = explode(';', $prestudent_id);
$prestudent_id = (array_filter($prestudent_id, 'strlen'));
$where = " WHERE a.prestudent_id in (" . $db->db_implode4SQL($prestudent_id) . ")
AND a.typ = 'Wiederholung' AND campus.get_status_studierendenantrag(a.studierendenantrag_id) = 'Abgemeldet';";
$not_found_error = 'Studierendenantrag not found for: ' . implode(',', $uid);
} else
die('<error>wrong parameters</error>');
}
else
die('<error>Format not supported</error>');
$query = "
SELECT stg.bezeichnung, bezeichnung_mehrsprachig[(SELECT index FROM public.tbl_sprache WHERE sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . ")], studierendenantrag_id, matrikelnr, studienjahr_kurzbz, a.studiensemester_kurzbz, vorname, nachname, studiengang_kz, pss.ausbildungssemester AS semester, (SELECT pt.text FROM system.tbl_phrase p JOIN system.tbl_phrasentext pt USING(phrase_id) WHERE p.category=" . $db->db_add_param('studierendenantrag', FHC_STRING) . " AND p.phrase=" . $db->db_add_param('grund_Wiederholung_deadline', FHC_STRING) . " AND pt.sprache=" . $db->db_add_param(getSprache(), FHC_STRING) . " LIMIT 1) AS grund
FROM
campus.tbl_studierendenantrag a
JOIN public.tbl_student USING (prestudent_id)
JOIN public.tbl_benutzer ON tbl_student.student_uid=uid
JOIN public.tbl_person USING (person_id)
JOIN public.tbl_studiengang stg USING (studiengang_kz)
JOIN public.tbl_studiensemester USING (studiensemester_kurzbz)
LEFT JOIN public.tbl_prestudentstatus pss ON (pss.prestudent_id = a.prestudent_id AND pss.studiensemester_kurzbz=a.studiensemester_kurzbz AND pss.status_kurzbz=get_rolle_prestudent(a.prestudent_id, a.studiensemester_kurzbz))
LEFT JOIN lehre.tbl_studienplan plan USING (studienplan_id)
JOIN bis.tbl_orgform ON (tbl_orgform.orgform_kurzbz = COALESCE(plan.orgform_kurzbz, pss.orgform_kurzbz, stg.orgform_kurzbz))" . $where;
if (!$db->db_query($query) || !$db->db_num_rows())
die('<error>' . $not_found_error . '</error>');
?>
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<antraege>
<?php while($row = $db->db_fetch_object()) { ?>
<antrag>
<name><![CDATA[<?= trim($row->vorname . ' ' . $row->nachname); ?>]]></name>
<studiengang><![CDATA[<?= $row->bezeichnung; ?>]]></studiengang>
<organisationsform><![CDATA[<?= $row->bezeichnung_mehrsprachig; ?>]]></organisationsform>
<personenkz><![CDATA[<?= $row->matrikelnr; ?>]]></personenkz>
<studienjahr><![CDATA[<?= $row->studienjahr_kurzbz; ?>]]></studienjahr>
<studiensemester><![CDATA[<?= $row->studiensemester_kurzbz; ?>]]></studiensemester>
<semester><![CDATA[<?= $row->semester; ?>]]></semester>
<grund><![CDATA[<?= $row->grund; ?>]]></grund>
</antrag>
<?php } ?>
</antraege>
+11 -3
View File
@@ -34,6 +34,11 @@ require_once('../include/entwicklungsteam.class.php');
require_once('../include/datum.class.php');
require_once('../include/studiengang.class.php');
if(isset($_GET['entwicklungsteam_id']))
$entwicklungsteam_id = $_GET['entwicklungsteam_id'];
else
$entwicklungsteam_id = '';
if(isset($_GET['mitarbeiter_uid']))
$mitarbeiter_uid = $_GET['mitarbeiter_uid'];
else
@@ -44,6 +49,7 @@ if(isset($_GET['studiengang_kz']))
else
$studiengang_kz = '';
$datum = new datum();
$stg = new studiengang();
$stg->getAll(null, false);
@@ -70,8 +76,10 @@ foreach ($entwicklungsteam->result as $row)
{
echo '
<RDF:li>
<RDF:Description id="'.$row->mitarbeiter_uid.'/'.$row->studiengang_kz.'" about="'.$rdf_url.'/'.$row->mitarbeiter_uid.'/'.$row->studiengang_kz.'" >
<ENTWICKLUNGSTEAM:mitarbeiter_uid><![CDATA['.$row->mitarbeiter_uid.']]></ENTWICKLUNGSTEAM:mitarbeiter_uid>
<RDF:Description id="'.$row->mitarbeiter_uid.'/'.$row->studiengang_kz.'/'.$row->entwicklungsteam_id.'"
about="'.$rdf_url.'/'.$row->mitarbeiter_uid.'/'.$row->studiengang_kz.'/'.$row->entwicklungsteam_id.'" >
<ENTWICKLUNGSTEAM:entwicklungsteam_id><![CDATA['.$row->entwicklungsteam_id.']]></ENTWICKLUNGSTEAM:entwicklungsteam_id>
<ENTWICKLUNGSTEAM:mitarbeiter_uid><![CDATA['.$row->mitarbeiter_uid.']]></ENTWICKLUNGSTEAM:mitarbeiter_uid>
<ENTWICKLUNGSTEAM:studiengang_kz><![CDATA['.$row->studiengang_kz.']]></ENTWICKLUNGSTEAM:studiengang_kz>
<ENTWICKLUNGSTEAM:besqualcode><![CDATA['.$row->besqualcode.']]></ENTWICKLUNGSTEAM:besqualcode>
<ENTWICKLUNGSTEAM:besqual><![CDATA['.$row->besqual.']]></ENTWICKLUNGSTEAM:besqual>
@@ -86,4 +94,4 @@ foreach ($entwicklungsteam->result as $row)
}
?>
</RDF:Seq>
</RDF:RDF>
</RDF:RDF>
+5
View File
@@ -80,6 +80,10 @@ function draw_studienerfolg($uid, $studiensemester_kurzbz)
$prestudentstatus = new prestudent();
$prestudentstatus->getLastStatus($student->prestudent_id,'','Student');
$prestudent = new prestudent();
$prestudent->getLastStatus($student->prestudent_id);
$last_status = $prestudent->status_kurzbz;
if($studiensemester_aktuell!=$prestudentstatus->studiensemester_kurzbz)
$studiensemester_aktuell = $prestudentstatus->studiensemester_kurzbz;
@@ -154,6 +158,7 @@ function draw_studienerfolg($uid, $studiensemester_kurzbz)
$xml .= " <studienerfolg>";
$xml .= " <logopath>".DOC_ROOT."skin/images/</logopath>";
$xml .= " <studiensemester>".$row->sembezeichnung."</studiensemester>";
$xml .= " <last_prestudentstatus>".$last_status."</last_prestudentstatus>";
$xml .= " <studiensemester_aktuell>".$studiensemester_aktuell."</studiensemester_aktuell>";
$xml .= " <studiensemester_aktuell_beschreibung>".(($studiensemester->beschreibung != NULL) ? $studiensemester->beschreibung : $studiensemester_aktuell)."</studiensemester_aktuell_beschreibung>";
$xml .= " <semester>".$row->semester."</semester>";
+25
View File
@@ -0,0 +1,25 @@
***NVM installieren***
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
oder
wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
***Node.js installieren***
nvm install --lts
***package.json***
npm install
***Rollup build***
einmalig:
npm run build
als watch bei Änderungen:
npm run watch
+99
View File
@@ -0,0 +1,99 @@
import babel from '@rollup/plugin-babel';
import nodeResolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import vue from "rollup-plugin-vue";
import { globSync } from 'glob';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import postcss from 'rollup-plugin-postcss';
import replace from '@rollup/plugin-replace';
import alias from '@rollup/plugin-alias';
import { existsSync } from 'node:fs';
import terser from '@rollup/plugin-terser';
import json from '@rollup/plugin-json';
function FhcResolver () {
return {
name: 'fhc-resolver', // this name will show up in logs and errors
resolveId ( source, importer, options ) {
if( source.includes('.php') ) {
return false;
}
//console.log('source: ' + source + ' options.isEntry: ' + options.isEntry + ' importer: ' + importer);
if(importer !== undefined && !options.isEntry && !path.isAbsolute(source)) {
let tmp = path.dirname(importer);
if( importer.includes('/application/') ) {
tmp = tmp.replace(/public\/js\//, 'js/').replace(/\/application\//, '/public/');
}
const resolved = path.resolve(tmp, source);
//console.log(resolved);
if( existsSync(resolved) ) {
return resolved
}
}
return null; // other ids should be handled as usually
}
};
}
export default {
input: Object.fromEntries(
globSync('public/**/js/apps/**/*.js', {follow: true, realpath: true}).map(file => {
if( path.dirname(file).includes('/dist/') || path.dirname(file).includes('/apps/vbform') ) {
return null;
}
// This remove `src/` as well as the file extension from each
// file, so e.g. src/nested/foo.js becomes nested/foo
return [path.relative(
'',
file.slice(0, file.length - path.extname(file).length)
).replace(/public\//, 'public/dist/'),
// This expands the relative paths to absolute paths, so e.g.
// src/nested/foo becomes /project/src/nested/foo.js
fileURLToPath(new URL(file, import.meta.url))]
}).filter(Boolean)
),
plugins: [
alias({
entries: {
vue: 'vue/dist/vue.esm-bundler.js'
}
}),
nodeResolve({
preferBuiltins: true,
moduleDirectories: ['node_modules'],
modulePaths: globSync('application/extensions/*/node_modules', {follow: true, realpath: true}).map(file =>
fileURLToPath(new URL(file, import.meta.url))
),
}),
FhcResolver(),
replace({
preventAssignment: true,
'process.env.NODE_ENV': JSON.stringify( 'production' ),
}),
commonjs(),
vue(),
json(),
babel({
babelHelpers: 'bundled',
plugins: ['transform-class-properties']
}),
postcss({
extract: false,
modules: true,
use: ['sass'],
}),
terser()
],
watch: {
buildDelay: 500
},
output: {
preserveModules: false,
sourcemap: true,
format: 'es',
dir: './',
//manualChunks: {}
chunkFileNames: 'public/dist/js/includes/[name]-[hash].js'
}
};
+106
View File
@@ -0,0 +1,106 @@
import babel from '@rollup/plugin-babel';
import nodeResolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import vue from "rollup-plugin-vue";
import { globSync } from 'glob';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import postcss from 'rollup-plugin-postcss';
import replace from '@rollup/plugin-replace';
import alias from '@rollup/plugin-alias';
import { existsSync } from 'node:fs';
import terser from '@rollup/plugin-terser';
import json from '@rollup/plugin-json';
function FhcResolver () {
return {
name: 'fhc-resolver', // this name will show up in logs and errors
resolveId ( source, importer, options ) {
if( source.includes('.php') ) {
return false;
}
//console.log('source: ' + source + ' options.isEntry: ' + options.isEntry + ' importer: ' + importer);
if(importer !== undefined && !options.isEntry && !path.isAbsolute(source)) {
let tmp = path.dirname(importer);
if( importer.includes('/application/') ) {
tmp = tmp.replace(/public\/js\//, 'js/').replace(/\/application\//, '/public/');
}
const resolved = path.resolve(tmp, source);
//console.log(resolved);
if( existsSync(resolved) ) {
return resolved
}
}
return null; // other ids should be handled as usually
}
};
}
const useplugins = [
alias({
entries: {
vue: 'vue/dist/vue.esm-bundler.js',
}
}),
commonjs(),
nodeResolve({
module: true,
jsnext: true,
preferBuiltins: true,
browser: true,
moduleDirectories: ['node_modules'],
modulePaths: globSync('application/extensions/*/node_modules', {follow: true, realpath: true}).map(file =>
fileURLToPath(new URL(file, import.meta.url))
),
}),
json({
compact: true
}),
FhcResolver(),
replace({
preventAssignment: true,
'process.env.NODE_ENV': JSON.stringify( 'production' ),
}),
vue(),
babel({
babelHelpers: 'bundled',
plugins: ['transform-class-properties'],
}),
/*
postcss({
extract: false,
modules: true,
use: ['sass'],
}),
*/
terser()
];
export default globSync('public/**/js/apps/**/*.js', {follow: true, realpath: true}).map(file => {
if( path.dirname(file).includes('/dist/') || path.dirname(file).includes('/apps/vbform') ) {
return null;
}
let tmp = fileURLToPath(new URL(file, import.meta.url));
let cssfile = path.basename(tmp.replace(/\.js/, '.css'));
console.log('cssfile: ' + cssfile);
let cssplugin = [
postcss({
extract: cssfile,
minimize: true,
sourceMap: true
})
];
return {
input: tmp,
plugins: [...useplugins, ...cssplugin],
watch: {
buildDelay: 500
},
output: {
preserveModules: false,
sourcemap: true,
format: 'es',
file: tmp.replace(/public\//, 'public/dist/'),
}
}
}).filter(Boolean);
+1 -1
View File
@@ -6826,7 +6826,7 @@ $tabellen=array(
"bis.tbl_bisstandort" => array("standort_code","bezeichnung","aktiv","insertamum","insertvon","updateamum","updatevon"),
"bis.tbl_bisverwendung" => array("bisverwendung_id","ba1code","ba2code","vertragsstunden","beschausmasscode","verwendung_code","mitarbeiter_uid","hauptberufcode","hauptberuflich","habilitation","beginn","ende","updateamum","updatevon","insertamum","insertvon","ext_id","dv_art","inkludierte_lehre","zeitaufzeichnungspflichtig","azgrelevant", "homeoffice"),
"bis.tbl_bundesland" => array("bundesland_code","kurzbz","bezeichnung"),
"bis.tbl_entwicklungsteam" => array("mitarbeiter_uid","studiengang_kz","besqualcode","beginn","ende","updateamum","updatevon","insertamum","insertvon","ext_id"),
"bis.tbl_entwicklungsteam" => array("entwicklungsteam_id","mitarbeiter_uid","studiengang_kz","besqualcode","beginn","ende","updateamum","updatevon","insertamum","insertvon","ext_id"),
"bis.tbl_gemeinde" => array("gemeinde_id","plz","name","ortschaftskennziffer","ortschaftsname","bulacode","bulabez","kennziffer"),
"bis.tbl_gsstudientyp" => array("gsstudientyp_kurzbz","bezeichnung","studientyp_code"),
"bis.tbl_gsprogrammtyp" => array("gsprogrammtyp_kurzbz","bezeichnung","programmtyp_code"),
+7 -6
View File
@@ -27,8 +27,7 @@ require_once('dbupdate_3.4/example.php');
require_once('dbupdate_3.4/example2.php');
...
*/
require_once('dbupdate_3.4/25003_notenimport_nachpruefung.php');
//require_once('dbupdate_3.4/25003_notenimport_nachpruefung.php');
require_once('dbupdate_3.4/26173_index_webservicelog.php');
require_once('dbupdate_3.4/24682_reihungstest_zugangscode_fuer_login.php');
require_once('dbupdate_3.4/17512_fehlercode_constraints.php');
@@ -49,8 +48,12 @@ require_once('dbupdate_3.4/30181_tabelle_anrechnung_neue_attribute_fuer_begruend
require_once('dbupdate_3.4/29529_infocenter_anpassungen.php');
require_once('dbupdate_3.4/29835_uhstat1_erfassung_der_uhstat1_daten_ueber_das_bewerbungstool.php');
require_once('dbupdate_3.4/33714_erhoehter_studienbeitrag_fuer_drittsaatenangehoerig.php');
require_once('dbupdate_3.4/33003_bis_meldung_personal.php');
require_once('dbupdate_3.4/36275_zeitaufzeichnung_karenz.php');
require_once('dbupdate_3.4/21620_neues_feld_zum_erfassen_des_ESI.php');
require_once('dbupdate_3.4/36530_bis_internationsalisierung_codextabelle_neuerungen.php');
require_once('dbupdate_3.4/34543_ux_template.php');
require_once('dbupdate_3.4/17513_Entwicklungsteam.php');
// *** Pruefung und hinzufuegen der neuen Attribute und Tabellen
echo '<H2>Pruefe Tabellen und Attribute!</H2>';
@@ -74,7 +77,7 @@ $tabellen=array(
"bis.tbl_bisstandort" => array("standort_code","bezeichnung","aktiv","insertamum","insertvon","updateamum","updatevon"),
"bis.tbl_bisverwendung" => array("bisverwendung_id","ba1code","ba2code","vertragsstunden","beschausmasscode","verwendung_code","mitarbeiter_uid","hauptberufcode","hauptberuflich","habilitation","beginn","ende","updateamum","updatevon","insertamum","insertvon","ext_id","dv_art","inkludierte_lehre","zeitaufzeichnungspflichtig","azgrelevant", "homeoffice"),
"bis.tbl_bundesland" => array("bundesland_code","kurzbz","bezeichnung"),
"bis.tbl_entwicklungsteam" => array("mitarbeiter_uid","studiengang_kz","besqualcode","beginn","ende","updateamum","updatevon","insertamum","insertvon","ext_id"),
"bis.tbl_entwicklungsteam" => array("mitarbeiter_uid","studiengang_kz","besqualcode","beginn","ende","updateamum","updatevon","insertamum","insertvon","ext_id","entwicklungsteam_id"),
"bis.tbl_gemeinde" => array("gemeinde_id","plz","name","ortschaftskennziffer","ortschaftsname","bulacode","bulabez","kennziffer"),
"bis.tbl_gsstudientyp" => array("gsstudientyp_kurzbz","bezeichnung","studientyp_code"),
"bis.tbl_gsprogrammtyp" => array("gsprogrammtyp_kurzbz","bezeichnung","programmtyp_code"),
@@ -164,12 +167,10 @@ $tabellen=array(
"fue.tbl_ressource" => array("ressource_id","student_uid","mitarbeiter_uid","betriebsmittel_id","firma_id","bezeichnung","beschreibung","insertamum","insertvon","updateamum","updatevon"),
"fue.tbl_scrumteam" => array("scrumteam_kurzbz","bezeichnung","punkteprosprint","tasksprosprint","gruppe_kurzbz"),
"fue.tbl_scrumsprint" => array("scrumsprint_id","scrumteam_kurzbz","sprint_kurzbz","sprintstart","sprintende","insertamum","insertvon","updateamum","updatevon"),
"hr.tbl_audit_log" => array("audit_log_id","mtime","action","username","table_name","diff_data","row_data"),
"hr.tbl_sachaufwand" => array("sachaufwand_id","mitarbeiter_uid","sachaufwandtyp_kurzbz","dienstverhaeltnis_id","beginn","ende","anmerkung","insertamum","insertvon","updateamum","updatevon"),
"hr.tbl_sachaufwandtyp" => array("sachaufwandtyp_kurzbz","bezeichnung","sort", "aktiv"),
"hr.tbl_stundensatz" => array("stundensatz_id","uid","stundensatztyp","stundensatz","oe_kurzbz","gueltig_von","gueltig_bis","insertamum","insertvon","updateamum","updatevon"),
"hr.tbl_stundensatztyp" => array("stundensatztyp","bezeichnung","aktiv","insertamum","insertvon","updateamum","updatevon"),
"hr.tbl_tmp_store" => array("tmp_store_id","typ","mitarbeiter_uid","formdata","insertvon","insertamum","updatevon","updateamum"),
"hr.tbl_dienstverhaeltnis" => array("dienstverhaeltnis_id","mitarbeiter_uid","vertragsart_kurzbz","oe_kurzbz","von","bis","insertamum","insertvon","updateamum","updatevon"),
"hr.tbl_vertragsart" => array("vertragsart_kurzbz","bezeichnung","anmerkung","dienstverhaeltnis","vertragsart_kurzbz_parent","aktiv","sort"),
"hr.tbl_vertragsbestandteil" => array("vertragsbestandteil_id","dienstverhaeltnis_id","vertragsbestandteiltyp_kurzbz","von", "bis","insertamum", "insertvon","updateamum","updatevon"),
@@ -280,7 +281,7 @@ $tabellen=array(
"public.tbl_konto" => array("buchungsnr","person_id","studiengang_kz","studiensemester_kurzbz","buchungstyp_kurzbz","buchungsnr_verweis","betrag","buchungsdatum","buchungstext","mahnspanne","updateamum","updatevon","insertamum","insertvon","ext_id","credit_points", "zahlungsreferenz", "anmerkung"),
"public.tbl_lehrverband" => array("studiengang_kz","semester","verband","gruppe","aktiv","bezeichnung","ext_id","orgform_kurzbz","gid"),
"public.tbl_log" => array("log_id","executetime","mitarbeiter_uid","beschreibung","sql","sqlundo"),
"public.tbl_mitarbeiter" => array("mitarbeiter_uid","personalnummer","telefonklappe","kurzbz","lektor","fixangestellt","bismelden","stundensatz","ausbildungcode","ort_kurzbz","standort_id","anmerkung","insertamum","insertvon","updateamum","updatevon","ext_id","kleriker"),
"public.tbl_mitarbeiter" => array("mitarbeiter_uid","personalnummer","telefonklappe","kurzbz","lektor","fixangestellt","bismelden","stundensatz","ausbildungcode","ort_kurzbz","standort_id","anmerkung","insertamum","insertvon","updateamum","updatevon","ext_id","kleriker","habilitation"),
"public.tbl_msg_attachment" => array("attachment_id","message_id","name","filename"),
"public.tbl_msg_message" => array("message_id","person_id","subject","body","priority","relationmessage_id","oe_kurzbz","insertamum","insertvon"),
"public.tbl_msg_recipient" => array("message_id","person_id","token","sent","sentinfo","insertamum","insertvon","oe_kurzbz"),
@@ -0,0 +1,121 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
//Add column entwicklungs_id to bis.tbl_entwicklungsteam
if(!@$db->db_query("SELECT entwicklungsteam_id FROM bis.tbl_entwicklungsteam LIMIT 1"))
{
$qry = 'ALTER TABLE bis.tbl_entwicklungsteam ADD COLUMN entwicklungsteam_id integer;';
if(!$db->db_query($qry))
echo '<strong> bis.tbl_entwicklungsteam '.$db->db_last_error().'</strong><br>';
else
echo '<br>bis.tbl_entwicklungsteam: Neue Spalte entwicklungsteam_id hinzugefügt';
}
//Column entwicklungsteam_id mit Werten befüllen
if($result = @$db->db_query("SELECT entwicklungsteam_id FROM bis.tbl_entwicklungsteam where entwicklungsteam_id is not null LIMIT 1"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = 'UPDATE bis.tbl_entwicklungsteam et SET entwicklungsteam_id =
(SELECT rownumber FROM (SELECT ROW_NUMBER() OVER (ORDER BY mitarbeiter_uid, studiengang_kz)
AS rownumber, t.* FROM bis.tbl_entwicklungsteam t ORDER BY mitarbeiter_uid, studiengang_kz) rn
WHERE rn.mitarbeiter_uid = et.mitarbeiter_uid
AND rn.studiengang_kz = et.studiengang_kz);
';
if(!$db->db_query($qry))
echo '<strong> bis.tbl_entwicklungsteam '.$db->db_last_error().'</strong><br>';
else
echo '<br>bis.tbl_entwicklungsteam: Spalte bis.tbl_entwicklungsteam_id mit Werten aufgefüllt';
}
}
//Create Sequence bis.tbl_entwicklungsteam and grant Rights
if ($result = @$db->db_query("SELECT * FROM pg_class WHERE relname = 'tbl_entwicklungsteam_entwicklungsteam_id_seq'"))
{
if ($db->db_num_rows($result) == 0)
{
if ($count = @$db->db_query("SELECT * FROM bis.tbl_entwicklungsteam"))
{
$count = $db->db_num_rows($count) + 1;
$qry = 'CREATE SEQUENCE bis.tbl_entwicklungsteam_entwicklungsteam_id_seq START ';
$qry .= $count;
if(!$db->db_query($qry))
{
echo '<strong> bis.tbl_entwicklungsteam '.$db->db_last_error().'</strong><br>';
}
else
{
echo '<br>bis.tbl_entwicklungsteam: Sequence bis.tbl_entwicklungsteam_entwicklungsteam_id_seq mit Startwert ' . $count . ' erstellt';
$qry2 = "GRANT SELECT, UPDATE ON bis.tbl_entwicklungsteam_entwicklungsteam_id_seq TO vilesci;
GRANT SELECT, UPDATE ON bis.tbl_entwicklungsteam_entwicklungsteam_id_seq TO web;";
if(!$db->db_query($qry2))
{
echo '<strong>bis.tbl_entwicklungsteam_entwicklungsteam_id_seqBerechtigungen: '.$db->db_last_error().'</strong><br>';
}
else
{
echo '<br>bis.tbl_entwicklungsteam: Rechte auf bis.tbl_entwicklungsteam_entwicklungsteam_id_seq fuer web user und vilesci gesetzt ';
}
}
}
}
}
//Bis.tbl_entwicklungsteam auf NOTNULL setzen
if ($result = @$db->db_query("SELECT is_nullable FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'tbl_entwicklungsteam' AND column_name = 'entwicklungsteam_id' and is_nullable = 'NO'"))
{
if($db->db_num_rows($result)==0)
{
$qry = 'ALTER TABLE bis.tbl_entwicklungsteam ALTER COLUMN entwicklungsteam_id SET NOT NULL';
if(!$db->db_query($qry))
echo '<strong> bis.tbl_entwicklungsteam '.$db->db_last_error().'</strong><br>';
else
echo '<br>bis.tbl_entwicklungsteam: Spalte bis.tbl_entwicklungsteam_id auf NOT NULL gesetzt';
}
}
//Bis.tbl_entwicklungsteam DEFAULT einstellen
if ($result = @$db->db_query("SELECT column_default FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = 'tbl_entwicklungsteam'AND column_name = 'entwicklungsteam_id' and column_default is null"))
{
if($db->db_num_rows($result)==1)
{
$qry = "ALTER TABLE bis.tbl_entwicklungsteam ALTER COLUMN entwicklungsteam_id SET DEFAULT nextval('bis.tbl_entwicklungsteam_entwicklungsteam_id_seq'::regclass);";
if(!$db->db_query($qry))
echo '<strong> bis.tbl_entwicklungsteam '.$db->db_last_error().'</strong><br>';
else
echo '<br> bis.tbl_entwicklungsteam: Defaultwert bei Spalte bis.tbl_entwicklungsteam_id gesetzt';
}
}
//DELETE Constraint PRIMARY KEY pk_tbl_entwicklungsteam (mitarbeiter_uid, studiengang_kz) entfernen
if ($result = @$db->db_query("SELECT conname FROM pg_constraint WHERE conname = 'pk_tbl_entwicklungsteam'"))
{
if($db->db_num_rows($result)==1)
{
$qry = "ALTER TABLE bis.tbl_entwicklungsteam DROP CONSTRAINT pk_tbl_entwicklungsteam;";
if (!$db->db_query($qry))
echo '<strong>bis.tbl_entwicklungsteam: '.$db->db_last_error().'</strong><br>';
else
echo '<br>bis.tbl_entwicklungsteam: Primary Key pk_tbl_entwicklungsteam (mitarbeiter_uid, studiengang_kz) entfernt ';
}
}
// ADD PRIMARY KEY tbl_entwicklungsteam_pk to bis.tbl_entwicklungsteam
if ($result = @$db->db_query("SELECT conname FROM pg_constraint WHERE conname = 'tbl_entwicklungsteam_pk'"))
{
if ($db->db_num_rows($result) == 0)
{
$qry = "ALTER TABLE bis.tbl_entwicklungsteam ADD CONSTRAINT tbl_entwicklungsteam_pk PRIMARY KEY(entwicklungsteam_id);";
if (!$db->db_query($qry))
echo '<strong>sbis.tbl_entwicklungsteam: '.$db->db_last_error().'</strong><br>';
else
echo '<br>bis.tbl_entwicklungsteam: Primary Key tbl_entwicklungsteam_pk (entwicklungsteam_id) hinzugefügt';
}
}
@@ -7,7 +7,8 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_status
$qry = "CREATE TABLE campus.tbl_studierendenantrag_statustyp (
studierendenantrag_statustyp_kurzbz VARCHAR(32) NOT NULL,
bezeichnung VARCHAR(128)[] NOT NULL,
CONSTRAINT tbl_studierendenantrag_statustyp_pk PRIMARY KEY(studierendenantrag_statustyp_kurzbz)
CONSTRAINT tbl_studierendenantrag_statustyp_pk
PRIMARY KEY(studierendenantrag_statustyp_kurzbz)
);
GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_statustyp TO vilesci;
@@ -62,6 +63,22 @@ if($result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statust
}
}
if($result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_statustyp WHERE studierendenantrag_statustyp_kurzbz = 'Pause' "))
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO campus.tbl_studierendenantrag_statustyp
(studierendenantrag_statustyp_kurzbz, bezeichnung)
VALUES
('Pause', '{\"Pausiert\",\"Paused\"}');
";
if (!$db->db_query($qry))
echo '<strong>campus.tbl_studierendenantrag_statustyp (insert): '.$db->db_last_error().'</strong><br>';
else
echo '<br>campus.tbl_studierendenantrag_statustyp: "Pause" added';
}
}
if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag LIMIT 1"))
{
$qry = "CREATE TABLE campus.tbl_studierendenantrag (
@@ -82,7 +99,9 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag LIMIT
NO MAXVALUE
NO MINVALUE
CACHE 1;
ALTER TABLE campus.tbl_studierendenantrag ALTER COLUMN studierendenantrag_id SET DEFAULT nextval('campus.tbl_studierendenantrag_studierendenantrag_id_seq');
ALTER TABLE campus.tbl_studierendenantrag
ALTER COLUMN studierendenantrag_id
SET DEFAULT nextval('campus.tbl_studierendenantrag_studierendenantrag_id_seq');
GRANT SELECT, INSERT ON campus.tbl_studierendenantrag TO vilesci;
GRANT SELECT, INSERT ON campus.tbl_studierendenantrag TO web;
@@ -104,16 +123,27 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_status
insertamum TIMESTAMP DEFAULT NOW(),
insertvon VARCHAR(32) NOT NULL,
grund TEXT NULL,
CONSTRAINT tbl_studierendenantrag_status_pk PRIMARY KEY(studierendenantrag_status_id),
CONSTRAINT tbl_studierendenantrag_fk FOREIGN KEY (studierendenantrag_id) REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id) ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT tbl_studierendenantrag_statustyp_fk FOREIGN KEY (studierendenantrag_statustyp_kurzbz) REFERENCES campus.tbl_studierendenantrag_statustyp(studierendenantrag_statustyp_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT
CONSTRAINT tbl_studierendenantrag_status_pk
PRIMARY KEY(studierendenantrag_status_id),
CONSTRAINT tbl_studierendenantrag_fk
FOREIGN KEY (studierendenantrag_id)
REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT tbl_studierendenantrag_statustyp_fk
FOREIGN KEY (studierendenantrag_statustyp_kurzbz)
REFERENCES campus.tbl_studierendenantrag_statustyp(studierendenantrag_statustyp_kurzbz)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE SEQUENCE campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
ALTER TABLE campus.tbl_studierendenantrag_status ALTER COLUMN studierendenantrag_status_id SET DEFAULT nextval('campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq');
ALTER TABLE campus.tbl_studierendenantrag_status
ALTER COLUMN studierendenantrag_status_id
SET DEFAULT nextval('campus.tbl_studierendenantrag_status_studierendenantrag_status_id_seq');
GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_status TO vilesci;
GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_status TO web;
@@ -137,17 +167,32 @@ if(!$result = @$db->db_query("SELECT 1 FROM campus.tbl_studierendenantrag_lehrve
anmerkung TEXT NULL,
insertamum TIMESTAMP DEFAULT NOW(),
insertvon VARCHAR(32) NOT NULL,
CONSTRAINT tbl_studierendenantrag_lehrveranstaltung_pk PRIMARY KEY(studierendenantrag_lehrveranstaltung_id),
CONSTRAINT tbl_studiensemester_fk FOREIGN KEY (studiensemester_kurzbz) REFERENCES public.tbl_studiensemester(studiensemester_kurzbz) ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT tbl_note_fk FOREIGN KEY (note) REFERENCES lehre.tbl_note(note) ON UPDATE CASCADE ON DELETE RESTRICT,
CONSTRAINT tbl_studierendenantrag_fk FOREIGN KEY (studierendenantrag_id) REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id) ON UPDATE CASCADE ON DELETE RESTRICT
CONSTRAINT tbl_studierendenantrag_lehrveranstaltung_pk
PRIMARY KEY(studierendenantrag_lehrveranstaltung_id),
CONSTRAINT tbl_studiensemester_fk
FOREIGN KEY (studiensemester_kurzbz)
REFERENCES public.tbl_studiensemester(studiensemester_kurzbz)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT tbl_note_fk
FOREIGN KEY (note)
REFERENCES lehre.tbl_note(note)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT tbl_studierendenantrag_fk
FOREIGN KEY (studierendenantrag_id)
REFERENCES campus.tbl_studierendenantrag(studierendenantrag_id)
ON UPDATE CASCADE
ON DELETE RESTRICT
);
CREATE SEQUENCE campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq
INCREMENT BY 1
NO MAXVALUE
NO MINVALUE
CACHE 1;
ALTER TABLE campus.tbl_studierendenantrag_lehrveranstaltung ALTER COLUMN studierendenantrag_lehrveranstaltung_id SET DEFAULT nextval('campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq');
ALTER TABLE campus.tbl_studierendenantrag_lehrveranstaltung
ALTER COLUMN studierendenantrag_lehrveranstaltung_id
SET DEFAULT nextval('campus.tbl_studierendenantrag_lehrveranstaltung_studierendenantrag_lehrveranstaltung_id_seq');
GRANT SELECT, INSERT, DELETE ON campus.tbl_studierendenantrag_lehrveranstaltung TO vilesci;
GRANT SELECT, INSERT ON campus.tbl_studierendenantrag_lehrveranstaltung TO web;
@@ -164,7 +209,8 @@ if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berecht
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('student/studierendenantrag', 'Berechtigung für Bearbeiten Studierendenanträge');";
$qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung)
VALUES ('student/studierendenantrag', 'Berechtigung für Bearbeiten Studierendenanträge');";
if(!$db->db_query($qry))
echo '<strong>system.tbl_berechtigung '.$db->db_last_error().'</strong><br>';
@@ -177,7 +223,8 @@ if($result = @$db->db_query("SELECT 1 FROM system.tbl_berechtigung WHERE berecht
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung) VALUES('student/antragfreigabe', 'Berechtigung für Freigabe der Studierendenanträge');";
$qry = "INSERT INTO system.tbl_berechtigung(berechtigung_kurzbz, beschreibung)
VALUES ('student/antragfreigabe', 'Berechtigung für Freigabe der Studierendenanträge');";
if(!$db->db_query($qry))
echo '<strong>system.tbl_berechtigung '.$db->db_last_error().'</strong><br>';
@@ -375,7 +422,8 @@ if($result = @$db->db_query("SELECT 1 FROM public.tbl_status_grund WHERE statusg
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig) VALUES('abbrecherStgl', 'Abbrecher', TRUE, '{\"durch Stgl\", \"by Course Director\"}', '{\"durch Stgl\", \"by Course Director\"}');";
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig)
VALUES ('abbrecherStgl', 'Abbrecher', TRUE, '{\"durch Stgl\", \"by Course Director\"}', '{\"durch Stgl\", \"by Course Director\"}');";
if(!$db->db_query($qry))
echo '<strong>public.tbl_status_grund '.$db->db_last_error().'</strong><br>';
@@ -388,7 +436,8 @@ if($result = @$db->db_query("SELECT 1 FROM public.tbl_status_grund WHERE statusg
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig) VALUES('abbrecherStud', 'Abbrecher', TRUE, '{\"durch Stud\", \"by Student\"}', '{\"durch Stud\", \"by Student\"}');";
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig)
VALUES ('abbrecherStud', 'Abbrecher', TRUE, '{\"durch Stud\", \"by Student\"}', '{\"durch Stud\", \"by Student\"}');";
if(!$db->db_query($qry))
echo '<strong>public.tbl_status_grund '.$db->db_last_error().'</strong><br>';
@@ -401,7 +450,8 @@ if($result = @$db->db_query("SELECT 1 FROM public.tbl_status_grund WHERE statusg
{
if($db->db_num_rows($result) == 0)
{
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig) VALUES('preabbrecher', 'Student', TRUE, '{\"Pre-Abbrecher\", \"Pre-Aborted\"}', '{\"Pre-Abbrecher\", \"Pre-Aborted\"}');";
$qry = "INSERT INTO public.tbl_status_grund(statusgrund_kurzbz, status_kurzbz, aktiv, beschreibung, bezeichnung_mehrsprachig)
VALUES ('preabbrecher', 'Student', TRUE, '{\"Pre-Abbrecher\", \"Pre-Aborted\"}', '{\"Pre-Abbrecher\", \"Pre-Aborted\"}');";
if(!$db->db_query($qry))
echo '<strong>public.tbl_status_grund '.$db->db_last_error().'</strong><br>';
@@ -0,0 +1,14 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
//Add column habilitation to public.tbl_mitarbeiter
if(!@$db->db_query("SELECT habilitation FROM public.tbl_mitarbeiter LIMIT 1"))
{
$qry = "ALTER TABLE public.tbl_mitarbeiter ADD COLUMN habilitation boolean NOT NULL DEFAULT false;
COMMENT ON COLUMN public.tbl_mitarbeiter.habilitation IS 'Zeigt an, ob Mitarbeiter habilitiert ist (BIS relevant).';";
if(!$db->db_query($qry))
echo '<strong>public.tbl_mitarbeiter '.$db->db_last_error().'</strong><br>';
else
echo '<br>Spalte habilitation zu Tabelle public.tbl_mitarbeiter hinzugefügt';
}
+16
View File
@@ -0,0 +1,16 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
// add app fhctemplate
if($result = $db->db_query("SELECT 1 FROM system.tbl_app WHERE app='fhctemplate'"))
{
if($db->db_num_rows($result) === 0)
{
$qry = "INSERT INTO system.tbl_app (app) VALUES('fhctemplate');";
if(!$db->db_query($qry))
echo '<strong>System Tabelle app: '.$db->db_last_error().'</strong><br>';
else
echo '<br>app fhctemplate hinzugefuegt';
}
}
@@ -0,0 +1,30 @@
<?php
if (! defined('DB_NAME')) exit('No direct script access allowed');
if($result = @$db->db_query("SELECT 1 FROM bis.tbl_mobilitaetsprogramm WHERE mobilitaetsprogramm_code IN (43, 44, 45, 46, 47, 48, 49, 50, 51, 52)"))
{
if($db->db_num_rows($result) < 10)
{
$qry = "
INSERT INTO bis.tbl_mobilitaetsprogramm(mobilitaetsprogramm_code, kurzbz, beschreibung, sichtbar, sichtbar_outgoing) VALUES
(43, 'AMinKunst', 'Auslandsstipendium des Bundesministeriums für Kunst', TRUE, TRUE),
(44, 'BundeslandProg', 'Bundesland-Programm', TRUE, TRUE),
(45, 'ERASMUSSMS', 'ERASMUS+ (SMS) - Studienaufenthalte', TRUE, TRUE),
(46, 'ERASMUSSMT', 'ERASMUS+ (SMT) - Studierendenpraktika', TRUE, TRUE),
(47, 'ERASMUSMundus', 'Erasmus Mundus Joint Master Degrees / Erasmus Mundus Joint Master', FALSE, FALSE),
(48, 'EUGrad', 'Mobilitätsprogramm für Graduierte im EU-Bereich', TRUE, TRUE),
(49, 'ÖStiftung', 'Stipendienstiftung der Republik Österreich', TRUE, FALSE),
(50, 'ÖAkadWiss', 'Stipendienabkommen der Österreichischen Akademie der Wissenschaften', TRUE, TRUE),
(51, 'FondWissForsch', 'Stipendium des Fonds zur Förderung der wissenschaftlichen Forschung', TRUE, TRUE),
(52, 'SEMP', 'Swiss-European Mobility Programme (SEMP)', TRUE, TRUE)
ON CONFLICT (mobilitaetsprogramm_code) DO NOTHING;
";
if(!$db->db_query($qry))
echo '<strong>bis.tbl_mobilitaetsprogramm: '.$db->db_last_error().'</strong><br>';
else
echo ' bis.tbl_mobilitaetsprogramm: Mobilitätsprogramme hinzugefuegt<br>';
}
}
+26
View File
@@ -1279,6 +1279,32 @@ $filters = array(
}
',
'oe_kurzbz' => null,
),
array(
'app' => 'fhctemplate',
'dataset_name' => 'exampledata',
'filter_kurzbz' => 'exampledata',
'description' => '{Beispieldaten Filter}',
'sort' => 1,
'default_filter' => true,
'filter' => '
{
"name": "Alle Beispieldaten",
"columns": [
{"name": "uid"},
{"name": "stringval"},
{"name": "integerval"},
{"name": "dateval"},
{"name": "booleanval"},
{"name": "moneyval"},
{"name": "dokument_bezeichnung"},
{"name": "textval"},
{"name": "examplestatus_kurzbz"}
],
"filters": []
}
',
'oe_kurzbz' => null
)
);
+442
View File
@@ -10862,6 +10862,7 @@ Any unusual occurrences
'app' => 'projektarbeitsbeurteilung',
'category' => 'projektarbeitsbeurteilung',
'phrase' => 'kommissionellePruefungHinweis',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
@@ -11395,6 +11396,26 @@ Any unusual occurrences
)
)
),
array(
'app' => 'core',
'category' => 'anrechnung',
'phrase' => 'anrechnung',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Anrechnung',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Exemption',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'anrechnung',
@@ -20508,6 +20529,46 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'btn_pause',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Pausieren',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Pause',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'btn_unpause',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Fortsetzen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Resume',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
@@ -21309,6 +21370,46 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'status_unpaused',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Fortgesetzt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Resumed',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'status_stop',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Gestoppt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Stopped',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
@@ -21509,6 +21610,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'error_no_antragstatus',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Kein Status für Bekanntgabe #{id} gefunden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'No status found announcement #{id}',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
@@ -21729,6 +21850,46 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'error_not_pausable',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bekanntgabe mit Id {id} kann nicht pausiert werden',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Announcement with Id {id} cannot be not paused',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'error_not_paused',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Bekanntgabe mit Id {id} ist nicht pausiert',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Announcement with Id {id} is not paused',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
@@ -22673,6 +22834,7 @@ array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'dropdown_bitteWaehlen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
@@ -22688,6 +22850,26 @@ array(
)
)
),
array(
'app' => 'core',
'category' => 'studierendenantrag',
'phrase' => 'grund_Wiederholung_deadline',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'negative kommissionelle Beurteilung und keine fristgerechte Bekanntgabe der Wiederholung des Studienjahres',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'negative assessment by the committee and no timely announcement of the repetition of the academic year',
'description' => '',
'insertvon' => 'system'
)
)
),
// Personalverwaltung begin
array(
'app' => 'core',
@@ -23796,6 +23978,26 @@ array(
)
)
),
array(
'app' => 'personalverwaltung',
'category' => 'person',
'phrase' => 'habilitation',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Habilitation',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Habilitation',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'personalverwaltung',
'category' => 'person',
@@ -24116,6 +24318,26 @@ array(
)
)
),
array(
'app' => 'personalverwaltung',
'category' => 'zeitaufzeichnung',
'phrase' => 'id',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'ID',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'ID',
'description' => '',
'insertvon' => 'system'
)
)
),
// Personalverwaltung end
array(
'app' => 'core',
@@ -24196,7 +24418,227 @@ array(
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'geloescht',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Gelöscht',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Deleted',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'aenderungGespeichert',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Änderung gespeichert',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Saved changes',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatz',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatzGenehmigen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz genehmigen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Approve dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatzAblehnen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz ablehnen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Reject dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatzAnlegen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz anlegen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Add dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'fhctemplate',
'category' => 'global',
'phrase' => 'datensatzBearbeiten',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Datensatz bearbeiten',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Edit dataset',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'alleGenehmigt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Alle genehmigt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'All accepted',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'alleAbgelehnt',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Alle abgelehnt',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'All rejected',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'dokument',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Dokument',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Document',
'description' => '',
'insertvon' => 'system'
)
)
),
array(
'app' => 'core',
'category' => 'global',
'phrase' => 'aktionen',
'insertvon' => 'system',
'phrases' => array(
array(
'sprache' => 'German',
'text' => 'Aktionen',
'description' => '',
'insertvon' => 'system'
),
array(
'sprache' => 'English',
'text' => 'Actions',
'description' => '',
'insertvon' => 'system'
)
)
)
);
Binary file not shown.
+378
View File
@@ -0,0 +1,378 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="antraege">
<office:document-content
xmlns:officeooo="http://openoffice.org/2009/office"
xmlns:css3t="http://www.w3.org/TR/css3-text/"
xmlns:grddl="http://www.w3.org/2003/g/data-view#"
xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rpt="http://openoffice.org/2005/report"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0"
xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0"
xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0"
xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0"
xmlns:oooc="http://openoffice.org/2004/calc"
xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0"
xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0"
xmlns:ooo="http://openoffice.org/2004/office"
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0"
xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0"
xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0"
xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0"
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2"
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
xmlns:tableooo="http://openoffice.org/2009/table"
xmlns:drawooo="http://openoffice.org/2010/draw"
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0"
xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0"
xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:xforms="http://www.w3.org/2002/xforms" office:version="1.3">
<office:scripts/>
<office:font-face-decls>
<style:font-face style:name="Arial" svg:font-family="Arial" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Sans" svg:font-family="&apos;Liberation Sans&apos;" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="Liberation Serif" svg:font-family="&apos;Liberation Serif&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
<style:font-face style:name="Lohit Devanagari" svg:font-family="&apos;Lohit Devanagari&apos;"/>
<style:font-face style:name="Lohit Devanagari1" svg:font-family="&apos;Lohit Devanagari&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="Noto Sans CJK SC" svg:font-family="&apos;Noto Sans CJK SC&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="Noto Serif CJK SC" svg:font-family="&apos;Noto Serif CJK SC&apos;" style:font-family-generic="system" style:font-pitch="variable"/>
<style:font-face style:name="Tahoma" svg:font-family="Tahoma" style:font-family-generic="swiss" style:font-pitch="variable"/>
<style:font-face style:name="Times New Roman" svg:font-family="&apos;Times New Roman&apos;" style:font-family-generic="roman" style:font-pitch="variable"/>
</office:font-face-decls>
<office:automatic-styles>
<style:style style:name="Tabelle1" style:family="table">
<style:table-properties style:width="16.245cm" fo:margin-left="-0.191cm" table:align="left" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle1.A" style:family="table-column">
<style:table-column-properties style:column-width="16.245cm"/>
</style:style>
<style:style style:name="Tabelle1.1" style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:style>
<style:style style:name="Tabelle1.A1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border="none" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle2" style:family="table">
<style:table-properties style:width="16.245cm" fo:margin-left="-0.191cm" table:align="left" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle2.A" style:family="table-column">
<style:table-column-properties style:column-width="4.41cm"/>
</style:style>
<style:style style:name="Tabelle2.B" style:family="table-column">
<style:table-column-properties style:column-width="11.836cm"/>
</style:style>
<style:style style:name="Tabelle2.1" style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:style>
<style:style style:name="Tabelle2.A1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border="0.5pt solid #000000" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle2.5" style:family="table-row">
<style:table-row-properties style:min-row-height="8.301cm" fo:keep-together="auto"/>
</style:style>
<style:style style:name="Tabelle3" style:family="table">
<style:table-properties style:width="16.245cm" fo:margin-left="-0.191cm" table:align="left" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle3.A" style:family="table-column">
<style:table-column-properties style:column-width="7.528cm"/>
</style:style>
<style:style style:name="Tabelle3.B" style:family="table-column">
<style:table-column-properties style:column-width="0.416cm"/>
</style:style>
<style:style style:name="Tabelle3.C" style:family="table-column">
<style:table-column-properties style:column-width="8.301cm"/>
</style:style>
<style:style style:name="Tabelle3.1" style:family="table-row">
<style:table-row-properties fo:keep-together="auto"/>
</style:style>
<style:style style:name="Tabelle3.A1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border-left="none" fo:border-right="none" fo:border-top="none" fo:border-bottom="0.5pt solid #000000" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle3.B1" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border="none" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="Tabelle3.A2" style:family="table-cell">
<style:table-cell-properties style:vertical-align="top" fo:padding-left="0.191cm" fo:padding-right="0.191cm" fo:padding-top="0cm" fo:padding-bottom="0cm" fo:border-left="none" fo:border-right="none" fo:border-top="0.5pt solid #000000" fo:border-bottom="none" style:writing-mode="lr-tb"/>
</style:style>
<style:style style:name="P1" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:line-height="150%">
<style:tab-stops>
<style:tab-stop style:position="3.501cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="P2" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:line-height="150%">
<style:tab-stops>
<style:tab-stop style:position="3.501cm"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="P3" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false">
<style:tab-stops>
<style:tab-stop style:position="7.502cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
</style:style>
<style:style style:name="P4" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:margin-top="0.494cm" fo:margin-bottom="0.882cm" style:contextual-spacing="false" fo:line-height="0.776cm">
<style:tab-stops>
<style:tab-stop style:position="7.502cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="14pt" style:font-size-asian="14pt" style:font-size-complex="14pt"/>
</style:style>
<style:style style:name="P5" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false">
<style:tab-stops>
<style:tab-stop style:position="7.502cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="9pt" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P6" style:family="paragraph" style:parent-style-name="Header">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false">
<style:tab-stops>
<style:tab-stop style:position="7.502cm"/>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="14.753cm"/>
<style:tab-stop style:position="15.503cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" fo:language="none" fo:country="none" style:font-size-asian="9pt" style:language-asian="none" style:country-asian="none" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P7" style:family="paragraph" style:parent-style-name="Header">
<style:text-properties fo:language="none" fo:country="none" style:language-asian="none" style:country-asian="none"/>
</style:style>
<style:style style:name="P8" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false" fo:line-height="0.776cm">
<style:tab-stops>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" style:font-size-asian="9pt" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P9" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false"/>
<style:text-properties fo:font-size="9pt" style:font-size-asian="9pt" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P10" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false">
<style:tab-stops>
<style:tab-stop style:position="9.502cm"/>
<style:tab-stop style:position="16.002cm" style:type="right"/>
</style:tab-stops>
</style:paragraph-properties>
<style:text-properties fo:font-size="9pt" fo:language="none" fo:country="none" style:font-size-asian="9pt" style:language-asian="none" style:country-asian="none" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="P11" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false"/>
</style:style>
<style:style style:name="P12" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:margin-top="0.141cm" fo:margin-bottom="0.141cm" style:contextual-spacing="false" style:snap-to-layout-grid="false"/>
</style:style>
<style:style style:name="P13" style:family="paragraph" style:parent-style-name="Standard">
<style:text-properties fo:font-size="10pt" style:font-size-asian="10pt" style:font-size-complex="10pt"/>
</style:style>
<style:style style:name="P14" style:family="paragraph" style:parent-style-name="Standard">
<style:paragraph-properties fo:break-after="page"/>
<style:text-properties fo:font-size="10pt" style:font-size-asian="10pt" style:font-size-complex="10pt"/>
</style:style>
<style:style style:name="T1" style:family="text">
<style:text-properties fo:font-size="10pt" style:font-size-asian="10pt"/>
</style:style>
<style:style style:name="T2" style:family="text">
<style:text-properties fo:font-size="10pt" style:font-size-asian="10pt" style:font-size-complex="10pt"/>
</style:style>
<style:style style:name="T3" style:family="text">
<style:text-properties fo:font-size="9pt" style:font-size-asian="9pt" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="T4" style:family="text">
<style:text-properties fo:font-size="9pt" fo:language="none" fo:country="none" style:font-size-asian="9pt" style:language-asian="none" style:country-asian="none" style:font-size-complex="9pt"/>
</style:style>
<style:style style:name="T5" style:family="text">
<style:text-properties fo:font-size="8pt" style:font-size-asian="8pt" style:font-size-complex="8pt"/>
</style:style>
<style:style style:name="fr1" style:family="graphic" style:parent-style-name="Graphics">
<style:graphic-properties fo:margin-left="0.319cm" fo:margin-right="0.319cm" fo:margin-top="0cm" fo:margin-bottom="0cm" style:run-through="background" style:wrap="parallel" style:number-wrapped-paragraphs="no-limit" style:wrap-contour="true" style:wrap-contour-mode="outside" style:vertical-pos="from-top" style:vertical-rel="paragraph" style:horizontal-pos="from-left" style:horizontal-rel="paragraph" fo:background-color="transparent" draw:fill="none" draw:fill-color="#ffffff" fo:padding="0.002cm" fo:border="none" style:mirror="none" fo:clip="rect(0cm, 0cm, 0cm, 0cm)" draw:luminance="0%" draw:contrast="0%" draw:red="0%" draw:green="0%" draw:blue="0%" draw:gamma="100%" draw:color-inversion="false" draw:image-opacity="100%" draw:color-mode="standard"/>
</style:style>
<style:style style:name="Sect1" style:family="section">
<style:section-properties text:dont-balance-text-columns="true" style:writing-mode="lr-tb" style:editable="false">
<style:columns fo:column-count="1" fo:column-gap="0cm"/>
</style:section-properties>
</style:style>
</office:automatic-styles>
<office:body>
<xsl:apply-templates match="antrag"/>
</office:body>
</office:document-content>
</xsl:template>
<xsl:template match="antrag">
<office:text>
<office:forms form:automatic-focus="false" form:apply-design-mode="false"/>
<text:tracked-changes text:track-changes="true"/>
<text:sequence-decls>
<text:sequence-decl text:display-outline-level="0" text:name="Illustration"/>
<text:sequence-decl text:display-outline-level="0" text:name="Table"/>
<text:sequence-decl text:display-outline-level="0" text:name="Text"/>
<text:sequence-decl text:display-outline-level="0" text:name="Drawing"/>
<text:sequence-decl text:display-outline-level="0" text:name="Figure"/>
</text:sequence-decls>
<text:section text:style-name="Sect1" text:name="Bereich1" text:protected="true">
<table:table table:name="Tabelle1" table:style-name="Tabelle1">
<table:table-column table:style-name="Tabelle1.A"/>
<table:table-row table:style-name="Tabelle1.1">
<table:table-cell table:style-name="Tabelle1.A1" office:value-type="string">
<text:p text:style-name="P1">
<text:span text:style-name="T2">Studiengang:
<text:s text:c="13"/>
</text:span>
<text:span text:style-name="T4"><xsl:value-of select="studiengang"/></text:span>
</text:p>
<text:p text:style-name="P2">
<text:span text:style-name="T2">Organisationsform:
<text:tab/>
</text:span>
<text:span text:style-name="T4"><xsl:value-of select="organisationsform"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
</table:table>
<text:p text:style-name="P4">Abmeldung vom Studium durch Studiengang</text:p>
<table:table table:name="Tabelle2" table:style-name="Tabelle2">
<table:table-column table:style-name="Tabelle2.A"/>
<table:table-column table:style-name="Tabelle2.B"/>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P3">
<text:span text:style-name="T3">Name der*des Studierenden</text:span>
</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P6">
<text:span text:style-name="T4"><xsl:value-of select="name"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">Personenkennzeichen</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">
<text:span text:style-name="T4"><xsl:value-of select="personenkz"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">Studienjahr</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">
<text:span text:style-name="T4"><xsl:value-of select="studienjahr"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">Studiensemester</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">
<text:span text:style-name="T4"><xsl:value-of select="studiensemester"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.1">
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">Semester</text:p>
</table:table-cell>
<table:table-cell table:style-name="Tabelle2.A1" office:value-type="string">
<text:p text:style-name="P5">
<text:span text:style-name="T4"><xsl:value-of select="semester"/></text:span>
</text:p>
</table:table-cell>
</table:table-row>
<table:table-row table:style-name="Tabelle2.5">
<table:table-cell table:style-name="Tabelle2.A1" table:number-columns-spanned="2" office:value-type="string">
<text:p text:style-name="P8">Grund der Abmeldung:</text:p>
<text:p text:style-name="P10">
<text:span text:style-name="T4"><xsl:value-of select="grund"/></text:span>
</text:p>
</table:table-cell>
<table:covered-table-cell/>
</table:table-row>
</table:table>
<text:p text:style-name="Standard"/>
<text:p text:style-name="Standard"/>
<text:p text:style-name="Standard"/>
<text:p text:style-name="Standard"/>
<text:p text:style-name="P13"/>
<text:p text:style-name="Standard">
<text:span text:style-name="T2">Wir weisen Sie darauf hin, dass Ihr FHTW Account noch 21 Tage aktiv ist. Wir bitten Sie, alle benötigte Dateien (Zeugnisse, Studienerfolgsbestätigungen, Studienbestätigungen, etc.) innerhalb dieses Zeitraums herunterzuladen. Für die Ausstellung von Duplikaten fallen nach Inaktivsetzung des CIS-Accounts Kosten an.
<text:line-break/>
</text:span>
<text:span text:style-name="T1">Sie sind gem. Ausbildungsvertrag verpflichtet, unverzüglich alle zur Verfügung gestellten Gerätschaften, Bücher, Schlüssel und sonstige Materialien zurückzugeben.</text:span>
<text:span text:style-name="T2">
<text:line-break/>Bei Abmeldung vor dem 01.09. bzw. 15.02. und bereits eingezahltem Studienbeitrag für das kommende Semester: Wir informieren Sie darüber, dass der Studienbeitrag für das kommende Semester von Ihnen zurückgefordert werden kann. Bitte geben Sie uns dafür innerhalb von 14 Tagen Ihre Bankdaten an folgende E-Mail-Adresse bekannt: billing@technikum-wien.at.
</text:span>
</text:p>
<text:p text:style-name="P14"/>
</text:section>
</office:text>
</xsl:template>
</xsl:stylesheet>
+64 -47
View File
@@ -36,7 +36,7 @@ $uid = get_uid();
$rechte = new benutzerberechtigung();
$rechte->getBerechtigungen($uid);
if(!$rechte->isBerechtigt('mitarbeiter/stammdaten',null,'suid'))
if(!$rechte->isBerechtigt('mitarbeiter/stammdaten', null, 'suid'))
die('Sie haben keine Berechtigung für diese Seite');
if (!$db = new basis_db())
@@ -141,11 +141,11 @@ $studiensemester = new studiensemester();
$stsem = (isset($_GET['stsem'])) ? $_GET['stsem'] : $studiensemester->getaktorNext(); // aktuelles Studiensemester
$datum_obj = new datum();
if(mb_strstr($stsem,'SS'))
if(mb_strstr($stsem, 'SS'))
{
$studiensemester->load($stsem);
$jahr = $datum_obj->formatDatum($studiensemester->start, 'Y');
$stichtag = date("Y-m-d", mktime(0, 0, 0, 12, 31, $jahr - 1)); // 31.12. des vorangehenden Kalenderjahres zur BIS Meldung TODO: oder Abfragetag mitgeben?
$stichtag = date("Y-m-d", mktime(0, 0, 0, 12, 31, $jahr - 1)); // 31.12. des vorangehenden Kalenderjahres zur BIS Meldung TODO: oder Abfragetag mitgeben?
}
else
{
@@ -219,7 +219,7 @@ foreach ($mitarbeiter_arr as $mitarbeiter)
* - nebenberuflich Lehrender: Hauptberufscode der letzten BIS-Verwendung
*/
$person_obj->hauptberufcode = ($is_hauptberuflich == true)
? NULL
? null
: $bisverwendung_arr[count($bisverwendung_arr) - 1]->hauptberufcode;
@@ -258,7 +258,6 @@ foreach ($mitarbeiter_arr as $mitarbeiter)
// Loop innerhalb Verwendungen mit selben Beschaeftigungsverhaeltnissen und Verwendung_codes
foreach ($verwendung_tmp_arr as $verwendung_tmp)
{
// Jahresvollzeitaequivalenz JVZAE ermitteln
// -----------------------------------------------------------------------------------------------------
/**
@@ -299,7 +298,7 @@ foreach ($mitarbeiter_arr as $mitarbeiter)
}
// Neue Verwendung im finalen Verwendungcontainer speichern
$verwendung_arr [] = $verwendung_obj;
$verwendung_arr[] = $verwendung_obj;
}
}
@@ -316,7 +315,8 @@ foreach ($mitarbeiter_arr as $mitarbeiter)
// Alle Benutzerfunktionen im BIS Meldungsjahr holen
$benutzerfunktion = new Benutzerfunktion();
$benutzerfunktion->getBenutzerFunktionByUid(
$person_obj->uid, null,
$person_obj->uid,
null,
$beginn_imJahr->format('Y-m-d'),
$ende_imJahr->format('Y-m-d')
);
@@ -334,7 +334,7 @@ foreach ($mitarbeiter_arr as $mitarbeiter)
* Exkludiert Funktionen, die einem Lehrgang bzw. STG, die nicht BIS-gemeldet werden, zugeordnet sind.
*/
// -------------------------------------------------------------------------------------------------------------
$funktion_arr = _addFunktionscontainer_Funktionscode7($person_obj->uid, $funktion_arr);
$funktion_arr = _addFunktionscontainer_Funktionscode7($person_obj->uid, $funktion_arr, $stichtag);
// Container Funktion dem Container Person anhaengen
// -----------------------------------------------------------------------------------------------------------------
@@ -368,7 +368,7 @@ foreach ($mitarbeiter_arr as $mitarbeiter)
// Container Person dem Gesamt-Container anhaengen
// -----------------------------------------------------------------------------------------------------------------
$person_arr []= $person_obj;
$person_arr[]= $person_obj;
}
// *********************************************************************************************************************
@@ -380,7 +380,7 @@ _outputHTML($person_arr);
$xml = _generateXML($person_arr);
$xml_datei = 'bisdaten/bismeldung_mitarbeiter.xml';
$dateiausgabe = fopen($xml_datei,'w');
$dateiausgabe = fopen($xml_datei, 'w');
fwrite($dateiausgabe, $xml);
fclose($dateiausgabe);
@@ -449,7 +449,7 @@ function _add_relativesBA_und_anteiligeJVZAE($uid, $bisverwendung_arr)
// Echter Dienstvertrag - d.h. Vertragsstunden sind vorhanden
// Bsp. angestellte Lektoren, angestellte MA in Verwaltung/Management/Wartung
// -------------------------------------------------------------------------------------------------------------
else if ($has_vertragsstunden)
elseif ($has_vertragsstunden)
{
// Vertragsstunden koennen max. VZ Aequivalenz-Basiswert haben
if ($bisverwendung->vertragsstunden > BIS_VOLLZEIT_ARBEITSSTUNDEN)
@@ -523,7 +523,7 @@ function _add_relativesBA_und_anteiligeJVZAE($uid, $bisverwendung_arr)
* (durch Abzug der eben erstellten anteiligen JVZAE fuer Lehrtaetigkeiten)
*/
$bisverwendung->jvzae_anteilig -= $verwendung_lehre_obj->jvzae_anteilig;
$bisverwendung_arr [] = $verwendung_lehre_obj;
$bisverwendung_arr[] = $verwendung_lehre_obj;
}
}
}
@@ -532,7 +532,7 @@ function _add_relativesBA_und_anteiligeJVZAE($uid, $bisverwendung_arr)
// Sonstige Beschaeftigungsverhaeltnisse ohne Vertragsstunden
// Freie Dienstvertraege auf Stundenbasis
// -------------------------------------------------------------------------------------------------------------
else if (!$has_vertragsstunden && $has_lehrtaetigkeit)
elseif (!$has_vertragsstunden && $has_lehrtaetigkeit)
{
/**
* Verwendungen ergänzen, wenn die BIS-Verwendung als externer Mitarbeiter in Sommer- / Wintersemester
@@ -565,7 +565,7 @@ function _add_relativesBA_und_anteiligeJVZAE($uid, $bisverwendung_arr)
$verwendung_lehre_obj->beschaeftigungsausmass_relativ = round($lehre_sws / BIS_VOLLZEIT_SWS_EINZELSTUNDENBASIS, 2); // VZ-Basis nach BIS-Vorgabe fuer Stundenbasis
$verwendung_lehre_obj->gewichtung = BIS_HALBJAHRES_GEWICHTUNG_SWS;
$verwendung_lehre_obj->jvzae_anteilig = round($verwendung_lehre_obj->beschaeftigungsausmass_relativ * $verwendung_lehre_obj->gewichtung, 2);
$bisverwendung_arr []= $verwendung_lehre_obj;
$bisverwendung_arr[]= $verwendung_lehre_obj;
}
}
}
@@ -723,13 +723,13 @@ function _addVerwendung_fuerLehre_Stundenbasis($bisverwendung)
* @param array $bisfunktion_arr
* @return array
*/
function _getFunktionscontainer_Funktionscode123456($bisfunktion_arr)
function _getFunktionscontainer_Funktionscode123456($bisfunktion_arr)
{
$funktion_arr = array();
foreach ($bisfunktion_arr as $bisfunktion)
{
$funktion_code = NULL;
$funktion_code = null;
$has_oe_lehrgang = false; // default
$studiengang = new Studiengang();
@@ -784,15 +784,15 @@ function _getFunktionscontainer_Funktionscode123456($bisfunktion_arr)
{
$funktion_obj = new StdClass();
$funktion_obj->funktionscode = $funktion_code;
$funktion_obj->besondereQualifikationCode = NULL;
$funktion_obj->besondereQualifikationCode = null;
$funktion_obj->studiengang = ($funktion_code == 5)
? array(setLeadingZero(intval($studiengang->studiengang_kz), 4)) // STG bei Funktionscode 5 melden
: NULL;
: null;
// Funktionsobjekt dem Funktionscontainer anhaengen
$funktion_arr []= $funktion_obj;
$funktion_arr[]= $funktion_obj;
}
else if ($funktion_code == 5) // Funktionscontainer vorhanden und Funktionscode 5
elseif ($funktion_code == 5)// Funktionscontainer vorhanden und Funktionscode 5
{
$funktion_obj_arr = array_filter($funktion_arr, function (&$obj) {
return $obj->funktionscode == 5;
@@ -812,17 +812,17 @@ function _getFunktionscontainer_Funktionscode123456($bisfunktion_arr)
* @return array
*
*/
function _addFunktionscontainer_Funktionscode7($uid, $funktion_arr)
function _addFunktionscontainer_Funktionscode7($uid, $funktion_arr, $stichtag)
{
$entwicklungsteam = new Entwicklungsteam();
$entwicklungsteam->getEntwicklungsteam($uid);
//nur aktuelle bzw EW-Teameinträge ohne Datumseinträgen werden berücksichtigt
$entwicklungsteam->getEntwicklungsteamBis($uid, $stichtag);
$entwicklungsteam_arr = $entwicklungsteam->result;
if (!empty($entwicklungsteam_arr))
{
// Lehrgaenge und STG, die nicht BIS gemeldet werden, extrahieren
$entwicklungsteam_arr = array_filter($entwicklungsteam_arr, function ($obj)
{
$entwicklungsteam_arr = array_filter($entwicklungsteam_arr, function ($obj) {
return
!in_array($obj->studiengang_kz, BIS_EXCLUDE_STG) &&
$obj->studiengang_kz > 0 &&
@@ -834,15 +834,14 @@ function _addFunktionscontainer_Funktionscode7($uid, $funktion_arr)
{
// Hoechste besondere Qualifikation
$besondere_qualifikation_code_arr = array();
foreach($entwicklungsteam_arr as $row_entw)
$besondere_qualifikation_code_arr[] = $row_entw->besqualcode;
$besondere_qualifikation_code = max($besondere_qualifikation_code_arr);
// Studiengaenge, wo Person Teil des Entwicklungsteams gewesen ist
$studiengang_kz_arr = array();
foreach($entwicklungsteam_arr as $row_entw)
{
$besondere_qualifikation_code_arr[] = $row_entw->besqualcode;
$studiengang_kz_arr[] = $row_entw->studiengang_kz;
}
$besondere_qualifikation_code = max($besondere_qualifikation_code_arr);
sort($studiengang_kz_arr); // sortieren
foreach($studiengang_kz_arr as &$studiengang_kz) // fuehrende Nullen fuer STG
@@ -855,7 +854,7 @@ function _addFunktionscontainer_Funktionscode7($uid, $funktion_arr)
$funktion_obj->funktionscode = 7;
$funktion_obj->besondereQualifikationCode = $besondere_qualifikation_code;
$funktion_obj->studiengang = $studiengang_kz_arr;
$funktion_arr []= $funktion_obj;
$funktion_arr[] = $funktion_obj;
}
return $funktion_arr;
@@ -873,13 +872,12 @@ function _getLehrecontainer($sws_proStg_arr)
if (!empty($sws_proStg_arr))
{
// Lehrgaenge und STG, die nicht BIS gemeldet werden, extrahieren
$sws_proStg_arr = array_filter($sws_proStg_arr, function ($obj)
{
return
!in_array($obj->studiengang_kz, BIS_EXCLUDE_STG) &&
$obj->studiengang_kz > 0 &&
$obj->studiengang_kz < 10000;
});
$sws_proStg_arr = array_filter($sws_proStg_arr, function ($obj) {
return
!in_array($obj->studiengang_kz, BIS_EXCLUDE_STG) &&
$obj->studiengang_kz > 0 &&
$obj->studiengang_kz < 10000;
});
}
if (!empty($sws_proStg_arr))
@@ -899,7 +897,7 @@ function _getLehrecontainer($sws_proStg_arr)
$lehre_obj->WintersemesterSWS = $is_wintersemester ? $sws_proStg->sws : 0.00;
// Lehreobjekt dem Lehrecontainer anhaengen
$lehre_arr []= $lehre_obj;
$lehre_arr[]= $lehre_obj;
}
else // Lehrecontainer mit STG schon vorhanden
{
@@ -912,7 +910,7 @@ function _getLehrecontainer($sws_proStg_arr)
{
current($lehre_obj_arr)->SommersemesterSWS = $sws_proStg->sws;
}
else if ($is_wintersemester)
elseif ($is_wintersemester)
{
current($lehre_obj_arr)->WintersemesterSWS = $sws_proStg->sws;
}
@@ -934,7 +932,7 @@ function _generateXML($person_arr)
if(isset($erhalter->result[0]))
{
$erhalter = sprintf("%03s",trim($erhalter->result[0]->erhalter_kz));
$erhalter = sprintf("%03s", trim($erhalter->result[0]->erhalter_kz));
}
else
$erhalter = '';
@@ -966,8 +964,8 @@ function _generateXML($person_arr)
$xml .= '<VerwendungsCode><![CDATA['. $verwendung->verwendung_code. ']]></VerwendungsCode>';
$xml .= '<BeschaeftigungsArt1><![CDATA['. $verwendung->ba1code. ']]></BeschaeftigungsArt1>';
$xml .= '<BeschaeftigungsArt2><![CDATA['. $verwendung->ba2code. ']]></BeschaeftigungsArt2>';
$xml .= '<BeschaeftigungsAusmassVZAE><![CDATA['. number_format($verwendung->vzae,2,'.',''). ']]></BeschaeftigungsAusmassVZAE>';
$xml .= '<BeschaeftigungsAusmassJVZAE><![CDATA['. number_format($verwendung->jvzae,2,'.',''). ']]></BeschaeftigungsAusmassJVZAE>';
$xml .= '<BeschaeftigungsAusmassVZAE><![CDATA['. number_format($verwendung->vzae, 2, '.', ''). ']]></BeschaeftigungsAusmassVZAE>';
$xml .= '<BeschaeftigungsAusmassJVZAE><![CDATA['. number_format($verwendung->jvzae, 2, '.', ''). ']]></BeschaeftigungsAusmassJVZAE>';
$xml .= '</Verwendung>';
}
@@ -979,7 +977,7 @@ function _generateXML($person_arr)
? '<BesondereQualifikationCode><![CDATA['. $funktion->besondereQualifikationCode. ']]></BesondereQualifikationCode>'
: '';
if ($funktion->funktionscode == 5 || $funktion->funktionscode == 7)
if (($funktion->funktionscode == 5) || ($funktion->funktionscode == 7))
{
if (is_array($funktion->studiengang))
{
@@ -990,7 +988,7 @@ function _generateXML($person_arr)
$xml .= '</Studiengang>';
}
}
else if (!is_null($funktion->studiengang))
elseif (!is_null($funktion->studiengang))
{
$xml .= '<Studiengang>';
$xml .= '<StgKz><![CDATA['. $funktion->studiengang. ']]></StgKz>';
@@ -998,6 +996,24 @@ function _generateXML($person_arr)
}
}
// if ($funktion->funktionscode == 7)
// {
// if (is_array($funktion->studiengang))
// {
// foreach ($funktion->studiengang as $studiengang)
// {
// $xml .= '<Studiengang>';
// $xml .= '<StgKz><![CDATA['. $studiengang["studieng_kz"]. ']]></StgKz>';
// $xml .= '</Studiengang>';
// }
// }
// elseif (!is_null($funktion->studiengang))
// {
// $xml .= '<Studiengang>';
// $xml .= '<StgKz><![CDATA['. $funktion->studiengang. ']]></StgKz>';
// $xml .= '</Studiengang>';
// }
// }
$xml .= '</Funktion>';
}
@@ -1154,7 +1170,7 @@ function _outputHTML($person_arr)
<td>'. $funktion->besondereQualifikationCode. '</td>
<td>';
if ($funktion->funktionscode == 5 || $funktion->funktionscode == 7)
if (($funktion->funktionscode == 5) || ($funktion->funktionscode == 7))
{
if (is_array($funktion->studiengang))
{
@@ -1163,11 +1179,12 @@ function _outputHTML($person_arr)
echo $studiengang.' ';
}
}
else if (!is_null($funktion->studiengang))
elseif (!is_null($funktion->studiengang))
{
echo $funktion->studiengang.' ';
}
}
echo '</td>
</tr>';
}
@@ -1306,7 +1323,7 @@ function outputPlausibilitaetschecks($person_arr)
if (count($msg) > 0)
{
echo "Fehler bei ".$row->vorname.' '.$row->nachname.' : '.implode($msg,', ');
echo "Fehler bei ".$row->vorname.' '.$row->nachname.' : '.implode($msg, ', ');
echo "\n<br/>";
}
}
+15 -3
View File
@@ -92,6 +92,18 @@ echo '<!DOCTYPE HTML>
<title>Lehreinheit Vorrueckung</title>
<meta charset="UTF-8">
<link rel="stylesheet" href="../../skin/vilesci.css" type="text/css">
<script type="text/javascript" src="../../vendor/jquery/jquery1/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
$("#select_studiensemester_kurzbz_from").change(function()
{
var index = $(this).prop("selectedIndex");
index = index-1;
$("#select_studiensemester_kurzbz_to :nth-child("+index+")").prop("selected", true);
});
});
</script>
</head>
<body style="background-color:#eeeeee;">
<h2>Lehreinheiten Vorr&uuml;ckung</h2>
@@ -132,9 +144,9 @@ for ($i = 1;$i <= 10;$i++)
}
echo '</SELECT>';
echo ' Von: <SELECT name="stsem_von">';
echo ' Von: <SELECT id="select_studiensemester_kurzbz_from" name="stsem_von">';
$stsem_obj = new studiensemester();
$stsem_obj->getAll();
$stsem_obj->getAll('desc');
foreach ($stsem_obj->studiensemester as $stsem)
{
@@ -147,7 +159,7 @@ foreach ($stsem_obj->studiensemester as $stsem)
}
echo '</SELECT>';
echo ' Nach: <SELECT name="stsem_nach">';
echo ' Nach: <SELECT id="select_studiensemester_kurzbz_to" name="stsem_nach">';
foreach ($stsem_obj->studiensemester as $stsem)
{
+1 -1
View File
@@ -108,7 +108,7 @@ echo '<form action="studienplan_vorrueckung.php" method="POST">';
echo ' Quelle: <select id="select_studiensemester_kurzbz_from" name="studiensemester_kurzbz_from" />';
$stsem = new studiensemester();
$stsem->getPlusMinus(null,10,'ende ASC');
$stsem->getPlusMinus(null,10,'ende DESC');
foreach($stsem->studiensemester as $row)
{
+1 -1
View File
@@ -56,7 +56,7 @@ $uid_benutzer = get_uid();
$rechte = new benutzerberechtigung();
$rechte->getBerechtigungen($uid_benutzer);
if(!$rechte->isBerechtigt('mitarbeiter', null, 's'))
if(!$rechte->isBerechtigt('mitarbeiter/zeitwuensche', null, 's'))
die($rechte->errormsg);
$datum_obj = new datum();
@@ -38,6 +38,8 @@ require_once('../../include/benutzer.class.php');
require_once('../../include/funktion.class.php');
require_once('../../include/wawi_kostenstelle.class.php');
require_once('../../include/log.class.php');
require_once('../../include/mitarbeiter.class.php');
require_once('../../include/datum.class.php');
/*
* TODOs
@@ -60,6 +62,7 @@ BEschreibungstexte bestehender Rechte
*/
$user = get_uid();
$datum = new datum();
$rechte = new benutzerberechtigung();
$rechte->getBerechtigungen($user);
@@ -68,7 +71,14 @@ if (!$db = new basis_db())
die('Fehler beim öffnen der Datenbankverbindung');
if(!$rechte->isBerechtigt('basis/berechtigung'))
die('Sie haben keine Berechtigung fuer diese Seite');
die($rechte->errormsg);
$mitarbeiter = new mitarbeiter($user);
$userKuerzel = $user;
if ($mitarbeiter->kurzbz != '')
{
$userKuerzel = $mitarbeiter->kurzbz;
}
//$reloadstr = ''; // neuladen der liste im oberen frame
$htmlstr = '';
@@ -104,7 +114,27 @@ if(isset($_POST['delete']) && $_POST['delete'] != '')
$ber = new benutzerberechtigung();
if(!$ber->delete($benutzerberechtigung_id))
{
$errorstr .= 'Datensatz konnte nicht gel&ouml;scht werden!';
}
else
{
//Log schreiben
$log = new log();
$logdata = var_export((array) $ber, true);
$log->new = true;
$log->sql = $logdata;
$log->sqlundo = 'Kein Undo vorhanden';
$log->executetime = date('Y-m-d H:i:s');
$log->mitarbeiter_uid = $user;
$log->beschreibung = 'Berechtigung gelöscht';
if(!$log->save())
{
$errorstr .= "<span style='color: red'><b>Fehler beim schreiben des Log-Eintrags</b></span><br>";
}
}
//$reloadstr .= "<script type='text/javascript'>";
//$reloadstr .= " parent.uebersicht.location.href='benutzerberechtigung_uebersicht.php';";
@@ -172,7 +202,13 @@ if(isset($_POST['uebertragen']) && $_POST['uebertragen_nach'] != '')
//echo '<pre>', var_dump($_POST), '</pre>';exit();
if($rechte->isBerechtigt('basis/berechtigung', null, 'suid'))
{
$mitarbeiter = new mitarbeiter($_POST['uid']);
$uidVon = $_POST['uid'];
if ($mitarbeiter->kurzbz != '')
{
$uidVon = $mitarbeiter->kurzbz;
}
$copyTo = $_POST['uebertragen_nach'];
if (isset($_POST['dataset']))
@@ -215,12 +251,12 @@ if(isset($_POST['uebertragen']) && $_POST['uebertragen_nach'] != '')
$ber->uid = $copyTo;
$ber->funktion_kurzbz = $funktion_kurzbz;
$ber->studiensemester_kurzbz = $studiensemester_kurzbz;
$ber->start = $start;
$ber->start = date('Y-m-d');
$ber->ende = $ende;
$ber->updateamum = date('Y-m-d H:i:s');
$ber->updatevon = $user;
$ber->kostenstelle_id = $kostenstelle_id;
$ber->anmerkung = 'Kopiert von UID '.$uidVon.($anmerkung!=''?'. Anmerkung von UID '.$uidVon.': '.$anmerkung:'');
$ber->anmerkung = 'Kp '.$uidVon.($anmerkung != '' ? ': '.$anmerkung : '');
if(!$ber->save())
{
@@ -317,6 +353,88 @@ if(isset($_POST['setDate_multi']) && $_POST['setDate_multi'] != '')
//$reloadstr .= "<script type='text/javascript'>";
//$reloadstr .= " parent.uebersicht.location.href='benutzerberechtigung_uebersicht.php';";
//$reloadstr .= "</script>";
}
if(isset($_POST['save_anmerkung_multi']) && $_POST['anmerkung_multi'] != '')
{
if(!$rechte->isBerechtigt('basis/berechtigung', null, 'su'))
die($rechte->errormsg);
$anmerkungNeu = $_POST['anmerkung_multi'];
if (isset($_POST['dataset']))
{
$i = 0;
foreach ($_POST['dataset'] AS $benutzerberechtigung_id => $value)
{
// Nur markierte Einträge bearbeiten
if (!isset($value['check']))
{
continue;
}
$ber = new benutzerberechtigung();
if(!$ber->load($benutzerberechtigung_id))
{
die('Fehler beim Laden der Berechtigung');
}
// Bestehende Anmerkungen belassen und neue Ergänzen
if ($ber->anmerkung != '')
{
$ber->anmerkung = $ber->anmerkung.'; '.$anmerkungNeu;
}
else
{
$ber->anmerkung = $anmerkungNeu;
}
// Wenn Anmerkung länger als 256 Zeichen ist (DB-Beschränkung), String kürzen und Warnung ausgeben
if (strlen($ber->anmerkung) > 256)
{
$ber->anmerkung = cutString($ber->anmerkung, 256, '...');
$errorstr .= "<span style='color: red'><b>Die Anmerkung bei der ID ".$benutzerberechtigung_id." übersteigt die maximale Länge von 256 Zeichen und wurde nicht vollständig gespeichert</b></span><br>";
}
$ber->updateamum = date('Y-m-d H:i:s');
$ber->updatevon = $user;
if(!$ber->save())
{
$errorstr .= "Die Anmerkung des Datensatzes mit der ID ".$benutzerberechtigung_id." konnte nicht gespeichert werden!".$ber->errormsg;
}
else
{
$i ++;
//Log schreiben
$log = new log();
$logdata = var_export((array) $ber, true);
$log->new = true;
$log->sql = $logdata;
$log->sqlundo = 'Kein Undo vorhanden';
$log->executetime = date('Y-m-d H:i:s');
$log->mitarbeiter_uid = $user;
$log->beschreibung = 'Anmerkung bearbeitet';
if(!$log->save())
{
$errorstr .= "<span style='color: red'><b>Fehler beim schreiben des Log-Eintrags</b></span><br>";
}
}
}
if ($i > 0)
{
$successstr .= "<span style='color: green'><b>Anmerkung bei ".$i." Einträgen erfolgreich gespeichert</b></span><br>";
}
}
//$reloadstr .= "<script type='text/javascript'>";
//$reloadstr .= " parent.uebersicht.location.href='benutzerberechtigung_uebersicht.php';";
//$reloadstr .= "</script>";
@@ -424,6 +542,10 @@ if(isset($_POST['schick']))
}
}
}
if ($errorstr == '')
{
$successstr .= "<span style='color: green'><b>Änderungen erfolgreich gespeichert</b></span><br>";
}
}
}
else
@@ -503,14 +625,16 @@ $oe = new organisationseinheit();
$oe->getAll();
foreach ($oe->result AS $row)
{
$oe_arr[$row->oe_kurzbz] = $row->organisationseinheittyp_kurzbz.' '.$row->bezeichnung;
$oe_arr[$row->oe_kurzbz]['bezeichnung'] = $row->organisationseinheittyp_kurzbz.' '.$row->bezeichnung;
$oe_arr[$row->oe_kurzbz]['aktiv'] = $row->aktiv;
}
$kostenstelle = new wawi_kostenstelle();
$kostenstelle->getAll();
foreach ($kostenstelle->result AS $row)
{
$kst_arr[$row->kostenstelle_id] = $row->bezeichnung;
$kst_arr[$row->kostenstelle_id]['bezeichnung'] = $row->bezeichnung;
$kst_arr[$row->kostenstelle_id]['aktiv'] = $row->aktiv;
}
if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
@@ -536,23 +660,27 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$name = new benutzer();
$name->load($uid);
$htmlstr .= "Berechtigungen von <b>".$name->nachname." ".$name->vorname." (".$uid.")</b>";
$htmlstr .= "Berechtigungen von <b>".$name->nachname." ".$name->vorname." (".$uid.")</b> <a href='".CIS_ROOT."cis/private/profile/index.php?uid=".$uid."' target='_blank'>Zum CIS-Profil</a>";
$message = '';
$class = '';
$messageString = '';
if ($errorstr != '' || $successstr != '')
{
if ($successstr != '')
{
$class = 'class="alert alert-success"';
$message = $successstr;
$messageString .= ' <div '.$class.'>'.$message.'</div>';
}
elseif ($errorstr != '')
if ($errorstr != '')
{
$class = 'class="alert alert-danger"';
$message = $errorstr;
$messageString .= ' <div '.$class.'>'.$message.'</div>';
}
}
$htmlstr .= ' <div id="msgbox" '.$class.'>'.$message.'</div>';
$htmlstr .= ' <div id="msgbox">'.$messageString.'</div>';
$i = 0;
@@ -643,8 +771,9 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
</tr></thead><tbody>";
$htmlstr .= "<tr id='neu'>";
$htmlstr .= "<form action='benutzerberechtigung_details.php?uid=".$uid."&funktion_kurzbz=".$funktion_kurzbz."' method='POST' name='berechtigung_neu'>";
$htmlstr .= "<form id='formNeuesRecht' action='benutzerberechtigung_details.php?uid=".$uid."&funktion_kurzbz=".$funktion_kurzbz."' method='POST' name='berechtigung_neu'>";
$htmlstr .= "<input type='hidden' name='neu' value='1'>";
$htmlstr .= "<input type='hidden' name='schick' value='1'>";
$htmlstr .= "<input type='hidden' name='benutzerberechtigung_id' value=''>";
$htmlstr .= "<input type='hidden' name='uid' value='".$uid."'>";
$htmlstr .= "<input type='hidden' name='funktion_kurzbz' value='".$funktion_kurzbz."'>";
@@ -708,7 +837,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$htmlstr .= " <td align='center'><input type='checkbox' name='dataset[0][negativ]'></td>";
//Start
$htmlstr .= " <td nowrap><input class='datepicker_datum' type='text' name='dataset[0][start]' value='' size='10' maxlength='10'></td>";
$htmlstr .= " <td nowrap><input class='datepicker_datum' type='text' name='dataset[0][start]' value='".date('Y-m-d')."' size='10' maxlength='10'></td>";
//Ende
$htmlstr .= " <td nowrap><input class='datepicker_datum' type='text' name='dataset[0][ende]' value='' size='10' maxlength='10'></td>";
@@ -716,7 +845,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
//Anmerkung
$htmlstr .= " <td><input id='anmerkung_neu' type='text' name='dataset[0][anmerkung]' value='' size='100' maxlength='256'></td>";
$htmlstr .= " <td><input type='submit' name='schick' value='Neu anlegen' onclick='return validateNewData()'></td>";
//$htmlstr .= " <td><input type='submit' name='schick' value='Neu anlegen' onclick='return validateNewData()'></td>";
$htmlstr .= "</form>";
$htmlstr .= " </tr></tbody></table>";
@@ -726,8 +855,8 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
// Tabelle für bestehende Berechtigungen
////////////////
$htmlstr .= "<p style='font-size: small' id='anzahl'></p>";
$htmlstr .= "<form action='benutzerberechtigung_details.php?uid=".$uid."&funktion_kurzbz=".$funktion_kurzbz."' method='POST'>";
$htmlstr .= "<div class='pull-left' style='font-size: small' id='anzahl'></div><div class='pull-right' style='font-size: smaller'>STRG+ALT+T fügt Datum ein</div>";
$htmlstr .= "<form id='formRechte' action='benutzerberechtigung_details.php?uid=".$uid."&funktion_kurzbz=".$funktion_kurzbz."' method='POST'>";
$htmlstr .= "<input type='hidden' name='uid' value='".$uid."'>";
$htmlstr .= "<input type='hidden' name='funktion_kurzbz' value='".$funktion_kurzbz."'>";
@@ -759,6 +888,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
</tr></thead><tbody>";
$countInaktiveUndWawi = 0;
foreach($rights->berechtigungen as $b)
{
switch($filter)
@@ -775,7 +905,6 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
default: break;
}
$htmlstr .= " <tr class='row_berechtigung' id='".$b->benutzerberechtigung_id."'>";
$heute = strtotime(date('Y-m-d'));
if ($b->ende!='' && strtotime($b->ende) < $heute)
{
@@ -798,6 +927,17 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$inaktiv_class = '';
$data = 'gruen';
}
// Inaktive Elemente sowie WaWi-Rechte ausblenden
if ($b->ende!='' && strtotime($b->ende) < $heute || $b->rolle_kurzbz == 'wawi' || substr($b->berechtigung_kurzbz, 0, 4) == 'wawi')
{
$htmlstr .= " <tr class='row_berechtigung ausgeblendet' id='".$b->benutzerberechtigung_id."'>";
$countInaktiveUndWawi++;
}
else
{
$htmlstr .= " <tr class='row_berechtigung' id='".$b->benutzerberechtigung_id."'>";
}
// Auswahlcheckbox
$htmlstr .= " <td $style class='auswahlcheckboxen' name='td_$b->benutzerberechtigung_id' data-".$data."='".$data."'>";
$htmlstr .= " <span style='display: none'>".$titel."</span>";
@@ -862,9 +1002,10 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
else
{
$htmlstr .= " <td class='oe_column'>";
$htmlstr .= " <span style='display: none'>".($b->oe_kurzbz != '' ? $oe_arr[$b->oe_kurzbz] : '')."</span>";
$htmlstr .= " <span style='display: none'>".($b->oe_kurzbz != '' ? $oe_arr[$b->oe_kurzbz]['bezeichnung'] : '')."</span>";
$htmlstr .= " <input type='hidden' name='dataset[$b->benutzerberechtigung_id][oe_kurzbz]' value='$b->oe_kurzbz'>";
$htmlstr .= " <input type='text' class='oe_kurzbz_autocomplete $inaktiv_class' value='".($b->oe_kurzbz != '' ? $oe_arr[$b->oe_kurzbz] : '')."'>";
$style = isset($oe_arr[$b->oe_kurzbz]) && $oe_arr[$b->oe_kurzbz]['aktiv'] == false? 'style="text-decoration: line-through"' : '';
$htmlstr .= " <input $style type='text' class='oe_kurzbz_autocomplete $inaktiv_class' value='".($b->oe_kurzbz != '' ? $oe_arr[$b->oe_kurzbz]['bezeichnung'] : '')."'>";
$htmlstr .= " </td>";
}
@@ -872,7 +1013,8 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$htmlstr .= " <td class='ks_column'>";
$htmlstr .= " <span style='display: none'>".$b->kostenstelle_id."</span>";
$htmlstr .= " <input type='hidden' name='dataset[$b->benutzerberechtigung_id][kostenstelle_id]' value='$b->kostenstelle_id'>";
$htmlstr .= " <input type='text' class='kostenstelle_autocomplete $inaktiv_class' value='".($b->kostenstelle_id != '' ? $kst_arr[$b->kostenstelle_id] : '')."'>";
$style = isset($kst_arr[$b->kostenstelle_id]) && $kst_arr[$b->kostenstelle_id]['aktiv'] == false ? 'style="text-decoration: line-through"' : '';
$htmlstr .= " <input $style type='text' class='kostenstelle_autocomplete $inaktiv_class' value='".($b->kostenstelle_id != '' ? $kst_arr[$b->kostenstelle_id]['bezeichnung'] : '')."'>";
$htmlstr .= " </td>";
@@ -960,20 +1102,39 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
$htmlstr .= " </tr>";
}
$htmlstr .= "</tbody></table>";
//Button zum einblenden ausgeblendeter Zeilen
if ($countInaktiveUndWawi > 0)
{
$htmlstr .= "<button type='button' class='btn btn-default' onclick='show_hidden()'>Inaktive und WaWi anzeigen</button>";
}
// Speichern und Aktions-Bereich
$htmlstr .= '<div id="bottomArea" >
<div class="input-group">
<button type="submit" class="btn btn-default" name="schick" onclick="return validateSpeichern()" style="margin-bottom: 10px">Speichern</button>
<div class="form-inline" style="">
<button id="ButtonNeu" type="button" class="btn btn-default" name="schick" onclick="return submitNeuesRecht()" style="margin-bottom: 10px">Neues Recht speichern</button>
<button id="ButtonSpeichern" type="submit" class="btn btn-default" name="schick" onclick="return validateSpeichern()" style="margin-bottom: 10px">Änderungen Speichern</button>
<div class="form-inline multi-options" style="">
<div class="input-group" style="width: 180px;">
<input type="text" id="input_uebertragen_nach" name="uebertragen_nach" class="form-control benutzer_autocomplete" placeholder="Zu UID übertragen">
<input type="text" id="input_uebertragen_nach" name="uebertragen_nach" class="form-control benutzer_autocomplete" placeholder="Zu UID übertragen" disabled>
<div class="input-group-btn">
<button class="btn btn-default" type="submit" id="button_uebertragen" name="uebertragen" onclick="return validateUebertragen()">
<button class="btn btn-default" type="submit" id="button_uebertragen" name="uebertragen" onclick="return validateUebertragen()" disabled>
<i class="glyphicon glyphicon-transfer" style="line-height: unset"></i>
</button>
</div>
</div>
<button type="submit" id="button_mehrfachbeenden" name="setDate_multi" value="setDate_multi" class="btn btn-default" onclick="return validateBeenden()">Ende setzen</button>
<button type="submit" id="button_mehrfachloeschen" name="delete_multi" value="delete_multi" class="btn btn-warning" onclick="return validateDeleteMulti()">Markierte löschen</button>
<button type="submit" id="button_mehrfachbeenden" name="setDate_multi" value="setDate_multi" class="btn btn-default" onclick="return validateBeenden()" disabled>Ende setzen</button>
<button type="submit" id="button_mehrfachloeschen" name="delete_multi" value="delete_multi" class="btn btn-warning" onclick="return validateDeleteMulti()" disabled>Markierte löschen</button>
</div>
<div class="form-inline multi-options" style="">
<div class="input-group" style="width: 180px;">
<input type="text" id="input_anmerkung_multi" maxlength="256" name="anmerkung_multi" class="form-control" placeholder="Mehrfach-Anmerkung" style="width: 390px;" disabled>
<div class="input-group-btn">
<button class="btn btn-default" type="submit" id="button_anmerkung_multi" name="save_anmerkung_multi" onclick="return validateAnmerkungMulti()" disabled>
<i class="glyphicon glyphicon-ok" style="line-height: unset"></i>
</button>
</div>
</div>
</div>
</div>
</div>';
@@ -992,6 +1153,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
<link href="../../skin/tablesort.css" rel="stylesheet" type="text/css"/>
<link href="../../skin/jquery-ui-1.9.2.custom.min.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="../../vendor/twbs/bootstrap3/dist/css/bootstrap.min.css">
<script type="text/javascript" src="../../include/tiny_mce/tiny_mce.js"></script>
<script src="../../include/js/mailcheck.js"></script>
<script src="../../include/js/datecheck.js"></script>
<!-- <script type="text/javascript" src="../../vendor/jquery/jquery1/jquery-1.12.4.min.js"></script>-->
@@ -1268,6 +1430,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
/*border-right: 1px solid #999;*/
margin-left: auto;
display: block ruby;
border-top-left-radius: 4px;
}
#msgbox
{
@@ -1306,8 +1469,35 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
{
background-color: #f3f3f3 !important;
}
.ausgeblendet
{
display: none;
}
/*.multi-options*/
/*{*/
/* display: none;*/
/*}*/
</style>
<script type="text/javascript">
$.tablesorter.addParser({
id: "customDate",
is: function(s) {
//return false;
//use the above line if you don\'t want table sorter to auto detected this parser
// match dd.mm.yyyy e.g. 01.01.2001 as regex
//return /\d{1,4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2} .*/.test(s);
return /\d{1,2}.\d{1,2}.\d{1,4} \d{1,2}:\d{1,2} .*/.test(s);
},
// replace regex-wildcards and return new date
format: function(s) {
s = s.replace(/\-/g," ");
s = s.replace(/:/g," ");
s = s.replace(/\./g," ");
s = s.split(" ");
return $.tablesorter.formatFloat(new Date(s[2], s[1]-1, s[0], s[3], s[4]).getTime());
},
type: "numeric"
});
$(document).ready(function()
{
// $("[data-toggle=\"popover\"]").popover();
@@ -1336,28 +1526,35 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
});
$("#t1").tablesorter(
{
sortList: [[0,0],[1,0],[2,0],[4,0]],
widgets: ["filter"],
headers: {0:{sorter:false},6:{sorter:false, filter:false},10:{sorter:false, filter:false},11:{sorter:false, filter:false}},
widgetOptions : { filter_functions : {
// Add select menu to this column
0 : {
"Aktive" : function(e, n, f, i, $r, c, data) { return /a/.test(e); },
"Wartende" : function(e, n, f, i, $r, c, data) { return /b/.test(e); },
"Inaktive" : function(e, n, f, i, $r, c, data) { return /c/.test(e); }
}
}},
// Um die Werte im Dropdown sortieren zu können
textExtraction: function(node) {
// Check if option selected is set
if ($(node).find('option:selected').text() != "") {
return $(node).find('option:selected').text();
{
sortList: [[0,0],[1,0],[2,0],[4,0]],
widgets: ["filter"],
headers: {0:{sorter:false},6:{sorter:false, filter:false},10:{sorter:false, filter:false},11:{sorter:false, filter:false}},
widgetOptions : { filter_functions : {
// Add select menu to this column
0 : {
"Aktive" : function(e, n, f, i, $r, c, data) { return /a/.test(e); },
"Wartende" : function(e, n, f, i, $r, c, data) { return /b/.test(e); },
"Inaktive" : function(e, n, f, i, $r, c, data) { return /c/.test(e); }
}
// Otherwise return text
else return $(node).text();
}},
// Um die Werte im Dropdown sortieren zu können
textExtraction: function(node) {
// Check if option selected is set
if ($(node).find('option:selected').text() != "") {
return $(node).find('option:selected').text();
}
});
// Otherwise return text
else return $(node).text();
}
});
$("#t2").tablesorter(
{
sortList: [[0,1]],
widgets: ["filter"],
headers: { 0: { sorter: "customDate"}},
widgetOptions : {}
});
//document.berechtigung_neu.rolle_kurzbz.focus();
// Breite des Autocompletes korrigieren um das Springen zu verhindern
@@ -1499,17 +1696,99 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
var aktiv = $('td.auswahlcheckboxen[data-gruen]').length + $('td.auswahlcheckboxen[data-gelb]').length;
var inaktiv = $('td.auswahlcheckboxen[data-rot]').length;
$("#anzahl").html(aktiv + inaktiv + " Einträge (" + aktiv + " Aktive, " + inaktiv + " Inaktive)");
$("#anzahl").html(aktiv + inaktiv + " Einträge (" + aktiv + " Aktive, " + inaktiv + " Inaktive (ausgeblendet))");
/*$('.checkbox').each(function ()
{
$("#t1").checkboxes('range', true);
});*/
$("#uncheck_t1").on('click', function(e) {
$(".auswahlcheckboxen").checkboxes('uncheck');
e.preventDefault();
});
$("#uncheck_t1").on('click', function(e)
{
$(".auswahlcheckboxen").checkboxes('uncheck');
e.preventDefault();
});
// Wenn eine Auswahlcheckbox angeklickt wird, Zusatzoptionen anzeigen
$(".auswahlcheckbox").change(function() {
if ($(".auswahlcheckbox:checked").length > 0)
{
// Aktiviere Inputs, wenn mindestens eine Checkbox ausgewählt ist
$(".multi-options input[type=text]").prop('disabled', false);
$(".multi-options").find("button").prop('disabled', false);
}
else
{
// Deaktiviere Inputs, wenn keine Checkbox ausgewählt ist
$(".multi-options input[type=text]").prop('disabled', true);
$(".multi-options").find("button").prop('disabled', true);
}
});
// Wenn etwas ins Neu-Formular eingegeben wird, nur den Neu-Speicherbutton aktivieren, sonst den anderen
$("#neu :input").on( "input", function() {
var filled = false;
$("#formNeuesRecht :input").each(function() {
if ($(this).val().trim() !== '') {
filled = true;
return false; // Brechen Sie die each-Schleife ab, wenn ein gefülltes Feld gefunden wurde
}
});
// Aktualisieren Sie den Status des Buttons basierend auf den Änderungen in den Feldern
$("#ButtonSpeichern").prop("disabled", !filled);
$("#ButtonNeu").prop("disabled", filled);
// Aktualisieren Sie die Variable, um den Status zu speichern
isButtonDisabled = !filled;
});
// Wenn etwas ins Rechte-Formular eingegeben wird, nur den Speicherbutton aktivieren, sonst den anderen
$("#formRechte :input").on( "input", function() {
var filled = false;
$("#formNeuesRecht :input").each(function() {
if ($(this).val().trim() !== '') {
filled = true;
return false; // Brechen Sie die each-Schleife ab, wenn ein gefülltes Feld gefunden wurde
}
});
// Aktualisieren Sie den Status des Buttons basierend auf den Änderungen in den Feldern
$("#ButtonNeu").prop("disabled", !filled);
$("#ButtonSpeichern").prop("disabled", filled);
// Aktualisieren Sie die Variable, um den Status zu speichern
isButtonDisabled = !filled;
});
$('input[type="text"]').on('keydown', function(e){
if(e.ctrlKey && e.altKey && e.keyCode == 84){ // Wenn Strg + Alt + T gedrückt wird
e.preventDefault();
insertDatumAtCursor(this);
}
});
function insertDatumAtCursor(input){
var startPos = input.selectionStart;
var endPos = input.selectionEnd;
var currentDate = getCurrentDateAndUser();
var text = $(input).val();
var newText = text.substring(0, startPos) + currentDate + text.substring(endPos, text.length);
$(input).val(newText);
$(input).prop('selectionStart', startPos + currentDate.length);
$(input).prop('selectionEnd', startPos + currentDate.length);
}
function getCurrentDateAndUser()
{
var today = new Date();
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); // Januar ist 0!
var yyyy = today.getFullYear();
return dd + '.' + mm + '.' + yyyy+ ' <?php echo $userKuerzel; ?>: ';
}
//if (typeof $("#filterTableDataset").checkboxes === 'function')
// $("#filterTableDataset").checkboxes("range", true);
@@ -1539,6 +1818,22 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
return true;
}
function validateAnmerkungMulti()
{
if($('input.auswahlcheckbox:checked').length == 0)
{
alert('Bitte mindestens eine Berechtigung auswählen');
return false;
}
else if($('#input_anmerkung_multi').val() == '')
{
alert('Bitte Text eingeben, der als Anmerkung hinzugefügt werden soll');
return false;
}
else
return true;
}
function validateBeenden()
{
if($('input.auswahlcheckbox:checked').length == 0)
@@ -1584,18 +1879,17 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
}
else if ($('#art_neu').val() != '')
{
var eingabe, c, erlaubt = 'suid', laenge;
eingabe = $('#art_neu').val();
eingabe = eingabe.toLowerCase();
laenge = eingabe.length;
for (c = 0; c < laenge; c++)
var eingabe = $('#art_neu').val().toLowerCase();
var erlaubt = ['s', 'su', 'sui', 'suid'];
if (erlaubt.includes(eingabe))
{
d = eingabe.charAt(c);
if (erlaubt.indexOf(d) == -1)
{
alert ('Erlaubte Werte für Art sind s,u,i,d');
return false;
}
return true;
}
else
{
alert('Erlaubte Werte für Art sind s, su, sui, suid');
return false;
}
}
else
@@ -1697,7 +1991,7 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
function validateArt(id)
{
var eingabe, c, erlaubt = 'suid', laenge;
eingabe = document.getElementById(id).value;;
eingabe = document.getElementById(id).value;
eingabe = eingabe.toLowerCase();
laenge = eingabe.length;
if (eingabe == '')
@@ -1718,6 +2012,22 @@ if (isset($_REQUEST['uid']) || isset($_REQUEST['funktion_kurzbz']))
document.getElementById(id).style.border = "";
}
}
function show_hidden()
{
$("tr.ausgeblendet:hidden").each(function()
{
$(this).fadeIn(1000);
});
}
function submitNeuesRecht()
{
if (validateNewData())
{
var form = document.getElementById("formNeuesRecht");
form.submit();
}
}
</script>
</head>
<body style="background-color:#eeeeee;">
@@ -29,17 +29,20 @@ require_once('../../include/benutzer.class.php');
require_once('../../include/berechtigung.class.php');
require_once ('../../include/organisationseinheit.class.php');
require_once ('../../include/benutzerfunktion.class.php');
require_once ('../../include/funktion.class.php');
echo '<html>
<head>
<title>Berechtigungen Uebersicht</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="../../skin/vilesci.css" type="text/css">';
<link rel="stylesheet" href="../../skin/vilesci.css" type="text/css">
<link href="../../skin/jquery-ui-1.9.2.custom.min.css" rel="stylesheet" type="text/css">';
include('../../include/meta/jquery.php');
include('../../include/meta/jquery-tablesorter.php');
echo '
<script type="text/javascript" src="../../vendor/components/jqueryui/jquery-ui.min.js"></script>
<script language="JavaScript" type="text/javascript">
function checkLength()
{
@@ -53,77 +56,138 @@ function checkLength()
return true;
}
$(document).ready(function()
{
if ($("#berechtigung_kurzbz").val() == "" && $("#rolle_kurzbz").val() == "")
$("#erweitertesuche").hide();
{
if ($("#berechtigung_kurzbz").val() == "" && $("#rolle_kurzbz").val() == "" && $("#person_oe_kurzbz").val() == "")
$("#erweitertesuche").hide();
$("#t1").tablesorter(
{
sortList: [[0,0],[1,0],[2,0]],
widgets: ["zebra"],
headers: {4:{sorter:false}}
});
$("#t2").tablesorter(
{
sortList: [[0,0],[1,0],[2,0],[3,0]],
widgets: ["zebra", "filter", "stickyHeaders"],
headers: {8:{sorter:false}},
emptyTo: "emptyMax",
widgetOptions : { filter_functions:
{
// Add select menu to this column
6 : {
"Ja" : function(e, n, f, i, $r, c, data) { return e == "Ja" || e == "" },
"Nein" : function(e, n, f, i, $r, c, data) { return /Nein/.test(e); }
},
7 : {
"Aktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonGreen" ); },
"Inaktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonRed" ) || $r.find("div").hasClass( "buttonYellow" ); }
}
}
}
});
$("#t3").tablesorter(
{
sortList: [[1,0],[2,0],[3,0]],
widgets: ["zebra", "filter", "stickyHeaders"],
headers: {8:{sorter:false}},
emptyTo: "emptyMax",
widgetOptions : { filter_functions:
{
// Add select menu to this column
6 : {
"Ja" : function(e, n, f, i, $r, c, data) { return /Ja/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return /Nein/.test(e); }
},
7 : {
"Aktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonGreen" ); },
"Inaktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonRed" ) || $r.find("div").hasClass( "buttonYellow" ); }
}
}
}
});
$("#t4").tablesorter(
{
sortList: [[0,0],[1,0],[2,0]],
widgets: ["zebra", "filter", "stickyHeaders"],
headers: {9:{sorter:false}},
emptyTo: "emptyMax",
widgetOptions : { filter_functions:
{
// Add select menu to this column
7 : {
"Ja" : function(e, n, f, i, $r, c, data) { return /Ja/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return /Nein/.test(e); }
},
8 : {
"Aktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonGreen" ); },
"Inaktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonRed" ) || $r.find("div").hasClass( "buttonYellow" ); }
}
}
}
});
$("#t1").tablesorter(
{
sortList: [[4,0],[0,0],[1,0],[2,0]],
widgets: ["zebra", "filter", "stickyHeaders"]
//headers: {4:{sorter:false}}
});
$("#t2").tablesorter(
{
sortList: [[0,0],[1,0],[2,0],[3,0]],
widgets: ["zebra", "filter", "stickyHeaders"],
headers: {8:{sorter:false}},
emptyTo: "emptyMax",
widgetOptions : { filter_functions:
{
// Add select menu to this column
7 : {
"Ja" : function(e, n, f, i, $r, c, data) { return e === "Ja" || /^\s*$/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return e === "Nein" || /^\s*$/.test(e); }
},
8 : {
"Aktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonGreen" ); },
"Inaktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonRed" ) || $r.find("div").hasClass( "buttonYellow" ); }
}
}
}
});
$("#t3").tablesorter(
{
sortList: [[1,0],[2,0],[3,0]],
widgets: ["zebra", "filter", "stickyHeaders"],
headers: {8:{sorter:false}},
emptyTo: "emptyMax",
widgetOptions : { filter_functions:
{
// Add select menu to this column
6 : {
"Ja" : function(e, n, f, i, $r, c, data) { return e === "Ja" || /^\s*$/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return e === "Nein" || /^\s*$/.test(e); }
},
7 : {
"Aktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonGreen" ); },
"Inaktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonRed" ) || $r.find("div").hasClass( "buttonYellow" ); }
}
}
}
});
$("#t4").tablesorter(
{
sortList: [[0,0],[1,0],[2,0]],
widgets: ["zebra", "filter", "stickyHeaders"],
headers: {9:{sorter:false}},
emptyTo: "emptyMax",
widgetOptions : { filter_functions:
{
// Add select menu to this column
7 : {
"Ja" : function(e, n, f, i, $r, c, data) { return /Ja/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return /Nein/.test(e); }
},
8 : {
"Aktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonGreen" ); },
"Inaktiv" : function(e, n, f, i, $r, c, data) { return $r.find("div").hasClass( "buttonRed" ) || $r.find("div").hasClass( "buttonYellow" ); }
}
}
}
});
$("#t5").tablesorter(
{
sortList: [[0,0],[1,0],[3,1]],
widgets: ["zebra", "filter", "stickyHeaders"],
headers: {4:{sorter:false}},
emptyTo: "emptyMax",
widgetOptions : { filter_functions:
{
// Add select menu to this column
4 : {
"Ja" : function(e, n, f, i, $r, c, data) { return /Ja/.test(e); },
"Nein" : function(e, n, f, i, $r, c, data) { return /Nein/.test(e); }
}
}
}
});
// Breite des Autocompletes korrigieren um das Springen zu verhindern
$.extend($.ui.autocomplete.prototype.options, {
open: function(event, ui) {
$(this).autocomplete("widget").css({
"width": ($(".ui-menu-item").width()+ 20 + "px"),
"padding-left": "5px"
});
}
});
$(".oe_kurzbz_autocomplete").autocomplete({
source: "benutzerberechtigung_autocomplete.php?autocomplete=oe_kurzbz",
minLength:2,
response: function(event, ui)
{
if (!ui.content.length)
{
var noResult = { value:"",label:"Keine Ergebnisse" };
ui.content.push(noResult);
}
else
{
//Value und Label fuer die Anzeige setzen
for (i in ui.content) {
ui.content[i].value = ui.content[i].organisationseinheittyp_kurzbz + " " + ui.content[i].bezeichnung;
ui.content[i].label = ui.content[i].organisationseinheittyp_kurzbz + " " + ui.content[i].bezeichnung;
}
}
},
select: function(event, ui)
{
$(this).siblings("input:hidden").val(ui.item.oe_kurzbz);
}
});
$(".oe_kurzbz_autocomplete").on( "input", function() {
if ($(this).val() == "")
{
$(this).siblings("input:hidden").val("");
}
});
$("#person_oe_kurzbz").on( "click", function() {
$(this).select();
});
$("#searchbox").on( "click", function() {
$(this).select();
});
});
</script>
<style>
@@ -199,10 +263,11 @@ if(!$rechte->isBerechtigt('basis/berechtigung'))
$htmlstr = "";
$searchstr = (isset($_GET['searchstr'])?$_GET['searchstr']:'');
$benutzerart = (isset($_GET['benutzerart'])?$_GET['benutzerart']:'');
$benutzerart = (isset($_GET['benutzerart'])?$_GET['benutzerart']:'mitarbeiter');
$benutzeraktiv = (isset($_GET['aktiv'])?$_GET['aktiv']:'aktiv');
$berechtigung_kurzbz = (isset($_GET['berechtigung_kurzbz'])?$_GET['berechtigung_kurzbz']:'');
$rolle_kurzbz = (isset($_GET['rolle_kurzbz'])?$_GET['rolle_kurzbz']:'');
$person_oe_kurzbz = (isset($_GET['person_oe_kurzbz'])?$_GET['person_oe_kurzbz']:'');
$userOnly = (isset($_GET['userOnly']) ? true : false);
$htmlstr='
@@ -228,6 +293,13 @@ $htmlstr='
</form>
<div id="erweitertesuche">
<hr>
<form accept-charset="UTF-8" name="searchPersonenOe" method="GET">
Personen in Organisationseinheit:
<input type="hidden" name="person_oe_kurzbz" value="'.$person_oe_kurzbz.'">
<input type="text" id="person_oe_kurzbz" value="'.$person_oe_kurzbz.'" class="oe_kurzbz_autocomplete">
<input type="submit" value="Suchen">
</form>
<hr>
<form accept-charset="UTF-8" name="searchrechte" method="GET">
Rechte:
<select id="berechtigung_kurzbz" name="berechtigung_kurzbz">
@@ -366,6 +438,7 @@ if($berechtigung_kurzbz != '')
<th>Nachname</th>
<th>Vorname</th>
<th>UID</th>
<th>Organisationseinheit</th>
<th>Art</th>
<th data-value='Ja'>Benutzer Aktiv</th>
<th data-value='Aktiv'>Status</th>
@@ -376,6 +449,8 @@ if($berechtigung_kurzbz != '')
{
$benutzer = new benutzer();
$benutzer->load($row->uid);
$organisationseinheit = new organisationseinheit($row->oe_kurzbz);
$heute = strtotime(date('Y-m-d'));
@@ -398,6 +473,7 @@ if($berechtigung_kurzbz != '')
$htmlstr .= ' <td>'.($benutzer->nachname != ''?$benutzer->nachname:'').'</td>';
$htmlstr .= ' <td>'.($benutzer->vorname != ''?$benutzer->vorname:'').'</td>';
$htmlstr .= ' <td>'.($row->uid != ''?$row->uid:'').'</td>';
$htmlstr .= ' <td style="text-overflow: ellipsis; white-space: nowrap; overflow:hidden;">'.($row->oe_kurzbz != '' ? $organisationseinheit->organisationseinheittyp_kurzbz.' '.$organisationseinheit->bezeichnung:'').'</td>';
$htmlstr .= ' <td>'.$row->art.'</td>';
$htmlstr .= ' <td>'.(isset($row->uid)?$benutzer->bnaktiv?'Ja':'Nein':'').'</td>';
$htmlstr .= ' <td align="center">'.$status.'</td>';
@@ -552,7 +628,7 @@ if($rolle_kurzbz != '')
// Anzahl uniquer UIDs ermitteln
$berechtigungen_array_uids = sizeof(array_column($rollen->result, null, 'uid'));
$htmlstr .= "<h3>".$berechtigung_kurzbz."</h3>\n";
$htmlstr .= "<h3>".$rolle_kurzbz."</h3>\n";
$htmlstr .= "<div style='font-size: 9pt'>".count($rollen->result)." Einträge</div>";
$htmlstr .= "<div style='font-size: 9pt'>".$berechtigungen_array_uids." UIDs</div>";
$htmlstr .= "<table id='t3' class='tablesorter'><thead><tr>\n";
@@ -607,6 +683,76 @@ if($rolle_kurzbz != '')
}
}
//Personen in OEs suchen und Tabelle anzeigen
if($person_oe_kurzbz != '')
{
$childOes = new organisationseinheit();
$oeChilds = $childOes->getChilds($person_oe_kurzbz);
$uids = array();
$countUID = array();
$benutzerfunktion = new benutzerfunktion();
foreach ($oeChilds AS $key => $oe)
{
$benutzerfunktion->getOeFunktionen($oe,'kstzuordnung,fachzuordnung','now()','now()');
foreach($benutzerfunktion->result as $bf)
{
$oeFunktion = new organisationseinheit($bf->oe_kurzbz);
$funktion = new funktion($bf->funktion_kurzbz);
$uids[$bf->uid.$bf->oe_kurzbz] = ["uid" => $bf->uid, "funktion" => $funktion->beschreibung." ".$oeFunktion->bezeichnung];
$countUID[] = $bf->uid;
}
$benutzerfunktion->getOeFunktionen($oe,'Leitung,stvLtg,oezuordnung','now()','now()');
foreach($benutzerfunktion->result as $bf)
{
$oeFunktion = new organisationseinheit($bf->oe_kurzbz);
$funktion = new funktion($bf->funktion_kurzbz);
$uids[$bf->uid.$bf->oe_kurzbz] = ["uid" => $bf->uid, "funktion" => $funktion->beschreibung." ".$oeFunktion->bezeichnung];
$countUID[] = $bf->uid;
}
}
if(count($uids) != 0)
{
// Anzahl uniquer UIDs ermitteln
$berechtigungen_array_uids = count($uids);
$countUID = array_unique($countUID);
$oeName = new organisationseinheit($person_oe_kurzbz);
$htmlstr .= "<h3>".$oeName->organisationseinheittyp_kurzbz." ".$oeName->bezeichnung."</h3>\n";
$htmlstr .= "<div style='font-size: 9pt'>".$berechtigungen_array_uids." Einträge</div>";
$htmlstr .= "<div style='font-size: 9pt'>".count($countUID)." UIDs</div>";
$htmlstr .= "<table id='t5' class='tablesorter'><thead><tr>\n";
$htmlstr .= " <th>Nachname</th>
<th>Vorname</th>
<th>UID</th>
<th>Funktion</th>
<th data-value='Ja'>Benutzer Aktiv</th>
<th>Aktion</th>";
$htmlstr .= "</tr></thead><tbody>\n";
foreach($uids as $key => $uid)
{
$benutzer = new benutzer();
$benutzer->load($uid["uid"]);
$htmlstr .= ' <tr>';
$htmlstr .= ' <td>'.($benutzer->nachname != ''?$benutzer->nachname:'').'</td>';
$htmlstr .= ' <td>'.($benutzer->vorname != ''?$benutzer->vorname:'').'</td>';
$htmlstr .= ' <td>'.$uid["uid"].'</td>';
$htmlstr .= ' <td>'.$uid["funktion"].'</td>';
$htmlstr .= ' <td>'.(isset($uid)?$benutzer->bnaktiv?'Ja':'Nein':'').'</td>';
$htmlstr .= ' <td><a href="benutzerberechtigung_details.php?uid='.$uid["uid"].'" target="vilesci_detail">Rechte bearbeiten</a></td>';
$htmlstr .= ' </tr>';
}
$htmlstr .= '</tbody></table>';
}
else
{
$htmlstr .= "Für diese Berechtigung sind keine Einträge vorhanden";
}
}
echo $htmlstr;
?>
+169 -23
View File
@@ -31,11 +31,12 @@ $rechte = new benutzerberechtigung();
$rechte->getBerechtigungen($user);
if(!$rechte->isBerechtigt('basis/berechtigung'))
die('Sie habe keine Rechte um diese Seite anzuzeigen');
die($rechte->errormsg);
//echo '<pre>', var_dump($_POST), '</pre>';exit();
$rolle_kurzbz = filter_input(INPUT_GET, 'rolle_kurzbz');
$delete = filter_input(INPUT_GET, 'delete', FILTER_VALIDATE_BOOLEAN);
$copy = filter_input(INPUT_POST, 'copy');
$saveRecht = isset($_POST['action']) && $_POST['action'] == 'saveRechtAjax' ? true : false;
$vergleich = filter_input(INPUT_GET, 'vergleich');
?>
<html>
@@ -157,13 +158,135 @@ $vergleich = filter_input(INPUT_GET, 'vergleich');
else
return true;
}
function saveRecht(rolle_kurzbz, recht, art)
{
data = {
action: 'saveRechtAjax',
rolle_ajax: rolle_kurzbz,
recht_ajax: recht,
art_ajax: art
};
$.ajax({
url: 'berechtigungrolle.php',
data: data,
type: 'POST',
dataType: 'json',
success: function(data)
{
if(data.status!='ok')
{
//error
console.log('error');
}
else
{
//location.reload(true);
window.location.reload(true)
// html = '<td style=""></td><td style="">'+recht+'</td><td style="text-align: right;">'+art+'</td>';
// console.log('#'+rolle_kurzbz+'_'+recht);
// $('#'+rolle_kurzbz+'_'+recht).html(html);
}
},
error: function(data)
{
//error
console.log('AJAX-Fehler in Error-Methode: ' + data.status + ' - ' + data.error);
location.reload(true);
},
stop: function (data)
{
location.reload(true);
}
});
}
</script>
<style>
button
{
line-height: 9pt;
}
table.tablesorter tr:hover td
{
/*pointer-events: none !important;*/
}
table.tablesorter tr.odd:hover td
{
background-color: #d3d3d3 !important;
}
table.tablesorter tr.even:hover td
{
background-color: #efefef !important;
}
table.tablesorter tr.odd:hover td.difference
{
background-color: #b2b2b2 !important;
/*border-top: 1px solid #aaa;*/
/*border-bottom: 1px solid #aaa;*/
}
table.tablesorter tr.even:hover td.difference
{
background-color: #b2b2b2 !important;
/*border-top: 1px solid #aaa;*/
/*border-bottom: 1px solid #aaa;*/
}
.difference
{
background-color: #b2b2b2 !important;
border-top: 1px solid #aaa;
border-bottom: 1px solid #aaa;
}
/*.difference:hover*/
/*{*/
/* background-color: #b2b2b2 !important;*/
/* border-top: 1px solid #aaa;*/
/* border-bottom: 1px solid #aaa;*/
/*}*/
.tablesorter
{
border-collapse: collapse !important;
}
</style>
</head>
<body class="background_main">
<?php
if($saveRecht)
{
$rolle_kurzbz = filter_input(INPUT_POST, 'rolle_ajax');
$recht = filter_input(INPUT_POST, 'recht_ajax');
$art = filter_input(INPUT_POST, 'art_ajax');
$berechtigung = new berechtigung();
$berechtigung->rolle_kurzbz = $rolle_kurzbz;
$berechtigung->berechtigung_kurzbz = $recht;
$berechtigung->art = $art;
$berechtigung->insertamum = date('Y-m-d H:i:s');
$berechtigung->insertvon = $user;
if($berechtigung->saveRolleBerechtigung())
{
echo json_encode(array(
'status' => 'ok',
'msg' => ''
));
exit();
}
else
{
echo json_encode(array(
'status' => 'error',
'msg' => 'Fehler beim Speichern der Rolle'
));
exit();
}
}
if(isset($rolle_kurzbz))
{
echo '<h2>Berechtigungen der Rolle "'.$rolle_kurzbz.'"</h2>';
@@ -335,35 +458,46 @@ $vergleich = filter_input(INPUT_GET, 'vergleich');
<tr>
<th>Kurzbz</th>
<th>Art</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>';
foreach ($rollenGesamt AS $recht => $art)
{
if (array_key_exists($recht, $rollen1Arr))
if (array_key_exists($recht, $rollen1Arr) || !array_key_exists($recht, $rollen2Arr))
{
if ($art != $rollen1Arr[$recht])
{
echo ' <tr>
<td style="border: 1px solid transparent">'.$recht.'</td>
<td style="border: 1px solid black">'.$rollen1Arr[$recht].'</td>
echo ' <tr id="'.$rolle1.'_'.$recht.'">
<td style="">'.$recht.'</td>
<td class="difference">'.$rollen1Arr[$recht].'</td>
<td style="text-align: right;"><button type="button" onclick="saveRecht(\''.$rolle2.'\', \''.$recht.'\', \''.$rollen1Arr[$recht].'\')"> -> </button></td>
</tr>';
}
elseif (!array_key_exists($recht, $rollen2Arr))
{
echo ' <tr id="'.$rolle1.'_'.$recht.'">
<td style="">'.$recht.'</td>
<td style="">'.$art.'</td>
<td style="text-align: right;"><button type="button" onclick="saveRecht(\''.$rolle2.'\', \''.$recht.'\', \''.$rollen1Arr[$recht].'\')"> -> </button></td>
</tr>';
}
else
{
echo ' <tr>
<td style="border: 1px solid transparent">'.$recht.'</td>
<td style="border: 1px solid transparent">'.$art.'</td>
echo ' <tr id="'.$rolle1.'_'.$recht.'">
<td style="">'.$recht.'</td>
<td style="">'.$art.'</td>
<td style="text-align: right;"></td>
</tr>';
}
}
else
{
echo ' <tr>
<td style="border: 1px solid black; border-right: 0">&nbsp;</td>
<td style="border: 1px solid black; border-left: 0">&nbsp;</td>
echo ' <tr id="'.$rolle1.'_'.$recht.'">
<td class="difference" style="">&nbsp;</td>
<td class="difference"style="">&nbsp;</td>
<td class="difference"style=" text-align: right;"></td>
</tr>';
}
}
@@ -395,6 +529,7 @@ $vergleich = filter_input(INPUT_GET, 'vergleich');
echo ' <table id="t4" class="tablesorter">
<thead>
<tr>
<th>&nbsp;</th>
<th>Kurzbz</th>
<th>Art</th>
</tr>
@@ -402,28 +537,39 @@ $vergleich = filter_input(INPUT_GET, 'vergleich');
<tbody>';
foreach ($rollenGesamt AS $recht => $art)
{
if (array_key_exists($recht, $rollen2Arr))
if (array_key_exists($recht, $rollen2Arr) || !array_key_exists($recht, $rollen1Arr))
{
if ($art != $rollen2Arr[$recht])
{
echo ' <tr>
<td style="border: 1px solid transparent">'.$recht.'</td>
<td style="border: 1px solid black">'.$rollen2Arr[$recht].'</td>
echo ' <tr id="'.$rolle2.'_'.$recht.'">
<td style="text-align: left;"><button type="button" onclick="saveRecht(\''.$rolle1.'\', \''.$recht.'\', \''.$rollen2Arr[$recht].'\')"> <- </button></td>
<td style="">'.$recht.'</td>
<td class="difference" style="">'.$rollen2Arr[$recht].'</td>
</tr>';
}
elseif (!array_key_exists($recht, $rollen1Arr))
{
echo ' <tr id="'.$rolle2.'_'.$recht.'">
<td style="text-align: left;"><button type="button" onclick="saveRecht(\''.$rolle1.'\', \''.$recht.'\', \''.$rollen2Arr[$recht].'\')"> <- </button></td>
<td style="">'.$recht.'</td>
<td style="">'.$art.'</td>
</tr>';
}
else
{
echo ' <tr>
<td style="border: 1px solid transparent">'.$recht.'</td>
<td style="border: 1px solid transparent">'.$art.'</td>
echo ' <tr id="'.$rolle2.'_'.$recht.'">
<td style="">&nbsp;</td>
<td style="">'.$recht.'</td>
<td style="">'.$art.'</td>
</tr>';
}
}
else
{
echo ' <tr>
<td style="border: 1px solid black; border-right: 0">&nbsp;</td>
<td style="border: 1px solid black; border-left: 0">&nbsp;</td>
echo ' <tr id="'.$rolle2.'_'.$recht.'">
<td class="difference" style=""></td>
<td class="difference" style="">&nbsp;</td>
<td class="difference" style="">&nbsp;</td>
</tr>';
}
}

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